From 44bd1a88bd8b42db50bea56fd12125b6cafe23bb Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 11 Mar 2024 12:06:47 -0700 Subject: [PATCH 01/35] issue5: add support to parameter waitComplete in rundataproduct --- onc/+onc/OncDelivery.m | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index 8cc98ca..09c779d 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -113,23 +113,26 @@ % run timed run request tic - status = 202; - while status == 202 + flag = 'queued'; + while ~strcmp(flag,'complete') && ~strcmp(flag,'cancelled') [response, info] = this.doRequest(url, filters); status = info.status; r.requestCount = r.requestCount + 1; % guard against failed request if util.is_failed_response(response, status) - r = response; throw(util.prepare_exception(status)); end - % repeat only if waitComplete if waitComplete log.printResponse(response); - if status == 202, pause(this.pollPeriod); end + if status == 202 + pause(this.pollPeriod); + end + else + break; end + flag = response.status; end duration = toc; fprintf('\n') From 1731231876c4a2d5df1a96c2f832495bc07b96c2 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 11 Mar 2024 12:08:34 -0700 Subject: [PATCH 02/35] issue5: set waitComplete default value to true --- onc/+onc/OncDelivery.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index 09c779d..20ba84f 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -104,7 +104,7 @@ % % Documentation: https://wiki.oceannetworks.ca/display/CLIBS/Data+product+download+methods - if ~exist('waitComplete','var'), waitComplete = false; end + if ~exist('waitComplete','var'), waitComplete = true; end url = sprintf('%sapi/dataProductDelivery', this.baseUrl); log = onc.DPLogger(); From 6a5ff03c79ac3ff504e860ac15704dfd6c5ed888 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Wed, 13 Mar 2024 15:43:19 -0700 Subject: [PATCH 03/35] issue-8: fixed never reached branch and update error response exceptions --- onc/+util/do_request.m | 25 ++++++--------- onc/+util/prepare_exception.m | 10 +++--- onc/+util/print_error.m | 60 ++++++++++++++++++++++------------- 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/onc/+util/do_request.m b/onc/+util/do_request.m index 0b667d7..0b57dc9 100644 --- a/onc/+util/do_request.m +++ b/onc/+util/do_request.m @@ -25,7 +25,9 @@ % run and time request if showInfo, fprintf('\nRequesting URL:\n %s\n', fullUrl); end tic - response = send(request, uri, options); + %response = send(request, uri, options); + response = request.send(uri,options); + duration = toc; % print duration @@ -47,22 +49,13 @@ case 202 % Accepted, no need to print error, handle manually result = response.Body.Data; - case 400 - % Bad request - result = response.Body.Data; - util.print_error(response, fullUrl); - case 401 - % Unauthorized - fprintf('\nERROR 401: Unauthorized. Please verify your user token.\n') - result = response.Body.Data; - case 503 - % Down for maintenance - fprintf('\nERROR 503: Service unavailable.\nWe could be down for maintenance; '); - fprintf('visit https://data.oceannetworks.ca for more information.\n') - result = struct('errors', [struct('errorCode', 503, 'message', 'Service Unavailable')]); otherwise - result = response.Body.Data; - fprintf('\nERROR: The request failed with HTTP error %d\n', status) + util.print_error(response, fullUrl); + if status == 400 || status == 401 + throw(util.prepare_exception(status,double(response.Body.Data.errors.errorCode))); + else + throw(util.prepare_exception(status)); + end end % prepare info.size only if the response is a file, otherwise 0 diff --git a/onc/+util/prepare_exception.m b/onc/+util/prepare_exception.m index 119698b..3dc9a84 100644 --- a/onc/+util/prepare_exception.m +++ b/onc/+util/prepare_exception.m @@ -1,15 +1,17 @@ -function ex = prepare_exception(status) +function ex = prepare_exception(status, errorCode) %% Prepares a throwable exception object for the response % % * response: (struct) Response as returned by do_request() - % - status: @TODO + % - status: http response code + % - errorCode: optional + % specific error code returned in field errors (only for 400 and 401) % % Returns: (MException) @TODO switch status case 400 - ex = MException('onc:http400', 'HTTP 400: Invalid request parameters'); + ex = MException(sprintf('onc:http400:error%d', errorCode), 'HTTP 400: Invalid request parameters'); case 401 - ex = MException('onc:http401', 'HTTP 401: Invalid token'); + ex = MException(sprintf('onc:http401:error%d', errorCode), 'HTTP 401: Invalid token'); case 404 ex = MException('onc:http404', 'HTTP 404: Not found'); case 410 diff --git a/onc/+util/print_error.m b/onc/+util/print_error.m index 039cf14..e1507f1 100644 --- a/onc/+util/print_error.m +++ b/onc/+util/print_error.m @@ -4,32 +4,48 @@ function print_error(response, url) status = double(response.StatusCode); if status == 400 + % Bad request fprintf('\nERROR 400 - Bad Request:\n %s\n\n', url) - payload = response.Body.Data; + print_error_message(response.Body.Data); - % Make sure the payload was parsed automatically - if ~isstruct(payload) - payload = jsondecode(payload); - end + elseif status == 401 + % Unauthorized + fprintf('\nERROR 401: Unauthorized. Please verify your user token.\n') + print_error_message(response.Body.Data) - if isfield(payload, 'errors') - for i = 1 : numel(payload.errors) - e = payload.errors(i); - msg = e.errorMessage; - parameters = e.parameter; - fprintf(' Parameter "%s" -> %s\n', string(parameters), msg) - end - fprintf('\n'); + elseif status == 404 + %Not Found + fprintf('\nERROR 404: Not Found \n') - elseif status == 401 - fprintf('\nERROR 401: Unauthorized - %s\n', url) - fprintf('Please check that your Web Services API token is valid. Find your token in your registered profile at https://data.oceannetworks.ca.\n') + elseif status == 500 + % Internal Server Error + fprintf('\nERROR 500: Internal Server Error - %s\n', url) + fprintf('The API failed to process your request. You might want to retry later in case this is a temporary issue (i.e. Maintenance).\n') + + elseif status == 503 + % Down for maintenance + fprintf('\nERROR 503: Service unavailable.\nWe could be down for maintenance; '); + fprintf('visit https://data.oceannetworks.ca for more information.\n') + + else + fprintf('\nERROR: The request failed with HTTP error %d\n', status); + end +end - elseif status == 500 - fprintf('\nERROR 500: Internal Server Error - %s\n', url) - fprintf('The API failed to process your request. You might want to retry later in case this is a temporary issue (i.e. Maintenance).\n') - else - fprintf('\nERROR %d: The request failed.\n', status) - end +% helper function +function print_error_message(payload) + % Make sure the payload was parsed automatically + if ~isstruct(payload) + payload = jsondecode(payload); end + + %if isfield(payload, 'errors') + for i = 1 : numel(payload.errors) + e = payload.errors(i); + msg = e.errorMessage; + parameters = e.parameter; + fprintf(' Parameter "%s" -> %s\n', string(parameters), msg) + end + fprintf('\n'); end + From 162ad59a3b2b5d00495aec4f10def32e0f81ace6 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Fri, 22 Mar 2024 14:39:41 -0700 Subject: [PATCH 04/35] issue7: rewrite test suites --- onc/tests/suites/Test01_Locations.m | 123 +++---- onc/tests/suites/Test02_Deployments.m | 102 +++--- onc/tests/suites/Test03_DeviceCategories.m | 83 ++--- onc/tests/suites/Test04_Devices.m | 108 +++--- onc/tests/suites/Test05_Properties.m | 82 ++--- .../suites/Test06_DataProductDiscovery.m | 96 +++--- onc/tests/suites/Test07_DataProductDelivery.m | 315 +++++++----------- onc/tests/suites/Test08_RealTime.m | 259 ++++++++++---- onc/tests/suites/Test09_ArchiveFiles.m | 228 ++++++++----- 9 files changed, 704 insertions(+), 692 deletions(-) diff --git a/onc/tests/suites/Test01_Locations.m b/onc/tests/suites/Test01_Locations.m index 03443ba..29cad1b 100644 --- a/onc/tests/suites/Test01_Locations.m +++ b/onc/tests/suites/Test01_Locations.m @@ -1,82 +1,93 @@ % OncTest Locations test suite -% Contains test cases for the locations discovery service. +% Contains test cases for the locations / locationtrees discovery service. -classdef Test01_Locations < TestDiscovery +classdef Test01_Locations < matlab.unittest.TestCase + properties + onc + end - %% Public Methods - methods - - function obj = Test01_Locations() - % Constructor - obj@TestDiscovery(); - obj.expectedFields('getLocations') = ["deployments", "locationName", "depth", "bbox", "description", "hasDeviceData", "lon", "locationCode", "hasPropertyData", "lat", "dataSearchURL"]; + methods (TestClassSetup) + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end - + %% Test methods methods (Test) - %% General test cases - - function testGetAllLocations(this) - % Make an unfiltered locations request - % verifies: expected fields, minimum rows - locations = this.o.getLocations(); - verify_fields(this, locations, this.expectedFields('getLocations')); - this.verify_min_length(locations, 500); + %% getLocations test cases + function testInvalidTimeRangeGreaterStartTime(this) + filters = {'locationCode', 'FGPD','dateFrom', '2020-01-01', 'dateTo', '2019-01-01'}; + verifyError(this, @() this.onc.getLocations(filters), 'onc:http400:error23'); end - - function testISODateRange(this) - % Test a date range with format ISO8601 - filters = {'dateFrom', '2014-02-24T00:00:01.000Z', 'dateTo', '2014-03-24T00:00:01.000Z'}; - locations = this.testSingleFilter('getLocations', filters, 100, NaN); + + function testInvalidTimeRangeFutureStartTime(this) + filters = {'locationCode', 'FGPD', 'dateFrom', '2050-01-01'}; + verifyError(this, @() this.onc.getLocations(filters), 'onc:http400:error25'); end - function testFilterIncludeChildren(this) - % Test filter includeChildren, verify children were obtained - filters = {'includeChildren', 'true', 'locationCode', 'SAAN'}; - locations = this.testSingleFilter('getLocations', filters, 30, NaN); + function testInvalidParamValue(this) + filters = {'locationCode', 'XYZ123'}; + verifyError(this, @() this.onc.getLocations(filters), 'onc:http400:error127'); end - function testWrongLocationCode(this) - % try an invalid locationCode, verify error structure - locations = this.o.getLocations({'locationCode', 'CQS34543BG'}); - verify_error_response(this, locations); + function testInvalidParamName(this) + filters = {'fakeParamName', 'FGPD'}; + verifyError(this, @() this.onc.getLocations(filters), 'onc:http400:error129'); end - function testNoLocationsFound(this) - % try a locations query with 0 results, verify result is an empty 0x0 matrix - locations = this.o.getLocations({'locationCode', 'SAAN', 'dateTo', '1995-03-24T00:00:01.000Z'}); - verifyEqual(this, size(locations), [0 0]); - + function testNoData(this) + filters = {'locationCode', 'FGPD', 'dateTo', '1900-01-01'}; + verifyError(this, @() this.onc.getLocations(filters), 'onc:http404'); end - %% Single filter test cases - % These tests invoke getLocations with a single filter, for every supported filter - % Verifications according to tests documentation at: https://internal.oceannetworks.ca/x/xYI2Ag - function testFilterLocationCode(this) - locations = this.testSingleFilter('getLocations', {'locationCode', 'CQSBG'}, 1, 1); - verifyEqual(this, locations(1).locationName, 'Bubbly Gulch'); + function testValidParams(this) + filters = {'locationCode', 'FGPD', 'dateFrom', '2005-09-17', 'dateTo', '2020-09-17'}; + locations = this.onc.getLocations(filters); + verifyTrue(this, length(locations) >= 1); + expectedLocationsFields = ["deployments", "locationName", "depth", "bbox", ... + "description", "hasDeviceData", "lon", "locationCode",... + "hasPropertyData", "lat", "dataSearchURL"]; + verify_fields(this, locations(1), expectedLocationsFields); + expectedBboxFields = ["maxDepth", "maxLat", "maxLon", "minDepth", "minLat", "minLon"]; + verify_fields(this, locations(1).bbox, expectedBboxFields); end - function testFilterLocationName(this) - locations = this.testSingleFilter('getLocations', {'locationName', 'Bubbly Gulch'}, 1, 1); - verifyEqual(this, locations(1).locationCode, 'CQSBG'); - end + %% Location tree test cases - function testFilterDeviceCategoryCode(this) - locations = this.testSingleFilter('getLocations', {'deviceCategoryCode', 'CTD'}, 50, NaN); + function testTreeInvalidTimeRangeGreaterStartTime(this) + filters = {'locationCode', 'ARCT', 'dateFrom', '2020-01-01', 'dateTo', '2019-01-01'}; + verifyError(this, @() this.onc.getLocationHierarchy(filters), 'onc:http400:error23'); end - - function testFilterDeviceCode(this) - locations = this.testSingleFilter('getLocations', {'deviceCode', 'NORTEKADCP9917'}, 1, NaN); + + function testTreeInvalidTimeRangeFutureStartTime(this) + filters = {'locationCode', 'ARCT', 'dateFrom', '2050-01-01'}; + verifyError(this, @() this.onc.getLocationHierarchy(filters), 'onc:http400:error25'); end - - function testFilterPropertyCode(this) - locations = this.testSingleFilter('getLocations', {'propertyCode', 'co2concentration'}, 1, NaN); + + function testTreeInvalidParamValue(this) + filters = {'locationCode', 'XYZ123'}; + verifyError(this, @() this.onc.getLocationHierarchy(filters), 'onc:http400:error127'); + end + + function testTreeInvalidParamName(this) + filters = {'fakeParamName', 'ARCT'}; + verifyError(this, @() this.onc.getLocationHierarchy(filters), 'onc:http400:error129'); end - function testFilterDataProductCode(this) - locations = this.testSingleFilter('getLocations', {'dataProductCode', 'MP4V'}, 20, NaN); + function testTreeNoData(this) + filters = {'locationCode', 'ARCT', 'dateTo', '1900-01-01'}; + verifyError(this, @() this.onc.getLocationHierarchy(filters), 'onc:http404'); + end + + function testTreeValidParams(this) + filters = {'locationCode', 'ARCT', 'deviceCategoryCode', 'VIDEOCAM'}; + locations = this.onc.getLocationHierarchy(filters); + verifyTrue(this, length(locations) >= 1); + expectedLocationsFields = ["locationName","children","description","hasDeviceData",... + "locationCode","hasPropertyData"]; + verify_fields(this, locations(1), expectedLocationsFields); + verifyTrue(this, length(locations(1).children) >= 1); end end end \ No newline at end of file diff --git a/onc/tests/suites/Test02_Deployments.m b/onc/tests/suites/Test02_Deployments.m index 05f1461..edaa2fd 100644 --- a/onc/tests/suites/Test02_Deployments.m +++ b/onc/tests/suites/Test02_Deployments.m @@ -1,66 +1,58 @@ % Deployments test suite % Contains test cases for the deployments discovery service. -classdef Test02_Deployments < TestDiscovery - - %% Public Methods - methods - - function obj = Test02_Deployments() - % Constructor - obj@TestDiscovery(); - obj.expectedFields('getDeployments') = ["begin", "depth", "deviceCode", "end", "hasDeviceData", "heading", "lat", "locationCode", "lon", "pitch", "roll"]; +classdef Test02_Deployments < matlab.unittest.TestCase + properties + onc + end + + methods (TestClassSetup) + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end %% Test methods methods (Test) %% General test cases - - function testGetAllDeployments(this) - % Make an unfiltered deployments request - % verifies: expected fields, minimum rows - deployments = this.o.getDeployments(); - verify_fields(this, deployments, this.expectedFields('getDeployments')); - this.verify_min_length(deployments, 500); - end - - function testISODateRange(this) - % Test a date range with format ISO8601 - filters = {'dateFrom', '2014-02-24T00:00:01.000Z', 'dateTo', '2014-03-24T00:00:01.000Z'}; - deployments = this.testSingleFilter('getDeployments', filters, 100, NaN); - end - - function testWrongLocationCode(this) - % try an invalid locationCode, verify error structure - deployments = this.o.getDeployments({'locationCode', 'CQS34543BG'}); - verify_error_response(this, deployments); - end - - function testNoDeploymentsFound(this) - % try a deployments query with 0 results, verify result is an empty 0x0 matrix - deployments = this.o.getDeployments({'locationCode', 'SAAN', 'dateTo', '1995-03-24T00:00:01.000Z'}); - verifyEqual(this, size(deployments), [0 0]); - - end - %% Single filter test cases - % These tests invoke getdeployments with a single filter, for every supported filter - % Verifications according to tests documentation at: https://internal.oceannetworks.ca/x/xYI2Ag - - function testFilterLocationCode(this) - deployments = this.testSingleFilter('getDeployments', {'locationCode', 'CQSBG'}, 2, NaN); - end - - function testFilterDeviceCategoryCode(this) - deployments = this.testSingleFilter('getDeployments', {'deviceCategoryCode', 'CTD'}, 50, NaN); - end - - function testFilterDeviceCode(this) - deployments = this.testSingleFilter('getDeployments', {'deviceCode', 'NORTEKADCP9917'}, 1, NaN); - end - - function testFilterPropertyCode(this) - deployments = this.testSingleFilter('getDeployments', {'propertyCode', 'co2concentration'}, 1, NaN); - end + function testInvalidTimeRangeGreaterStartTime(this) + filters = {'locationCode', 'BACAX', 'deviceCategoryCode', 'CTD', 'dateFrom', '2020-01-01', 'dateTo', '2019-01-01'}; + verifyError(this, @() this.onc.getDeployments(filters), 'onc:http400:error23'); + end + + function testInvalidTimeRangeFutureStartTime(this) + filters = {'locationCode', 'BACAX', 'deviceCategoryCode', 'CTD', 'dateFrom', '2050-01-01'}; + verifyError(this, @() this.onc.getDeployments(filters), 'onc:http400:error25'); + end + + function testInvalidParamValue(this) + filters = {'locationCode', 'XYZ123', 'deviceCategoryCode', 'CTD'}; + verifyError(this, @() this.onc.getDeployments(filters), 'onc:http400:error127'); + end + + function testInvalidParamName(this) + filters = {'fakeParamName', 'BACAX', 'deviceCategoryCode', 'CTD'}; + verifyError(this, @() this.onc.getDeployments(filters), 'onc:http400:error129'); + end + + function testNoData(this) + filters = {'locationCode', 'BACAX', 'deviceCategoryCode', 'CTD', 'dateTo', '1900-01-01'}; + verifyError(this, @() this.onc.getDeployments(filters), 'onc:http400:error127'); + end + + function testValidParams(this) + filters = {'locationCode', 'BACAX', 'deviceCategoryCode', 'CTD', 'dateFrom', '2005-09-17', 'dateTo', '2015-09-17T13:00:00.000Z'}; + deployments = this.onc.getDeployments(filters); + verifyTrue(this, length(deployments) >= 1); + expectedDeploymentFields = ["begin", "citation", "depth", "deviceCategoryCode", ... + "deviceCode", "end", "hasDeviceData", "heading", ... + "lat", "locationCode", "lon", "pitch", "roll"]; + verify_fields(this, deployments(1), expectedDeploymentFields); + expectedCitationFields = ["citation", "doi", "landingPageUrl", "queryPid"]; + verify_fields(this, deployments(1).citation, expectedCitationFields); + end + + end end diff --git a/onc/tests/suites/Test03_DeviceCategories.m b/onc/tests/suites/Test03_DeviceCategories.m index f2a4882..9d4bd56 100644 --- a/onc/tests/suites/Test03_DeviceCategories.m +++ b/onc/tests/suites/Test03_DeviceCategories.m @@ -1,67 +1,52 @@ % DeviceCategories test suite % Contains test cases for the deviceCategories discovery service. -classdef Test03_DeviceCategories < TestDiscovery - - %% Public Methods - methods - - function obj = Test03_DeviceCategories() - % Constructor - obj@TestDiscovery(); - obj.expectedFields('getDeviceCategories') = ["description", "deviceCategoryCode", "deviceCategoryName", "hasDeviceData", "longDescription"]; +classdef Test03_DeviceCategories < matlab.unittest.TestCase + properties + onc + end + + methods (TestClassSetup) + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end + %% Test methods methods (Test) %% General test cases - function testGetAllDeviceCategories(this) + function testInvalidParamValue(this) % Make an unfiltered deviceCategories request % verifies: expected fields, minimum rows - deviceCategories = this.o.getDeviceCategories(); - verify_fields(this, deviceCategories, this.expectedFields('getDeviceCategories')); - this.verify_min_length(deviceCategories, 100); + filters = {'deviceCategoryCode','XYZ123'}; + verifyError(this, @() this.onc.getDeviceCategories(filters), 'onc:http400:error127'); end - function testWrongDeviceCategoryCode(this) + function testInvalidParamName(this) % try an invalid locationCode, verify error structure - deviceCategories = this.o.getDeviceCategories({'deviceCategoryCode', 'XYZ321'}); - verify_error_response(this, deviceCategories); - end - - function testNoDeviceCategoriesFound(this) - % try a deviceCategories query with 0 results, verify result is an empty 0x0 matrix - deviceCategories = this.o.getDeviceCategories({'locationCode', 'SAAN', 'propertyCode', 'co2concentration'}); - verifyEqual(this, size(deviceCategories), [0 0]); - end - - %% Single filter test cases - % These tests invoke getDeviceCategories with a single filter, for every supported filter - % Verifications according to tests documentation at: https://internal.oceannetworks.ca/x/xYI2Ag - - function testFilterDeviceCategoryCode(this) - deviceCategories = this.testSingleFilter('getDeviceCategories', {'deviceCategoryCode', 'ADCP1200KHZ'}, 1, 1); - verifyEqual(this, deviceCategories(1).deviceCategoryCode, 'ADCP1200KHZ'); - end - - function testFilterDeviceCategoryName(this) - deviceCategories = this.testSingleFilter('getDeviceCategories', {'deviceCategoryName', 'Current Profiler 1200'}, 1, 1); - verifyEqual(this, deviceCategories(1).deviceCategoryCode, 'ADCP1200KHZ'); - end - - function testFilterDescription(this) - deviceCategories = this.testSingleFilter('getDeviceCategories', {'description', '3D Camera'}, 1, 1); - verifyEqual(this, deviceCategories(1).deviceCategoryCode, 'CAMERA_3D'); - end - - function testFilterLocationCode(this) - deviceCategories = this.testSingleFilter('getDeviceCategories', {'locationCode', 'CQSBG'}, 1, NaN); - end - - function testFilterPropertyCode(this) - deviceCategories = this.testSingleFilter('getDeviceCategories', {'propertyCode', 'co2concentration'}, 1, NaN); + filters = {'fakeParamName', 'CTD'}; + verifyError(this, @() this.onc.getDeviceCategories(filters), 'onc:http400:error129'); + end + + function testNoData(this) + % try a deviceCategories query with 0 results, verify result message + filters = {'deviceCategoryCode', 'CTD', 'deviceCategoryName', 'Conductivity','description','TemperatureXXX'}; + verifyError(this, @() this.onc.getDeviceCategories(filters), 'onc:http404'); + end + + function testValidParams(this) + filters = {'deviceCategoryCode', 'CTD', 'deviceCategoryName', 'Conductivity', 'description', 'Temperature'}; + + deviceCategories = this.onc.getDeviceCategories(filters); + verifyTrue(this, length(deviceCategories) >= 1); + expectedDeviceCategoriesFields = ["cvTerm", "description", "deviceCategoryCode", ... + "deviceCategoryName", "hasDeviceData", "longDescription"]; + verify_fields(this, deviceCategories(1), expectedDeviceCategoriesFields); + expectedCvTermFields = ["uri", "vocabulary"]; + verify_fields(this, deviceCategories(1).cvTerm.deviceCategory, expectedCvTermFields); end end end diff --git a/onc/tests/suites/Test04_Devices.m b/onc/tests/suites/Test04_Devices.m index f0f4d4b..66b3bbb 100644 --- a/onc/tests/suites/Test04_Devices.m +++ b/onc/tests/suites/Test04_Devices.m @@ -1,76 +1,58 @@ % Devices test suite % Contains test cases for the devices discovery service. -classdef Test04_Devices < TestDiscovery +classdef Test04_Devices < matlab.unittest.TestCase - %% Public Methods - methods - - function obj = Test04_Devices() - % Constructor - obj@TestDiscovery(); - obj.expectedFields('getDevices') = ["dataRating", "deviceCode", "deviceId", "deviceLink", "deviceName"]; + properties + onc + end + + methods (TestClassSetup) + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end %% Test methods methods (Test) %% General test cases - - function testGetAllDevices(this) - % Make an unfiltered Ddvices request - % verifies: expected fields, minimum rows - devices = this.o.getDevices(); - verify_fields(this, devices, this.expectedFields('getDevices')); - this.verify_min_length(devices, 300); - end - - function testISODateRange(this) - % Test a date range with format ISO8601 - filters = {'dateFrom', '2014-02-24T00:00:01.000Z', 'dateTo', '2014-03-24T00:00:01.000Z'}; - devices = this.testSingleFilter('getDevices', filters, 100, NaN); - end - - function testWrongDeviceCode(this) - % try an invalid locationCode, verify error structure - devices = this.o.getDevices({'deviceCode', 'XYZ321'}); - verify_error_response(this, devices); - end - - function testNoDevicesFound(this) - % try a Devices query with 0 results, verify result is an empty 0x0 matrix - devices = this.o.getDevices({'locationCode', 'SAAN', 'dateTo', '1995-03-24T00:00:01.000Z'}); - verifyEqual(this, size(devices), [0 0]); - - end - %% Single filter test cases - % These tests invoke getDevices with a single filter, for every supported filter - % Verifications according to tests documentation at: https://internal.oceannetworks.ca/x/xYI2Ag - - function testFilterDeviceCode(this) - devices = this.testSingleFilter('getDevices', {'deviceCode', 'NORTEKADCP9917'}, 1, 1); - verifyEqual(this, devices(1).deviceCode, 'NORTEKADCP9917'); - end - - function testFilterDeviceName(this) - devices = this.testSingleFilter('getDevices', {'deviceName', 'Nortek Aquadopp HR-Profiler 2965'}, 1, 1); - verifyEqual(this, devices(1).deviceCode, 'BC_POD1_AD2M'); - end - - function testFilterLocationCode(this) - devices = this.testSingleFilter('getDevices', {'locationCode', 'CQSBG'}, 1, NaN); - end - - function testFilterDeviceCategoryCode(this) - devices = this.testSingleFilter('getDevices', {'deviceCategoryCode', 'CTD'}, 100, NaN); - end - - function testFilterPropertyCode(this) - devices = this.testSingleFilter('getDevices', {'propertyCode', 'co2concentration'}, 2, NaN); - end - - function testFilterDataProductCode(this) - devices = this.testSingleFilter('getDevices', {'dataProductCode', 'MP4V'}, 20, NaN); + function testInvalidTimeRangeGreaterStartTime(this) + filters = {'deviceCode', 'BPR-Folger-59','dateFrom', '2020-01-01', 'dateTo', '2019-01-01'}; + verifyError(this, @() this.onc.getDevices(filters), 'onc:http400:error23'); + end + + function testInvalidTimeRangeFutureStartTime(this) + filters = {'deviceCode', 'BPR-Folger-59', 'dateFrom', '2050-01-01'}; + verifyError(this, @() this.onc.getDevices(filters), 'onc:http400:error25'); + end + + function testInvalidParamValue(this) + filters = {'deviceCode', 'XYZ123'}; + verifyError(this, @() this.onc.getDevices(filters), 'onc:http400:error127'); + end + + function testInvalidParamName(this) + filters = {'fakeParamName', 'BPR-Folger-59'}; + verifyError(this, @() this.onc.getDevices(filters), 'onc:http400:error129'); + end + + function testNoData(this) + filters = {'deviceCode', 'BPR-Folger-59', 'dateTo', '1900-01-01'}; + verifyError(this, @() this.onc.getDevices(filters), 'onc:http404'); + end + + function testValidParams(this) + filters = {'deviceCode', 'BPR-Folger-59', 'dateFrom', '2005-09-17', 'dateTo', '2020-09-17'}; + devices = this.onc.getDevices(filters); + verifyTrue(this, length(devices) >= 1); + expectedDevicesFields = ["cvTerm", "dataRating", "deviceCategoryCode", "deviceCode", ... + "deviceId", "deviceLink", "deviceName", "hasDeviceData"]; + verify_fields(this, devices(1), expectedDevicesFields); + expectedCvTermFields = ["uri", "vocabulary"]; + verify_fields(this, devices(1).cvTerm.device, expectedCvTermFields); + expectedDataRatingFields = ["dateFrom", "dateTo", "samplePeriod", "sampleSize"]; + verify_fields(this, devices(1).dataRating, expectedDataRatingFields); end end end diff --git a/onc/tests/suites/Test05_Properties.m b/onc/tests/suites/Test05_Properties.m index 6381a87..d4346b7 100644 --- a/onc/tests/suites/Test05_Properties.m +++ b/onc/tests/suites/Test05_Properties.m @@ -1,15 +1,15 @@ % Properties test suite % Contains test cases for the properties discovery service. -classdef Test05_Properties < TestDiscovery - - %% Public Methods - methods - - function obj = Test05_Properties() - % Constructor - obj@TestDiscovery(); - obj.expectedFields('getProperties') = ["description", "hasDeviceData", "hasPropertyData", "propertyCode", "propertyName", "uom"]; +classdef Test05_Properties < matlab.unittest.TestCase + properties + onc + end + + methods (TestClassSetup) + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end @@ -17,55 +17,35 @@ methods (Test) %% General test cases - function testGetAllProperties(this) - % Make an unfiltered properties request + function testInvalidParamValue(this) + % Make an unfiltered deviceCategories request % verifies: expected fields, minimum rows - properties = this.o.getProperties(); - verify_fields(this, properties, this.expectedFields('getProperties')); - this.verify_min_length(properties, 150); - end - - function testWrongPropertyCode(this) - % try an invalid propertyCode, verify error structure - properties = this.o.getProperties({'propertyCode', 'XYZ321'}); - verify_error_response(this, properties); - end - - function testNoPropertiesFound(this) - % try a properties query with 0 results, verify result is an empty 0x0 matrix - properties = this.o.getProperties({'locationCode', 'SAAN', 'deviceCategoryCode', 'POWER_SUPPLY'}); - verifyEqual(this, size(properties), [0 0]); - - end - %% Single filter test cases - % These tests invoke getProperties with a single filter, for every supported filter - % Verifications according to tests documentation at: https://internal.oceannetworks.ca/x/xYI2Ag - - function testFilterPropertyCode(this) - properties = this.testSingleFilter('getProperties', {'propertyCode', 'absolutehumidity'}, 1, 1); - verifyEqual(this, properties(1).propertyCode, 'absolutehumidity'); - end - - function testFilterPropertyName(this) - properties = this.testSingleFilter('getProperties', {'propertyName', 'Bender Electrical Resistance'}, 1, 1); - verifyEqual(this, properties(1).propertyCode, 'benderelectricalresistance'); - end - - function testFilterDescription(this) - properties = this.testSingleFilter('getProperties', {'description', 'Kurtosis Statistical Analysis'}, 1, 1); - verifyEqual(this, properties(1).propertyCode, 'kurtosisstatisticalanalysis'); + filters = {'propertyCode','XYZ123'}; + verifyError(this, @() this.onc.getProperties(filters), 'onc:http400:error127'); end - function testFilterLocationCode(this) - properties = this.testSingleFilter('getProperties', {'locationCode', 'ROVMP'}, 10, NaN); + function testInvalidParamName(this) + % try an invalid locationCode, verify error structure + filters = {'fakeParamName', 'conductivity'}; + verifyError(this, @() this.onc.getProperties(filters), 'onc:http400:error129'); end - function testFilterDeviceCategoryCode(this) - properties = this.testSingleFilter('getProperties', {'deviceCategoryCode', 'CTD'}, 10, NaN); + function testNoData(this) + % try a deviceCategories query with 0 results, verify result message + filters = {'propertyCode', 'conductivity', 'locationCode', 'SAAN'}; + verifyError(this, @() this.onc.getProperties(filters), 'onc:http404'); end - function testFilterDeviceCode(this) - properties = this.testSingleFilter('getProperties', {'deviceCode', 'ALECACTW-CAR0014'}, 3, NaN); + function testValidParams(this) + filters = {'propertyCode', 'conductivity', 'locationCode', 'BACAX', 'deviceCategoryCode', 'CTD'}; + + properties = this.onc.getProperties(filters); + verifyTrue(this, length(properties) >= 1); + expectedPropertiesFields = ["cvTerm", "description", "hasDeviceData", ... + "hasPropertyData", "propertyCode", "propertyName", "uom"]; + verify_fields(this, properties(1), expectedPropertiesFields); + expectedCvTermFields = ["uri", "vocabulary"]; + verify_fields(this, properties(1).cvTerm.uom, expectedCvTermFields); end end end diff --git a/onc/tests/suites/Test06_DataProductDiscovery.m b/onc/tests/suites/Test06_DataProductDiscovery.m index d5b6769..111ab3e 100644 --- a/onc/tests/suites/Test06_DataProductDiscovery.m +++ b/onc/tests/suites/Test06_DataProductDiscovery.m @@ -1,15 +1,15 @@ % DataProductsDiscovery test suite % Contains test cases for the dataProducts discovery service. -classdef Test06_DataProductDiscovery < TestDiscovery - - %% Public Methods - methods - - function obj = Test06_DataProductDiscovery() - % Constructor - obj@TestDiscovery(); - obj.expectedFields('getDataProducts') = ["dataProductCode", "dataProductName", "extension", "hasDeviceData", "hasPropertyData", "helpDocument"]; +classdef Test06_DataProductDiscovery < matlab.unittest.TestCase + properties + onc + end + + methods (TestClassSetup) + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end @@ -17,54 +17,38 @@ methods (Test) %% General test cases - function testGetAllDataProducts(this) - % Make an unfiltered dataProducts request + function testInvalidParamValue(this) + % Make an unfiltered deviceCategories request % verifies: expected fields, minimum rows - dataProducts = this.o.getDataProducts(); - verify_fields(this, dataProducts, this.expectedFields('getDataProducts')); - this.verify_min_length(dataProducts, 100); - end - - function testWrongDataProductCode(this) - % try an invalid dataProductCode, verify error structure - dataProducts = this.o.getDataProducts({'dataProductCode', 'XYZ321'}); - verify_error_response(this, dataProducts); - end - - function testNoDataProductsFound(this) - % try a dataProducts query with 0 results, verify result is an empty 0x0 matrix - dataProducts = this.o.getDataProducts({'locationCode', 'SAAN', 'deviceCategoryCode', 'POWER_SUPPLY'}); - verifyEqual(this, size(dataProducts), [0 0]); - - end - %% Single filter test cases - % These tests invoke getDataProducts with a single filter, for every supported filter - % Verifications according to tests documentation at: https://internal.oceannetworks.ca/x/xYI2Ag - - function testFilterDataProductCode(this) - dataProducts = this.testSingleFilter('getDataProducts', {'dataProductCode', 'CPD'}, 1, 1); - verifyEqual(this, dataProducts(1).dataProductCode, 'CPD'); - end - - function testFilterExtension(this) - dataProducts = this.testSingleFilter('getDataProducts', {'extension', 'cor'}, 1, 2); - verifyEqual(this, dataProducts(1).extension, 'cor'); - end - - function testFilterLocationCode(this) - dataProducts = this.testSingleFilter('getDataProducts', {'locationCode', 'SAAN'}, 1, NaN); - end - - function testFilterDeviceCategoryCode(this) - dataProducts = this.testSingleFilter('getDataProducts', {'deviceCategoryCode', 'CTD'}, 20, NaN); - end - - function testFilterDeviceCode(this) - dataProducts = this.testSingleFilter('getDataProducts', {'deviceCode', 'BC_POD1_AD2M'}, 5, NaN); - end - - function testFilterPropertyCode(this) - dataProducts = this.testSingleFilter('getDataProducts', {'propertyCode', 'oxygen'}, 10, NaN); + filters = {'dataProductCode','XYZ123'}; + verifyError(this, @() this.onc.getDataProducts(filters), 'onc:http400:error127'); + end + + function testInvalidParamName(this) + % try an invalid locationCode, verify error structure + filters = {'fakeParamName', 'HSD'}; + verifyError(this, @() this.onc.getDataProducts(filters), 'onc:http400:error129'); + end + + function testNoData(this) + % try a deviceCategories query with 0 results, verify result message + filters = {'dataProductCode', 'HSD', 'extension', 'txt'}; + verifyError(this, @() this.onc.getDataProducts(filters), 'onc:http404'); + end + + function testValidParams(this) + filters = {'dataProductCode', 'HSD', 'extension', 'png'}; + + dataProducts = this.onc.getDataProducts(filters); + verifyTrue(this, length(dataProducts) >= 1); + expectedDataProductFields = ["dataProductCode", "dataProductName", "dataProductOptions", ... + "extension", "hasDeviceData", "hasPropertyData", "helpDocument"]; + verify_fields(this, dataProducts(1), expectedDataProductFields); + expectedDataProductOptions = ["allowableRange", "allowableValues", "defaultValue", ... + "documentation", "option", "suboptions"]; + verify_fields(this, dataProducts(1).dataProductOptions(7), expectedDataProductOptions); + expectedDataProductOptionsAllowableRange = ["lowerBound", "onlyIntegers", "unitOfMeasure", "upperBound"]; + verify_fields(this, dataProducts(1).dataProductOptions(7).allowableRange, expectedDataProductOptionsAllowableRange); end end end diff --git a/onc/tests/suites/Test07_DataProductDelivery.m b/onc/tests/suites/Test07_DataProductDelivery.m index b5abfd2..db393ae 100644 --- a/onc/tests/suites/Test07_DataProductDelivery.m +++ b/onc/tests/suites/Test07_DataProductDelivery.m @@ -4,225 +4,148 @@ classdef Test07_DataProductDelivery < matlab.unittest.TestCase %% Private Properties properties (SetAccess = private) + onc + outPath maxRetries % default max Number of orderDataProduct() retries - - % dummy filters for downloading a data product with 1 file - F_DUMMY1 = struct( ... - 'dataProductCode', 'TSSD', ... - 'extension', 'csv', ... - 'locationCode', 'BACAX', ... - 'deviceCategoryCode', 'ADCP2MHZ', ... - 'dateFrom', '2016-07-27T00:00:00.000Z', ... - 'dateTo', '2016-07-27T00:00:30.000Z', ... - 'dpo_dataGaps', '0', ... - 'dpo_qualityControl', '1', ... - 'dpo_resample', 'none'); - - % dummy filters for downloading a data product with 2 files - F_DUMMY2 = struct( ... + Params = struct( ... 'dataProductCode', 'TSSP', ... 'extension', 'png', ... - 'locationCode', 'CRIP.C1', ... - 'deviceCategoryCode', 'CTD', ... - 'dateFrom', '2019-03-20T00:00:00.000Z', ... - 'dateTo', '2019-03-20T00:30:00.000Z', ... + 'dateFrom', '2019-08-29', ... + 'dateTo', '2019-08-30', ... + 'locationCode', 'CRIP.C1', ... + 'deviceCategoryCode', 'CTD', ... ... 'dpo_qualityControl', '1', ... - 'dpo_resample', 'none'); - - % fake filter - F_FAKE = struct( ... - 'dataProductCode', 'FAKECODE', ... - 'extension', 'XYZ', ... - 'locationCode', 'AREA51', ... - 'deviceCategoryCode', 'AK47', ... - 'dateFrom', '2019-03-20T00:00:00.000Z', ... - 'dateTo', '2019-03-20T00:30:00.000Z', ... - 'dpo_qualityControl', '1', ... - 'dpo_resample', 'none'); + 'dpo_resample', 'none'... + ); + + expectedFields = struct('url', 'char', ... + 'status', 'char', ... + 'size', 'int', ... + 'file', 'char', ... + 'index', 'char', ... + 'downloaded' , 'logical', ... + 'requestCount', 'int', ... + 'fileDownloadTime', 'double'); end methods (TestClassSetup) - function prepareSuite(testCase) - s = rmdir('tests/output/07', 's'); % delete directory contents + function classSetup(this) + config = globals(); + this.outPath = 'output'; + this.onc = Onc(config.token, config.production, config.showInfo, this.outPath, config.timeout); + this.maxRetries = 100; end + end methods (TestClassTeardown) - function cleanSuite(testCase) - s = rmdir('tests/output/07', 's'); % delete directory contents + function cleanSuite(this) + if isfolder(this.outPath) + rmdir(this.outPath, 's'); + end end end %% Protected Methods methods (Access = protected) - - function validStruct = verifyRowStructure(this, data) - validStruct = verify_fields(this, data, ["url", "status", "status", "size", "file", "index", "downloaded", "requestCount", "fileDownloadTime"]); - end - - % Validates that row at index has the status and downloaded provided - function validateRow(this, rows, varargin) - [index, status, downloaded] = util.param(varargin, 'index', '1', 'status', 'complete', 'downloaded', false); - - % grab the row at index - row = rows(1); - for i = 1: numel(rows) - if rows(i).index == index - row = rows(i); - break; - end - end - verifyInstanceOf(this, row, 'struct'); - - % verify properties - verifyEqual(this, row.status, status); - verifyEqual(this, row.downloaded, downloaded); - end - - function cleanDirectory(this, outPath) - % Deletes all files in output directory - delete(strcat(outPath, '/*')); - end - - function onc = prepareOnc(this, outPath) - global config; - onc = Onc(config.token, config.production, config.showInfo, outPath, config.timeout); - end + function updateOncOutPath(this, outPath) + this.onc = Onc(this.onc.token, this.onc.production, this.onc.showInfo, outPath, this.onc.timeout); + end end - %% Public Methods - methods - function this = Test07_DataProductDelivery() - this.maxRetries = 100; - end - end - %% Test methods + %% Test method + %% Testing order method methods (Test) - function test01_order_product_links_only(this) - % Order a dummy data product, only obtain the download links - onc = this.prepareOnc('output/07/01'); - this.cleanDirectory(onc.outPath); - result = onc.orderDataProduct(this.F_DUMMY1, 100, true, false); - rows = result.downloadResults; - - verifyLength(this, rows, 1); - if verifyRowStructure(this, rows(1)) - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', false); - verify_files_in_path(this, onc.outPath, 0); - end - - end - - function test02_order_links_with_metadata(this) - onc = this.prepareOnc('output/07/02'); - this.cleanDirectory(onc.outPath); - result = onc.orderDataProduct(this.F_DUMMY1, 100, true, true); - rows = result.downloadResults; - verifyLength(this, rows, 2); - if verifyRowStructure(this, rows(1)) - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', false); - this.validateRow(rows, 'index', 'meta', 'status', 'complete', 'downloaded', false); - end - verify_files_in_path(this, onc.outPath, 0); + function testInvalidParamValue(this) + filters = this.Params; + filters.dataProductCode ='XYZ123'; + verifyError(this, @() this.onc.orderDataProduct(filters, this.maxRetries), 'onc:http400:error127'); + end + + function testValidDefault(this) + this.updateOncOutPath('output/testValidDefault'); + result = this.onc.orderDataProduct(this.Params); + verifyTrue(this, length(result.downloadResults) == 3, ... + 'The first two are png files, and the third one is the metadata.'); + assertEqual(this, result.downloadResults(1).status, 'complete'); + assertEqual(this, result.downloadResults(1).index, '1'); + assertTrue(this, result.downloadResults(1).downloaded); + + + assertEqual(this, result.downloadResults(3).status, 'complete'); + assertEqual(this, result.downloadResults(3).index, 'meta'); + assertTrue(this, result.downloadResults(3).downloaded); + + verify_files_in_path(this, this.onc.outPath, 3); + verify_field_value_type(this, result.downloadResults(1), this.expectedFields); + end + + function testValidNoMetadata(this) + this.updateOncOutPath('output/testValidNoMetadata'); + result = this.onc.orderDataProduct(this.Params, 'includeMetadataFile', false); + verifyTrue(this, length(result.downloadResults) == 2); + assertEqual(this, result.downloadResults(1).status, 'complete'); + assertEqual(this, result.downloadResults(1).index, '1'); + assertTrue(this, result.downloadResults(1).downloaded); + + verify_files_in_path(this, this.onc.outPath, 2, 'The first two are png files.'); + verify_field_value_type(this, result.downloadResults(1), this.expectedFields); + end + + function testValidResultsOnly(this) + this.updateOncOutPath('output/testValidResultsOnly'); + result = this.onc.orderDataProduct(this.Params, 'downloadResultsOnly', true); + verifyTrue(this, length(result.downloadResults) == 3, ... + 'The first two are png files, and the third one is the metadata.'); + assertEqual(this, result.downloadResults(1).status, 'complete'); + assertEqual(this, result.downloadResults(1).index, '1'); + assertTrue(this, ~result.downloadResults(1).downloaded); + + + assertEqual(this, result.downloadResults(3).status, 'complete'); + assertEqual(this, result.downloadResults(3).index, 'meta'); + assertTrue(this, ~result.downloadResults(3).downloaded); + + verify_files_in_path(this, this.onc.outPath, 0, 'No files should be downloaded when download_results_only is True.'); + verify_field_value_type(this, result.downloadResults(1), this.expectedFields); + + + end + + function testValidManual(this) + this.updateOncOutPath('output/testValidManual'); + requestId = this.onc.requestDataProduct(this.Params).dpRequestId; + runId = this.onc.runDataProduct(requestId).runIds(1); + data = this.onc.downloadDataProduct(runId); + verifyTrue(this, length(data) == 3, ... + 'The first two are png files, and the third one is the metadata.'); + assertEqual(this, data(1).status, 'complete'); + assertEqual(this, data(1).index, '1'); + assertTrue(this, data(1).downloaded); + + + assertEqual(this, data(3).status, 'complete'); + assertEqual(this, data(3).index, 'meta'); + assertTrue(this, data(3).downloaded); + + verify_files_in_path(this, this.onc.outPath, 3); + verify_field_value_type(this, data(1), this.expectedFields); + end - - function test03_order_and_download(this) - onc = this.prepareOnc('output/07/03'); - this.cleanDirectory(onc.outPath); - result = onc.orderDataProduct(this.F_DUMMY1, 100, false, false); - rows = result.downloadResults; - verifyLength(this, rows, 1); - if verifyRowStructure(this, rows(1)) - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', true); - end - verify_files_in_path(this, onc.outPath, 1); - end - - function test04_order_and_download_multiple(this) - onc = this.prepareOnc('output/07/04'); - this.cleanDirectory(onc.outPath); - result = onc.orderDataProduct(this.F_DUMMY2, 100, false, false); - rows = result.downloadResults; - verifyLength(this, rows, 2); - if verifyRowStructure(this, rows(1)) - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', true); - this.validateRow(rows, 'index', '2', 'status', 'complete', 'downloaded', true); - end - verify_files_in_path(this, onc.outPath, 2); - end - - function test05_order_and_download_with_metadata(this) - onc = this.prepareOnc('output/07/05'); - this.cleanDirectory(onc.outPath); - result = onc.orderDataProduct(this.F_DUMMY1, 100, false, true); - rows = result.downloadResults; - verifyLength(this, rows, 2); - if verifyRowStructure(this, rows(1)) - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', true); - this.validateRow(rows, 'index', 'meta', 'status', 'complete', 'downloaded', true); - end - verify_files_in_path(this, onc.outPath, 2); - end - - function test06_order_and_download_multiple_with_metadata(this) - onc = this.prepareOnc('output/07/06'); - this.cleanDirectory(onc.outPath); - result = onc.orderDataProduct(this.F_DUMMY2, 100, false, true); - rows = result.downloadResults; - verifyLength(this, rows, 3); - if verifyRowStructure(this, rows(1)) - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', true); - this.validateRow(rows, 'index', '2', 'status', 'complete', 'downloaded', true); - this.validateRow(rows, 'index', 'meta', 'status', 'complete', 'downloaded', true); - end - verify_files_in_path(this, onc.outPath, 3); - end - - function test07_wrong_order_request_argument(this) - onc = this.prepareOnc('output/07/07'); - this.cleanDirectory(onc.outPath); - verifyError(this, @() onc.orderDataProduct(this.F_FAKE, 100, true, false), 'onc:http400'); - end - - function test08_manual_request_run_and_download(this) - onc = this.prepareOnc('output/07/08'); - this.cleanDirectory(onc.outPath); - reqId = onc.requestDataProduct(this.F_DUMMY1).dpRequestId; - runId = onc.runDataProduct(reqId).runIds(1); - rows = onc.downloadDataProduct( ... - runId, 'maxRetries', 0, 'downloadResultsOnly', false, 'includeMetadataFile', true); - verifyLength(this, rows, 2); - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', true); - this.validateRow(rows, 'index', 'meta', 'status', 'complete', 'downloaded', true); - verify_files_in_path(this, onc.outPath, 2); - end - - function test09_manual_request_run_and_download_results_only(this) - onc = this.prepareOnc('output/07/09'); - this.cleanDirectory(onc.outPath); - reqId = onc.requestDataProduct(this.F_DUMMY1).dpRequestId; - runId = onc.runDataProduct(reqId).runIds(1); - rows = onc.downloadDataProduct(runId, 'downloadResultsOnly', true, 'includeMetadataFile', true); - verifyLength(this, rows, 2); - this.validateRow(rows, 'index', '1', 'status', 'complete', 'downloaded', false); - this.validateRow(rows, 'index', 'meta', 'status', 'complete', 'downloaded', false); - verify_files_in_path(this, onc.outPath, 0); - end - - function test10_manual_run_with_wrong_argument(this) - onc = this.prepareOnc('output/07/10'); - this.cleanDirectory(onc.outPath); - verifyError(this, @() onc.runDataProduct(1234568790), 'onc:http400'); + + %% Testing run method + function testInvalidRequestId(this) + verifyError(this, @() this.onc.runDataProduct(1234567890), 'onc:http400:error127'); end - - function test11_manual_download_with_wrong_argument(this) - onc = this.prepareOnc('output/07/11'); - this.cleanDirectory(onc.outPath); - verifyError(this, ... - @() onc.downloadDataProduct(1234568790, 'downloadResultsOnly', false, 'includeMetadataFile', true), ... - 'DataProductFile:HTTP400'); + + %% Testing download method + function testInvalidRunId(this) + verifyError(this, @() this.onc.downloadDataProduct(1234567890), 'onc:http400:error127'); end end + + + end diff --git a/onc/tests/suites/Test08_RealTime.m b/onc/tests/suites/Test08_RealTime.m index 6ff7626..982d675 100644 --- a/onc/tests/suites/Test08_RealTime.m +++ b/onc/tests/suites/Test08_RealTime.m @@ -1,111 +1,222 @@ classdef Test08_RealTime < matlab.unittest.TestCase properties (SetAccess = private) onc - F_SCALAR1 = struct('locationCode', 'CRIP.C1', 'deviceCategoryCode', 'CTD', 'propertyCode', 'density', ... - 'dateFrom', '2018-03-24T00:00:00.000Z', 'dateTo', '2018-03-24T00:00:15.000Z'); - % 3 pages of temperature, by location - F_SCALAR2 = struct('locationCode', 'CRIP.C1', 'deviceCategoryCode', 'CTD', 'propertyCode', 'density', ... - 'dateFrom', '2018-03-24T00:00:00.000Z', 'dateTo', '2018-03-24T00:00:15.000Z', 'rowLimit', 5); - % 3 pages of temperature - F_SCALAR3 = struct('deviceCode', 'BARIX001', 'dateFrom', '2017-06-08T00:00:00.000Z', 'dateTo', 'PT7M', 'rowLimit', 5); - F_RAW1 = struct('locationCode', 'CRIP.C1', 'deviceCategoryCode', 'CTD', ... - 'dateFrom', '2018-03-24T00:00:00.000Z', 'dateTo', '2018-03-24T00:00:10.000Z'); - F_RAW3 = struct('locationCode', 'CRIP.C1', 'deviceCategoryCode', 'CTD', ... - 'dateFrom', '2018-03-24T00:00:00.000Z', 'dateTo', '2018-03-24T00:00:15.000Z', 'rowLimit', 5); - F_RAWDEV1 = struct('deviceCode', 'BARIX001', 'dateFrom', '2017-06-08T00:00:00.000Z', 'dateTo', 'PT5S'); - F_WRONG_FILTERS = struct('locationCode', 'ONION', 'deviceCategoryCode', 'POTATO', 'propertyCode', 'BANANA', ... - 'dateFrom', '2018-03-24T00:00:00.000Z', 'dateTo', '2018-03-24T00:00:10.000Z'); - F_NODATA = struct('locationCode', 'CRIP.C1 ', 'deviceCategoryCode', 'CTD', ... - 'dateFrom', '2015-03-24T00:00:00.000Z', 'dateTo', '2015-03-24T00:00:10.000Z'); + outPath = 'output'; + paramsLocation = struct('locationCode', 'NCBC',... + 'deviceCategoryCode', 'BPR',... + 'propertyCode', 'seawatertemperature,totalpressure',... + 'dateFrom', '2019-11-23T00:00:00.000Z',... + 'dateTo', '2019-11-23T00:01:00.000Z',... + 'rowLimit', 80000); + + paramsRawLocation = struct('locationCode', 'NCBC',... + 'deviceCategoryCode', 'BPR',... + 'dateFrom', '2019-11-23T00:00:00.000Z',... + 'dateTo', '2019-11-23T00:01:00.000Z',... + 'rowLimit', 80000, ... + 'sizeLimit', 20, ... + 'convertHexToDecimal', false); + + paramsLocationMultiPages = struct('locationCode', 'NCBC',... + 'deviceCategoryCode', 'BPR',... + 'propertyCode', 'seawatertemperature,totalpressure',... + 'dateFrom', '2019-11-23T00:00:00.000Z',... + 'dateTo', '2019-11-23T00:01:00.000Z',... + 'rowLimit', 25); + + paramsRawLocationMultiPages = struct('locationCode', 'NCBC',... + 'deviceCategoryCode', 'BPR',... + 'dateFrom', '2019-11-23T00:00:00.000Z',... + 'dateTo', '2019-11-23T00:01:00.000Z',... + 'rowLimit', 25, ... + 'sizeLimit', 20, ... + 'convertHexToDecimal', false); + + paramsDevice = struct('deviceCode', 'BPR-Folger-59', ... + 'dateFrom', '2019-11-23T00:00:00.000Z', ... + 'dateTo', '2019-11-23T00:01:00.000Z', ... + 'rowLimit', 80000); + + paramsDeviceMultiPages = struct('deviceCode', 'BPR-Folger-59', ... + 'dateFrom', '2019-11-23T00:00:00.000Z', ... + 'dateTo', '2019-11-23T00:01:00.000Z', ... + 'rowLimit', 25); end methods (TestClassSetup) - function prepareSuite(testCase) - s = rmdir('tests/output/08', 's'); % delete directory contents + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end methods (TestClassTeardown) - function cleanSuite(testCase) - s = rmdir('tests/output/08', 's'); % delete directory contents - end - end - - %% Public Methods - methods - % Constructor - function this = Test08_RealTime() - global config; - this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); + function cleanSuite(this) + if isfolder(this.outPath) + rmdir(this.outPath, 's'); + end end end %% Test methods methods (Test) - %% General test cases + %% Testing scalardata location + + function testLocationInvalidParamValue(this) + filters = this.paramsLocation; + filters.locationCode = 'XYZ123'; + verifyError(this, @() this.onc.getDirectByLocation(filters), 'onc:http400:error127'); + end - function test01_scalar_by_location_1_page(this) - response = this.onc.getDirectByLocation(this.F_SCALAR1); - sensorData = response.sensorData(1); - verify_has_field(this, sensorData, 'data'); - verify_field_value(this, sensorData, 'sensorCode', 'Sensor8_Voltage'); - verify_no_next_page(this, response); + function testLocationInvalidParamName(this) + filters = this.paramsLocation; + filters.fakeParamName = 'NCBC'; + verifyError(this, @() this.onc.getDirectByLocation(filters), 'onc:http400:error129'); end - function test02_scalar_by_location_3_pages(this) - response = this.onc.getDirectByLocation(this.F_SCALAR2, true); - sensorData = response.sensorData(1); - verify_has_field(this, sensorData, 'data'); - verify_field_value(this, sensorData, 'sensorCode', 'Sensor8_Voltage'); - verifyLength(this, sensorData.data.values, 15); - verify_no_next_page(this, response); + function testLocationNoData(this) + filters = this.paramsLocation; + filters.dateFrom = '2000-01-01'; + filters.dateTo = '2000-01-02'; + verifyError(this, @() this.onc.getDirectByLocation(filters), 'onc:http400:error127'); end - function test03_scalar_by_location_no_results(this) - response = this.onc.getDirectByLocation(this.F_NODATA); - verifyLength(this, response.sensorData, 0); + function testLocationValidParamsOnePage(this) + result = this.onc.getDirectByLocation(this.paramsLocation); + resultAllPages = this.onc.getDirectByLocation(this.paramsLocationMultiPages, 'allPages', true); + assertTrue(this, length(result.sensorData(1).data.values) > this.paramsLocationMultiPages.rowLimit, ... + 'Test should return at least `rowLimit` rows for each sensor.'); + assertEmpty(this, result.next, 'Test should return only one page.'); + assertEqual(this, resultAllPages.sensorData(1).data, result.sensorData(1).data, ... + 'Test should concatenate rows for all pages.'); + assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); + end + + function testLocationValidParamsMultiplePages(this) + result = this.onc.getDirectByLocation(this.paramsLocationMultiPages); + assertEqual(this, length(result.sensorData(1).data.values), this.paramsLocationMultiPages.rowLimit, ... + 'Test should only return `rowLimit` rows for each sensor.'); + assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); end - function test04_scalar_by_location_wrong_filters(this) - result = this.onc.getDirectByLocation(this.F_WRONG_FILTERS); - verify_error_response(this, result); + %% Testing rawdata location + function testRawLocationInvalidParamValue(this) + filters = this.paramsRawLocation; + filters.locationCode = 'XYZ123'; + verifyError(this, @() this.onc.getDirectRawByLocation(filters), 'onc:http400:error127'); + end + + function testRawLocationInvalidParamName(this) + filters = this.paramsRawLocation; + filters.fakeParamName = 'NCBC'; + verifyError(this, @() this.onc.getDirectRawByLocation(filters), 'onc:http400:error129'); end - function test05_raw_by_location_1_page(this) - response = this.onc.getDirectRawByLocation(this.F_RAW1); - verifyLength(this, response.data.readings, 10); - verify_no_next_page(this, response); + function testRawLocationNoData(this) + filters = this.paramsRawLocation; + filters.dateFrom = '2000-01-01'; + filters.dateTo = '2000-01-02'; + verifyError(this, @() this.onc.getDirectRawByLocation(filters), 'onc:http400:error127'); end - function test06_raw_by_location_3_pages(this) - response = this.onc.getDirectRawByLocation(this.F_RAW3, true); - verifyLength(this, response.data.readings, 15); - verify_no_next_page(this, response); + function testRawLocationValidParamsOnePage(this) + result = this.onc.getDirectRawByLocation(this.paramsRawLocation); + resultAllPages = this.onc.getDirectRawByLocation(this.paramsRawLocationMultiPages, 'allPages', true); + assertTrue(this, length(result.data.readings) > this.paramsRawLocationMultiPages.rowLimit, ... + 'Test should return at least `rowLimit` rows'); + assertEmpty(this, result.next, 'Test should return only one page.'); + assertEqual(this, resultAllPages.data, result.data, ... + 'Test should concatenate rows for all pages.'); + assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); + end + + function testRawLocationValidParamsMultiplePages(this) + result = this.onc.getDirectRawByLocation(this.paramsRawLocationMultiPages); + assertEqual(this, length(result.data.readings), this.paramsRawLocationMultiPages.rowLimit, ... + 'Test should only return `rowLimit` rows for each sensor.'); + assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); + end + + %% Testing scalardata device + + function testDeviceInvalidParamValue(this) + filters = this.paramsDevice; + filters.deviceCode = 'XYZ123'; + verifyError(this, @() this.onc.getDirectByDevice(filters), 'onc:http400:error127'); end - function test07_raw_by_device_1_page(this) - response = this.onc.getDirectRawByDevice(this.F_RAWDEV1); - verifyLength(this, response.data.readings, 47); - verify_no_next_page(this, response); + function testDeviceInvalidParamName(this) + filters = this.paramsDevice; + filters.fakeParamName = 'BPR-Folger-59'; + verifyError(this, @() this.onc.getDirectByDevice(filters), 'onc:http400:error129'); end - function test08_raw_no_results(this) - response = this.onc.getDirectRawByLocation(this.F_NODATA); - verifyLength(this, response.data.readings, 0); + function testDeviceNoData(this) + filters = this.paramsDevice; + filters.dateFrom = '2000-01-01'; + filters.dateTo = '2000-01-02'; + result = this.onc.getDirectByDevice(filters); + assertEmpty(this, result.sensorData); end - function test09_raw_by_location_wrong_filters(this) - result = this.onc.getDirectRawByLocation(this.F_WRONG_FILTERS); - verify_error_response(this, result); + function testDeviceValidParamsOnePage(this) + result = this.onc.getDirectByDevice(this.paramsDevice); + resultAllPages = this.onc.getDirectByDevice(this.paramsDeviceMultiPages, 'allPages', true); + assertTrue(this, length(result.sensorData(1).data.values) > this.paramsDeviceMultiPages.rowLimit, ... + 'Test should return at least `rowLimit` rows for each sensor.'); + assertEmpty(this, result.next, 'Test should return only one page.'); + assertEqual(this, resultAllPages.sensorData(1).data, result.sensorData(1).data, ... + 'Test should concatenate rows for all pages.'); + assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); + end + + function testDeviceValidParamsMultiplePages(this) + result = this.onc.getDirectByDevice(this.paramsDeviceMultiPages); + assertEqual(this, length(result.sensorData(1).data.values), this.paramsDeviceMultiPages.rowLimit, ... + 'Test should only return `rowLimit` rows for each sensor.'); + assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); end - function test10_scalar_by_device_6_pages(this) - response = this.onc.getDirectByDevice(this.F_SCALAR3, true); - sensorData = response.sensorData(1); - verify_has_field(this, sensorData, 'data'); - verify_field_value(this, sensorData, 'sensorCode', 'analog_input501'); - verifyLength(this, sensorData.data.values, 14); - verify_no_next_page(this, response); + %% Testing rawdata device + %{ + % waiting for python updates + function testRawDeviceInvalidParamValue(this) + filters = this.paramsDevice; + filters.deviceCode = 'XYZ123'; + verifyError(this, @() this.onc.getDirectRawByDevice(filters), 'onc:http400:error127'); + end + + function testRawDeviceInvalidParamName(this) + filters = this.paramsDevice; + filters.fakeParamName = 'BPR-Folger-59'; + verifyError(this, @() this.onc.getDirectRawByDevice(filters), 'onc:http400:error129'); + end + + function testRawDeviceNoData(this) + filters = this.paramsDevice; + filters.dateFrom = '2000-01-01'; + filters.dateTo = '2000-01-02'; + result = this.onc.getDirectByDevice(filters); + assertEmpty(this, result.sensorData); + end + + function testRawDeviceValidParamsOnePage(this) + result = this.onc.getDirectByDevice(this.paramsDevice); + resultAllPages = this.onc.getDirectByDevice(this.paramsDeviceMultiPages, 'allPages', true); + assertTrue(this, length(result.sensorData(1).data.values) > this.paramsDeviceMultiPages.rowLimit, ... + 'Test should return at least `rowLimit` rows for each sensor.'); + assertEmpty(this, result.next, 'Test should return only one page.'); + assertEqual(this, resultAllPages.sensorData(1).data, result.sensorData(1).data, ... + 'Test should concatenate rows for all pages.'); + assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); + end + + function testRawDeviceValidParamsMultiplePages(this) + result = this.onc.getDirectByDevice(this.paramsDeviceMultiPages); + assertEqual(this, length(result.sensorData(1).data.values), this.paramsDeviceMultiPages.rowLimit, ... + 'Test should only return `rowLimit` rows for each sensor.'); + assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); end + %} end end \ No newline at end of file diff --git a/onc/tests/suites/Test09_ArchiveFiles.m b/onc/tests/suites/Test09_ArchiveFiles.m index a362dda..2a30a94 100644 --- a/onc/tests/suites/Test09_ArchiveFiles.m +++ b/onc/tests/suites/Test09_ArchiveFiles.m @@ -1,139 +1,183 @@ classdef Test09_ArchiveFiles < matlab.unittest.TestCase properties (SetAccess = private) onc - F_LOCATION1 = struct("locationCode", "RISS", "deviceCategoryCode", "VIDEOCAM", "dateFrom", "2016-12-01T00:00:00.000Z", "dateTo", "2016-12-01T01:00:00.000Z"); - F_LOCATION3 = struct("locationCode", "RISS", "deviceCategoryCode", "VIDEOCAM", "dateFrom", "2016-12-01T00:00:00.000Z", "dateTo", "2016-12-01T01:00:00.000Z", "rowLimit", 5); - F_LOCATIONFULL = struct("locationCode", "RISS", "deviceCategoryCode", "VIDEOCAM", "dateFrom", "2016-12-01T00:00:00.000Z", "dateTo", "2016-12-01T01:00:00.000Z", "extension", "mp4"); - F_LOC_RETURN1 = struct("locationCode", "RISS", "deviceCategoryCode", "VIDEOCAM", "dateFrom", "2016-12-01T00:00:00.000Z", "dateTo", "2016-12-01T01:00:00.000Z", "rowLimit", 5, "returnOptions", "archiveLocation"); - F_LOC_RETURN2 = struct("locationCode", "RISS", "deviceCategoryCode", "VIDEOCAM", "dateFrom", "2016-12-01T00:00:00.000Z", "dateTo", "2016-12-03T00:00:00.000Z", "rowLimit", 50, "returnOptions", "all", "extension", "mp4"); - F_DEVICE1 = struct("dateFrom", "2010-01-01T00:00:00.000Z", "dateTo", "2010-01-01T00:02:00.000Z"); - F_DEVICE1EXT = struct("deviceCode", "NAXYS_HYD_007", "dateFrom", "2010-01-01T00:00:00.000Z", "dateTo", "2010-01-01T00:02:00.000Z", "extension", "mp3"); - F_GETDIRECT_DEV = struct("dateFrom", "2010-01-01T00:00:00.000Z", "dateTo", "2010-01-01T00:00:30.000Z", "deviceCode", "NAXYS_HYD_007", "returnOptions", "all"); - F_GETDIRECT_LOC = struct("dateFrom", "2016-12-01T00:00:00.000Z", "dateTo", "2016-12-01T01:00:00.000Z", "locationCode", "RISS", "deviceCategoryCode", "VIDEOCAM", "extension", "mp4"); - F_FAKE = struct("locationCode", "AREA51"); + outPath = 'output'; + paramsLocation = struct( ... + 'locationCode', 'NCBC',... + 'deviceCategoryCode', 'BPR',... + 'dateFrom', '2019-11-23',... + 'dateTo', '2019-11-26',... + 'fileExtension', 'txt',... + 'rowLimit', 80000,... + 'page', 1); + + paramsLocationMultiPages = struct( ... + 'locationCode', 'NCBC',... + 'deviceCategoryCode', 'BPR',... + 'dateFrom', '2019-11-23',... + 'dateTo', '2019-11-26',... + 'fileExtension', 'txt',... + 'rowLimit', 2,... + 'page', 1); + + paramsDevice = struct('deviceCode', 'BPR-Folger-59',... + 'dateFrom', '2019-11-23',... + 'dateTo', '2019-11-26',... + 'fileExtension', 'txt',... + 'rowLimit', 80000,... + 'page', 1); + + paramsDeviceMultiPages = struct('deviceCode', 'BPR-Folger-59',... + 'dateFrom', '2019-11-23',... + 'dateTo', '2019-11-26',... + 'fileExtension', 'txt',... + 'rowLimit', 2,... + 'page', 1); end methods (TestClassSetup) - function prepareSuite(testCase) - s = rmdir('tests/output/09', 's'); % delete directory contents + function classSetup(this) + config = globals(); + this.onc = Onc(config.token, config.production, config.showInfo, this.outPath, config.timeout); end + end methods (TestClassTeardown) - function cleanSuite(testCase) - s = rmdir('tests/output/09', 's'); % delete directory contents + function cleanSuite(this) + if isfolder(this.outPath) + rmdir(this.outPath, 's'); + end end end - %% Public Methods - methods - % Constructor - function this = Test09_ArchiveFiles() - % prepare generic onc object - global config; - this.onc = Onc(config.token, config.production, config.showInfo, 'output/09', config.timeout); - end - - function onc = prepareOnc(this, outPath) - global config; - if ~isempty(outPath) - delete(sprintf('%s/*', outPath)); - end - onc = Onc(config.token, config.production, config.showInfo, outPath, config.timeout); - end + %% Protected helper method + methods (Access = protected) + function updateOncOutPath(this, outPath) + this.onc = Onc(this.onc.token, this.onc.production, this.onc.showInfo, outPath, this.onc.timeout); + end end %% Test methods methods (Test) - %% General test cases - - function test01_list_by_location_1_page(this) - result = this.onc.getListByLocation(this.F_LOCATION1); - verifyLength(this, result.files, 15); + %% Testing location + function testLocationInvalidParamValue(this) + filters = this.paramsLocation; + filters.locationCode = 'XYZ123'; + verifyError(this, @() this.onc.getListByLocation(filters), 'onc:http400:error127'); + end + + function testLocationInvalidParamName(this) + filters = this.paramsLocation; + filters.fakeParamName = 'NCBC'; + verifyError(this, @() this.onc.getListByLocation(filters), 'onc:http400:error129'); end - function test02_list_by_location_3_pages(this) - result = this.onc.getListByLocation(this.F_LOCATION1, true); - verifyLength(this, result.files, 15); + function testLocationNoData(this) + filters = this.paramsLocation; + filters.dateFrom = '2000-01-01'; + filters.dateTo = '2000-01-02'; + verifyError(this, @() this.onc.getListByLocation(filters), 'onc:http400:error127'); end - function test03_list_by_location_1_page_filter_ext(this) - result = this.onc.getListByLocation(this.F_LOCATIONFULL); - verifyLength(this, result.files, 1); + function testLocationValidParamsOnePage(this) + result = this.onc.getListByLocation(this.paramsLocation); + resultAllPages = this.onc.getListByLocation(this.paramsLocationMultiPages, 'allPages', true); + assertTrue(this, length(result.files) > this.paramsLocationMultiPages.rowLimit, ... + 'Test should return at least `rowLimit` rows.'); + assertEmpty(this, result.next, 'Test should return only one page.'); + assertEqual(this, resultAllPages.files, result.files, ... + 'Test should concatenate rows for all pages.'); + assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); end - function test04_list_by_location_wrong_filters(this) - result = this.onc.getListByLocation(this.F_DEVICE1); - verify_error_response(this, result); + function testLocationValidParamsMultiplePages(this) + result = this.onc.getListByLocation(this.paramsLocationMultiPages); + assertEqual(this, length(result.files), this.paramsLocationMultiPages.rowLimit, ... + 'Test should only return `rowLimit` rows.'); + assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); end - function test05_list_by_device_1_page_filter_ext(this) - result = this.onc.getListByDevice(this.F_DEVICE1EXT); - verifyLength(this, result.files, 4); + %% Testing device + + function testDeviceInvalidParamValue(this) + filters = this.paramsDevice; + filters.deviceCode = 'XYZ123'; + verifyError(this, @() this.onc.getListByDevice(filters), 'onc:http400:error127'); end - function test06_get_file(this) - onc9 = this.prepareOnc('output/09/06'); - onc9.getFile('NAXYS_HYD_007_20091231T235919.476Z-spect-small.png'); - verify_files_in_path(this, onc9.outPath, 1); + function testDeviceInvalidParamsMissingRequired(this) + filters = rmfield(this.paramsDevice, 'deviceCode'); + verifyError(this, @() this.onc.getListByDevice(filters), 'onc:http400:error128'); end - function test07_direct_files_device_returnOptions(this) - onc9 = this.prepareOnc('output/09/07'); - result = onc9.getDirectFiles(this.F_GETDIRECT_DEV); - verify_files_in_path(this, onc9.outPath, 12); - verifyLength(this, result.downloadResults, 12); + function testDeviceInvalidParamName(this) + filters = this.paramsDevice; + filters.fakeParamName = 'BPR-Folger-59'; + verifyError(this, @() this.onc.getListByDevice(filters), 'onc:http400:error129'); end - function test08_direct_files_location_overwrite(this) - onc9 = this.prepareOnc('output/09/08'); - result = onc9.getDirectFiles(this.F_GETDIRECT_LOC); - verifyLength(this, result.downloadResults, 1); - verify_field_value(this, result.downloadResults(1), 'status', 'completed'); - verify_files_in_path(this, onc9.outPath, 1); - result = onc9.getDirectFiles(this.F_GETDIRECT_LOC); - verifyLength(this, result.downloadResults, 1); - verify_field_value(this, result.downloadResults(1), 'status', 'skipped'); - verify_files_in_path(this, onc9.outPath, 1); + function testDeviceNoData(this) + filters = this.paramsDevice; + filters.dateFrom = '2000-01-01'; + filters.dateTo = '2000-01-02'; + result = this.onc.getListByDevice(filters); + assertEmpty(this, result.files); end - function test09_getfile_wrong_filename(this) - onc9 = this.prepareOnc('output/09/09'); - result = onc9.getFile('FAKEFILE.XYZ'); - verify_error_response(this, result); + function testDeviceValidParamsOnePage(this) + result = this.onc.getListByDevice(this.paramsDevice); + resultAllPages = this.onc.getListByDevice(this.paramsDeviceMultiPages, 'allPages', true); + assertTrue(this, length(result.files) > this.paramsDeviceMultiPages.rowLimit, ... + 'Test should return at least `rowLimit` rows.'); + assertEmpty(this, result.next, 'Test should return only one page.'); + assertEqual(this, resultAllPages.files, result.files, ... + 'Test should concatenate rows for all pages.'); + assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); end - function test10_direct_files_no_source(this) - onc9 = this.prepareOnc('output/09/10'); - verifyError(this, ... - @() onc9.getDirectFiles(this.F_FAKE), ... - 'Archive:InvalidFilters'); + function testDeviceValidParamsMultiplePages(this) + result = this.onc.getListByDevice(this.paramsDeviceMultiPages); + assertEqual(this, length(result.files), this.paramsDeviceMultiPages.rowLimit, ... + 'Test should only return `rowLimit` rows.'); + assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); end + + %% Testing download - function test11_list_by_device_wrong_filters(this) - result = this.onc.getListByDevice(this.F_FAKE); - verify_error_response(this, result); + function testDownloadInvalidParamValue(this) + verifyError(this, @() this.onc.getFile('FAKEFILE.XYZ'), 'onc:http400:error96'); end - function test12_list_by_location_3_pages_archiveLocations(this) - result = this.onc.getListByLocation(this.F_LOC_RETURN1, true); - verifyLength(this, result.files, 15); - verify_has_field(this, result.files(1), 'archiveLocation'); + function testDownloadInvalidParamsMissingRequired(this) + verifyError(this, @() this.onc.getFile(), 'onc:http400:error128'); end - function test13_list_by_device_3_pages_extension_all(this) - result = this.onc.getListByLocation(this.F_LOC_RETURN2, true); - verifyLength(this, result.files, 2); - verify_has_field(this, result.files(1), 'uncompressedFileSize') + function testDownloadValidParams(this) + this.updateOncOutPath('output/testDownloadValidParams'); + filename = 'BPR-Folger-59_20191123T000000.000Z.txt'; + this.onc.getFile(filename); + assertTrue(this, exist([this.onc.outPath '/' filename], 'file') == 2); + verifyError(this, @() this.onc.getFile(filename), 'onc:FileExistsError'); + this.onc.getFile(filename, 'overwrite', true); + verify_files_in_path(this, this.onc.outPath, 1); end - function test14_save_file_empty_outpath(this) - filename = 'NAXYS_HYD_007_20091231T235919.476Z-spect-small.png'; - onc9 = this.prepareOnc(''); - result = onc9.getFile(filename); - verifyTrue(this, isfile(filename)); - delete(filename); % clean up + %% Testing direct download + + function testDirectDownloadValidParamsOnePage(this) + this.updateOncOutPath('output/testDirectDownloadValidParamsOnePage'); + data = this.onc.getListByLocation(this.paramsLocation); + result = this.onc.getDirectFiles(this.paramsLocation); + verify_files_in_path(this, this.onc.outPath, length(data.files)); + assertEqual(this, result.stats.fileCount, length(data.files)); end + function testDirectDownloadValidParamsMultiplePages(this) + this.updateOncOutPath('output/testDirectDownloadValidParamsMultiplePages'); + result = this.onc.getDirectFiles(this.paramsLocationMultiPages); + verify_files_in_path(this, this.onc.outPath, this.paramsLocationMultiPages.rowLimit); + assertEqual(this, result.stats.fileCount, this.paramsLocationMultiPages.rowLimit) + end end end \ No newline at end of file From 39d4a0f4fe9f9cd53374c44f4eb29e8d4b9f2686 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 25 Mar 2024 15:21:07 -0700 Subject: [PATCH 05/35] issue7: Modify tests so that can be run with matlab's unittest library functions, change config from global variable to mat, abd update instructions --- onc/tests/README.md | 15 +++--- onc/tests/globals.m | 47 ++++++++++--------- onc/tests/load_config.m | 12 +++++ onc/tests/runAllTests.m | 10 ---- onc/tests/runTestCase.m | 10 ---- onc/tests/runTestSuite.m | 36 -------------- onc/tests/suites/Test01_Locations.m | 2 +- onc/tests/suites/Test02_Deployments.m | 2 +- onc/tests/suites/Test03_DeviceCategories.m | 2 +- onc/tests/suites/Test04_Devices.m | 2 +- onc/tests/suites/Test05_Properties.m | 2 +- .../suites/Test06_DataProductDiscovery.m | 2 +- onc/tests/suites/Test07_DataProductDelivery.m | 2 +- onc/tests/suites/Test08_RealTime.m | 2 +- onc/tests/suites/Test09_ArchiveFiles.m | 2 +- 15 files changed, 55 insertions(+), 93 deletions(-) create mode 100644 onc/tests/load_config.m delete mode 100644 onc/tests/runAllTests.m delete mode 100644 onc/tests/runTestCase.m delete mode 100644 onc/tests/runTestSuite.m diff --git a/onc/tests/README.md b/onc/tests/README.md index 4b88b7c..443550f 100644 --- a/onc/tests/README.md +++ b/onc/tests/README.md @@ -24,20 +24,23 @@ Although each test suite inherits from matlab.unittest.TestCase, each is written 2. Use MATLAB's command window to run all tests, using the commands described below: *Running all tests:* + in folder api-matlab-client, run command: + runtests('onc/tests/suites', 'IncludeSubfolders', true); - runAllTests - +(if it doesn't display test results table at the end, all tests pass. You can also remove semicolon to see test results) + *Running a test suite:* - runTestSuite + runtests() i.e.: - runTestSuite 1 + runtests("Test01_Locations"); *Running a test case:* + + runtests(/) - runTestCase i.e.: - runTestCase Test01_Locations testGetAllLocations + runtests("Test01_Locations/testInvalidTimeRangeGreaterStartTime") **DEVELOPING TESTS** diff --git a/onc/tests/globals.m b/onc/tests/globals.m index cbf416d..9aedd11 100644 --- a/onc/tests/globals.m +++ b/onc/tests/globals.m @@ -1,25 +1,28 @@ -import matlab.unittest.TestSuite; -clc; +function config = globals() + clc; + + addpath(genpath('')); + addpath(genpath('util')); + addpath(genpath('suites')); + addpath(genpath('../')); + + % Change the current folder to the folder of this m-file. -addpath(genpath('')); -addpath(genpath('util')); -addpath(genpath('suites')); -addpath(genpath('../')); + % grab token from "TOKEN" file + f = fopen('TOKEN','r'); + if f > 0 + line = fgetl(f); + fclose(f); + else + line = getenv('TOKEN_STRING'); + end -% Change the current folder to the folder of this m-file. -if(~isdeployed) - cd(fileparts(which(mfilename))); -end - -% configuration used by default unless test cases say otherwise -global config; -config.production = true; -config.showInfo = false; -config.outPath = 'output'; -config.timeout = 60; + % Set and save config + config.production = true; + config.showInfo = false; + config.outPath = 'output'; + config.timeout = 60; + config.token = strtrim(line); -% grab token from "TOKEN" file -f = fopen('TOKEN','r'); -line = fgetl(f); -fclose(f); -config.token = strtrim(line); + save('config.mat', 'config') +end diff --git a/onc/tests/load_config.m b/onc/tests/load_config.m new file mode 100644 index 0000000..4cb62ce --- /dev/null +++ b/onc/tests/load_config.m @@ -0,0 +1,12 @@ +function config = load_config() + % Change the current folder to the folder of this m-file. + if(~isdeployed) + cd(fileparts(which(mfilename))); + end + + % If exist config load directly else run globals to get config + if exist('config.mat', 'file') + load('config.mat', 'config'); + else + config = globals(); + end diff --git a/onc/tests/runAllTests.m b/onc/tests/runAllTests.m deleted file mode 100644 index 229497b..0000000 --- a/onc/tests/runAllTests.m +++ /dev/null @@ -1,10 +0,0 @@ -function runAllTests() - import matlab.unittest.TestSuite; - run('globals.m'); - - % Runs all tests suites and displays results - suiteFolder = TestSuite.fromFolder('./suites'); - testResults = run(suiteFolder); - rt = table(testResults); - disp(rt); -end \ No newline at end of file diff --git a/onc/tests/runTestCase.m b/onc/tests/runTestCase.m deleted file mode 100644 index 2a309f6..0000000 --- a/onc/tests/runTestCase.m +++ /dev/null @@ -1,10 +0,0 @@ -function runTestCase(suiteName, caseName) - import matlab.unittest.TestSuite; - run('globals.m'); - - % Run a single test case - obj = eval(suiteName); - testResults = run(obj, caseName); % Method name - rt = table(testResults); - disp(rt); -end \ No newline at end of file diff --git a/onc/tests/runTestSuite.m b/onc/tests/runTestSuite.m deleted file mode 100644 index 55a3f31..0000000 --- a/onc/tests/runTestSuite.m +++ /dev/null @@ -1,36 +0,0 @@ -function runTestSuite(suite) - import matlab.unittest.TestSuite; - run('globals.m'); - - % Run a single test suite - testResults = []; - suite = str2num(suite); - - switch suite - case 1 - testResults = run(Test01_Locations); - case 2 - testResults = run(Test02_Deployments); - case 3 - testResults = run(Test03_DeviceCategories); - case 4 - testResults = run(Test04_Devices); - case 5 - testResults = run(Test05_Properties); - case 6 - testResults = run(Test06_DataProductDiscovery); - case 7 - testResults = run(Test07_DataProductDelivery); - case 8 - testResults = run(Test08_RealTime); - case 9 - testResults = run(Test09_ArchiveFiles); - otherwise - throw(MException('onc:BadSuiteNumber', sprintf('Wrong suite number: %d', suite))); - - end - - rt = table(testResults); - fprintf('\n'); - disp(rt); -end \ No newline at end of file diff --git a/onc/tests/suites/Test01_Locations.m b/onc/tests/suites/Test01_Locations.m index 29cad1b..4d6e2dd 100644 --- a/onc/tests/suites/Test01_Locations.m +++ b/onc/tests/suites/Test01_Locations.m @@ -8,7 +8,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test02_Deployments.m b/onc/tests/suites/Test02_Deployments.m index edaa2fd..0089967 100644 --- a/onc/tests/suites/Test02_Deployments.m +++ b/onc/tests/suites/Test02_Deployments.m @@ -8,7 +8,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test03_DeviceCategories.m b/onc/tests/suites/Test03_DeviceCategories.m index 9d4bd56..3575ad6 100644 --- a/onc/tests/suites/Test03_DeviceCategories.m +++ b/onc/tests/suites/Test03_DeviceCategories.m @@ -8,7 +8,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test04_Devices.m b/onc/tests/suites/Test04_Devices.m index 66b3bbb..95ad925 100644 --- a/onc/tests/suites/Test04_Devices.m +++ b/onc/tests/suites/Test04_Devices.m @@ -9,7 +9,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test05_Properties.m b/onc/tests/suites/Test05_Properties.m index d4346b7..c1803e9 100644 --- a/onc/tests/suites/Test05_Properties.m +++ b/onc/tests/suites/Test05_Properties.m @@ -8,7 +8,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test06_DataProductDiscovery.m b/onc/tests/suites/Test06_DataProductDiscovery.m index 111ab3e..a29a628 100644 --- a/onc/tests/suites/Test06_DataProductDiscovery.m +++ b/onc/tests/suites/Test06_DataProductDiscovery.m @@ -8,7 +8,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test07_DataProductDelivery.m b/onc/tests/suites/Test07_DataProductDelivery.m index db393ae..ff5073a 100644 --- a/onc/tests/suites/Test07_DataProductDelivery.m +++ b/onc/tests/suites/Test07_DataProductDelivery.m @@ -30,7 +30,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.outPath = 'output'; this.onc = Onc(config.token, config.production, config.showInfo, this.outPath, config.timeout); this.maxRetries = 100; diff --git a/onc/tests/suites/Test08_RealTime.m b/onc/tests/suites/Test08_RealTime.m index 982d675..1ac730c 100644 --- a/onc/tests/suites/Test08_RealTime.m +++ b/onc/tests/suites/Test08_RealTime.m @@ -45,7 +45,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); end end diff --git a/onc/tests/suites/Test09_ArchiveFiles.m b/onc/tests/suites/Test09_ArchiveFiles.m index 2a30a94..bedef55 100644 --- a/onc/tests/suites/Test09_ArchiveFiles.m +++ b/onc/tests/suites/Test09_ArchiveFiles.m @@ -37,7 +37,7 @@ methods (TestClassSetup) function classSetup(this) - config = globals(); + config = load_config(); this.onc = Onc(config.token, config.production, config.showInfo, this.outPath, config.timeout); end From 2bbede4bf32f39d21284b59586873d6ecafd1148 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 25 Mar 2024 15:28:26 -0700 Subject: [PATCH 06/35] issue7: Remove, modify and add util files for testing as needed --- onc/tests/util/TestDiscovery.m | 48 ------------------- onc/tests/util/verify_cell_array_length.m | 17 ------- onc/tests/util/verify_downloaded_file.m | 6 --- onc/tests/util/verify_error_response.m | 8 ---- onc/tests/util/verify_field_value.m | 7 +-- onc/tests/util/verify_field_value_not_empty.m | 7 --- onc/tests/util/verify_field_value_type.m | 21 ++++++++ onc/tests/util/verify_files_in_path.m | 9 ++-- onc/tests/util/verify_has_field.m | 6 --- onc/tests/util/verify_min_length.m | 4 -- onc/tests/util/verify_no_next_page.m | 7 --- 11 files changed, 31 insertions(+), 109 deletions(-) delete mode 100644 onc/tests/util/TestDiscovery.m delete mode 100644 onc/tests/util/verify_cell_array_length.m delete mode 100644 onc/tests/util/verify_downloaded_file.m delete mode 100644 onc/tests/util/verify_error_response.m delete mode 100644 onc/tests/util/verify_field_value_not_empty.m create mode 100644 onc/tests/util/verify_field_value_type.m delete mode 100644 onc/tests/util/verify_has_field.m delete mode 100644 onc/tests/util/verify_min_length.m delete mode 100644 onc/tests/util/verify_no_next_page.m diff --git a/onc/tests/util/TestDiscovery.m b/onc/tests/util/TestDiscovery.m deleted file mode 100644 index 385035e..0000000 --- a/onc/tests/util/TestDiscovery.m +++ /dev/null @@ -1,48 +0,0 @@ -classdef TestDiscovery < matlab.unittest.TestCase -% Discovery services generic test model -% Contains common utility functions for discovery test cases - %% Private Properties - properties (SetAccess = private) - o % ONC object - expectedFields % Map of string array with field names expected in a locations response - end - - %% Public Methods - methods - - function obj = TestDiscovery() - % Constructor - global config; - obj.o = Onc(config.token, config.production, config.showInfo, config.outPath, config.timeout); - - obj.expectedFields = containers.Map; - end - end - - %% Protected Methods - methods (Access = protected) - - function verify_min_length(this, data, min) - % Verifies that data has a min length - verifyGreaterThanOrEqual(this, length(data), min); - end - - function result = testSingleFilter(this, methodName, filters, minRows, maxRows) - % Generic single filter test with validation for expected - % filters and min/max result rows - % methodName {String} Name of the method to invoke on ONC object - % filters {CellArray} Cell array of strings, with key, value pairs - % minRows {Number} Min number of rows expected or NaN for no limit - % maxRows {Number} Max number of rows expected or NaN for no limit - result = this.o.(methodName)(filters); - fields = this.expectedFields(methodName); - verify_fields(this, result, fields); - if ~isnan(minRows) - verifyGreaterThanOrEqual(this, length(result), minRows); - end - if ~isnan(maxRows) - verifyLessThanOrEqual(this, length(result), maxRows); - end - end - end -end \ No newline at end of file diff --git a/onc/tests/util/verify_cell_array_length.m b/onc/tests/util/verify_cell_array_length.m deleted file mode 100644 index 1ec177a..0000000 --- a/onc/tests/util/verify_cell_array_length.m +++ /dev/null @@ -1,17 +0,0 @@ -function validLength = verify_cell_array_length(testCase, data, minRows, maxRows) - % verifies that a 1D cell array meets min and max dimensions - % throws verification soft failures in obj if rules are not met - % if min or max are NaN, they are not evaluated - % returns number of rows - validLength = true; - [~, l] = size(data); - - if ~isnan(minRows) - if (l < minRows), validLength = false; end - verifyGreaterThanOrEqual(testCase, l, minRows); - end - if ~isnan(maxRows) - if (l > maxRows), validLength = false; end - verifyLessThanOrEqual(testCase, l, maxRows); - end -end diff --git a/onc/tests/util/verify_downloaded_file.m b/onc/tests/util/verify_downloaded_file.m deleted file mode 100644 index 8c376d8..0000000 --- a/onc/tests/util/verify_downloaded_file.m +++ /dev/null @@ -1,6 +0,0 @@ -function fileExists = verify_downloaded_file(testCase, path) -%verify_downloaded_file Verifies that the file in path exists -% path {string} is an absolute file path - fileExists = (exist(path, 'file') == 2); - verifyTrue(testCase, fileExists); -end diff --git a/onc/tests/util/verify_error_response.m b/onc/tests/util/verify_error_response.m deleted file mode 100644 index d0e38b6..0000000 --- a/onc/tests/util/verify_error_response.m +++ /dev/null @@ -1,8 +0,0 @@ -function verify_error_response(obj, response) - verifyTrue(obj, isfield(response, "errors")) - if isfield(response, "errors") - names = fieldnames(response.errors(1)); - verifyTrue(obj, ismember("errorCode", names)) - verifyTrue(obj, ismember("errorMessage", names)) - end -end \ No newline at end of file diff --git a/onc/tests/util/verify_field_value.m b/onc/tests/util/verify_field_value.m index 074475f..bebf169 100644 --- a/onc/tests/util/verify_field_value.m +++ b/onc/tests/util/verify_field_value.m @@ -2,8 +2,9 @@ function verify_field_value(testCase, data, fieldName, expectedValue) %VERIFYFIELDVALUE Verifies that the fieldName has the expected value only if it exists % Does nothing if fieldName doesnt exist % If value is not as expected, throws a soft failure on testCase - if (isfield(data, fieldName)) - verifyEqual(testCase, data.(fieldName), expectedValue); - end + +% First test if field exist then test value + verifyTrue(testCase, isfield(data, fieldName)); + verifyEqual(testCase, data.(fieldName), expectedValue); end diff --git a/onc/tests/util/verify_field_value_not_empty.m b/onc/tests/util/verify_field_value_not_empty.m deleted file mode 100644 index b403298..0000000 --- a/onc/tests/util/verify_field_value_not_empty.m +++ /dev/null @@ -1,7 +0,0 @@ -function verify_field_value_not_empty(testCase, data, fieldName) -%verify_field_value_not_empty Throws a verification failure if data.fieldName exists but is an empty string -% Doesn't do anything if the field doesn't exist - if isfield(data, fieldName) - verifyNotEqual(testCase, data.(fieldName), ''); - end -end diff --git a/onc/tests/util/verify_field_value_type.m b/onc/tests/util/verify_field_value_type.m new file mode 100644 index 0000000..05f59d3 --- /dev/null +++ b/onc/tests/util/verify_field_value_type.m @@ -0,0 +1,21 @@ +function verify_field_value_type(testCase, dataStruct, expectedStruct) + % Verify that dataStruct contains correct fields and the corresponding values + % are of the correct variable type + % + % Example input: + % dataStruct = struct('fieldName1', data1, 'fieldName2', data2, ...); + % expectedStruct = struct('fieldName1', 'int', 'fieldName2', 'char', ...); + + expectedFieldNames = fieldnames(expectedStruct); + for i = 1 : length(expectedFieldNames) + currField = expectedFieldNames{i}; + verifyTrue(testCase, isfield(dataStruct, currField)); + if strcmp(expectedStruct.(currField), 'int') + verifyTrue(testCase, isa(dataStruct.(currField), 'double')); + % using floor to test if this is an integer + verifyTrue(testCase, floor(dataStruct.(currField)) == dataStruct.(currField)); + else + verifyTrue(testCase, isa(dataStruct.(currField), expectedStruct.(currField))); + end + end +end \ No newline at end of file diff --git a/onc/tests/util/verify_files_in_path.m b/onc/tests/util/verify_files_in_path.m index e245c76..5946a45 100644 --- a/onc/tests/util/verify_files_in_path.m +++ b/onc/tests/util/verify_files_in_path.m @@ -1,5 +1,5 @@ % verifies that path has exactly n files -function verify_files_in_path(obj, path, n) +function verify_files_in_path(obj, path, n, msg) files = dir(sprintf('%s/*.*', path)); % remove . and .. @@ -9,6 +9,9 @@ function verify_files_in_path(obj, path, n) count = count + 1; end end - - verifyEqual(obj, count, n); + if exist('msg', 'var') + verifyEqual(obj, count, n, msg); + else + verifyEqual(obj, count, n); + end end \ No newline at end of file diff --git a/onc/tests/util/verify_has_field.m b/onc/tests/util/verify_has_field.m deleted file mode 100644 index 714578c..0000000 --- a/onc/tests/util/verify_has_field.m +++ /dev/null @@ -1,6 +0,0 @@ -function verify_has_field(testCase, data, fieldName) -%VERIFYFIELDVALUE Verifies that the data is a structire with field fieldName -% Throws a soft failure if the field is not a member - verifyTrue(testCase, isfield(data, fieldName)); -end - diff --git a/onc/tests/util/verify_min_length.m b/onc/tests/util/verify_min_length.m deleted file mode 100644 index 0e51f26..0000000 --- a/onc/tests/util/verify_min_length.m +++ /dev/null @@ -1,4 +0,0 @@ -function verify_min_length(data, min) - % Verifies that data has a min length - verifyGreaterThanOrEqual(length(data), min); -end diff --git a/onc/tests/util/verify_no_next_page.m b/onc/tests/util/verify_no_next_page.m deleted file mode 100644 index 00c4963..0000000 --- a/onc/tests/util/verify_no_next_page.m +++ /dev/null @@ -1,7 +0,0 @@ -function verify_no_next_page(testCase, data) -%VERIFY_NO_NEXT_PAGE only passes if data is a response where next is null - verify_has_field(testCase, data, 'next'); - verifyTrue(testCase, isempty(data.next)); - -end - From da4495eac7d210bf03d6cfe9b2c448482d5197e3 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 25 Mar 2024 15:35:17 -0700 Subject: [PATCH 07/35] issue8: Clean up codes --- onc/+util/do_request.m | 4 ++-- onc/+util/print_error.m | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/onc/+util/do_request.m b/onc/+util/do_request.m index 0b57dc9..ba02eb3 100644 --- a/onc/+util/do_request.m +++ b/onc/+util/do_request.m @@ -25,7 +25,6 @@ % run and time request if showInfo, fprintf('\nRequesting URL:\n %s\n', fullUrl); end tic - %response = send(request, uri, options); response = request.send(uri,options); duration = toc; @@ -52,7 +51,8 @@ otherwise util.print_error(response, fullUrl); if status == 400 || status == 401 - throw(util.prepare_exception(status,double(response.Body.Data.errors.errorCode))); + errorStruct = response.Body.Data; + throw(util.prepare_exception(status, double(errorStruct.errors.errorCode))); else throw(util.prepare_exception(status)); end diff --git a/onc/+util/print_error.m b/onc/+util/print_error.m index e1507f1..d803508 100644 --- a/onc/+util/print_error.m +++ b/onc/+util/print_error.m @@ -39,7 +39,6 @@ function print_error_message(payload) payload = jsondecode(payload); end - %if isfield(payload, 'errors') for i = 1 : numel(payload.errors) e = payload.errors(i); msg = e.errorMessage; From 2bdca3772c4630c0d3e234c8d28e2f26e3c3aaa9 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 25 Mar 2024 15:39:53 -0700 Subject: [PATCH 08/35] issue5: Modify documentation --- onc/+onc/OncDelivery.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index 20ba84f..5e7cc89 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -98,7 +98,7 @@ % runDataProduct (dpRequestId) % % * dpRequestId (int) Request id obtained by requestDataProduct() - % - waitComplete @TODO + % - waitComplete: wait until dp finish when set to true (default) % % Returns: (struct) information of the run process % From f8543d9d89bb3047c48f139ba7687ccc25421021 Mon Sep 17 00:00:00 2001 From: IslaL <142735981+IslaL@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:28:33 -0700 Subject: [PATCH 09/35] remove commented line --- onc/tests/globals.m | 1 - 1 file changed, 1 deletion(-) diff --git a/onc/tests/globals.m b/onc/tests/globals.m index 9aedd11..23100a7 100644 --- a/onc/tests/globals.m +++ b/onc/tests/globals.m @@ -6,7 +6,6 @@ addpath(genpath('suites')); addpath(genpath('../')); - % Change the current folder to the folder of this m-file. % grab token from "TOKEN" file f = fopen('TOKEN','r'); From 838ad491b53e295c50ec1663163c66d0ae9abdab Mon Sep 17 00:00:00 2001 From: Isla Li Date: Tue, 26 Mar 2024 10:11:16 -0700 Subject: [PATCH 10/35] issue4: set up MATLAB workflow --- .github/workflows/matlab.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/matlab.yml diff --git a/.github/workflows/matlab.yml b/.github/workflows/matlab.yml new file mode 100644 index 0000000..3aed878 --- /dev/null +++ b/.github/workflows/matlab.yml @@ -0,0 +1,36 @@ +name: Run MATLAB Tests + +on: + pull_request: + branches: main + push: + branches: main + workflow_dispatch: + +jobs: + tests: + name: MATLAB Test + runs-on: ${{ matrix.os }} + strategy: + matrix: + matlab: [ "R2022b"] + os: [ubuntu-latest, windows-latest] + env: + MLM_LICENSE_FILE: ${{ secrets.MATLAB_LICENSE }} + steps: + - name: Check out repository + uses: actions/checkout@main + + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v2 + with: + release: ${{ matrix.matlab }} + cache: true + + - name: Run tests + uses: matlab-actions/run-tests@v2 + with: + source-folder: 'onc' + env: + TOKEN_STRING: ${{ secrets.TOKEN_STRING }} + From 179f8d6c8bc97addb3498415d2041f7ffaf7d582 Mon Sep 17 00:00:00 2001 From: IslaL <142735981+IslaL@users.noreply.github.com> Date: Tue, 26 Mar 2024 13:22:52 -0700 Subject: [PATCH 11/35] Update variable name line to token, TOKEN_STRING to TOKEN --- onc/tests/globals.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/onc/tests/globals.m b/onc/tests/globals.m index 23100a7..baffae5 100644 --- a/onc/tests/globals.m +++ b/onc/tests/globals.m @@ -10,10 +10,10 @@ % grab token from "TOKEN" file f = fopen('TOKEN','r'); if f > 0 - line = fgetl(f); + token = fgetl(f); fclose(f); else - line = getenv('TOKEN_STRING'); + token = getenv('TOKEN'); end % Set and save config @@ -21,7 +21,7 @@ config.showInfo = false; config.outPath = 'output'; config.timeout = 60; - config.token = strtrim(line); + config.token = strtrim(token); save('config.mat', 'config') end From ac7fd85bb33d93be9b7016edea9ffd54be7c7e11 Mon Sep 17 00:00:00 2001 From: IslaL <142735981+IslaL@users.noreply.github.com> Date: Tue, 26 Mar 2024 13:24:00 -0700 Subject: [PATCH 12/35] Update variable name TOKEN_STRING to TOKEN --- .github/workflows/matlab.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/matlab.yml b/.github/workflows/matlab.yml index 3aed878..f8ab354 100644 --- a/.github/workflows/matlab.yml +++ b/.github/workflows/matlab.yml @@ -13,7 +13,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - matlab: [ "R2022b"] + matlab: ["R2022b"] os: [ubuntu-latest, windows-latest] env: MLM_LICENSE_FILE: ${{ secrets.MATLAB_LICENSE }} @@ -32,5 +32,5 @@ jobs: with: source-folder: 'onc' env: - TOKEN_STRING: ${{ secrets.TOKEN_STRING }} + TOKEN: ${{ secrets.TOKEN }} From 0294950fdcb67ff2f28c0858b063569e90ad1486 Mon Sep 17 00:00:00 2001 From: IslaL <142735981+IslaL@users.noreply.github.com> Date: Tue, 26 Mar 2024 13:28:28 -0700 Subject: [PATCH 13/35] Update globals.m to make sure it saves config file in the correct folder --- onc/tests/globals.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/onc/tests/globals.m b/onc/tests/globals.m index baffae5..9293dbe 100644 --- a/onc/tests/globals.m +++ b/onc/tests/globals.m @@ -1,12 +1,16 @@ function config = globals() clc; - + addpath(genpath('')); addpath(genpath('util')); addpath(genpath('suites')); addpath(genpath('../')); - + % Change the current folder to the folder of this m-file. + if(~isdeployed) + cd(fileparts(which(mfilename))); + end + % grab token from "TOKEN" file f = fopen('TOKEN','r'); if f > 0 From 7bf5cd7b72bcb93fe81d3136d9d8149a52213823 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Thu, 28 Mar 2024 16:06:52 -0700 Subject: [PATCH 14/35] issue-8: fixed minor bugs found when testing --- onc/+onc/DataProductFile.m | 50 +++++++++++++++++++++++--------------- onc/+onc/MultiPage.m | 8 +++--- onc/+onc/OncArchive.m | 12 ++++----- onc/+onc/OncDelivery.m | 11 ++------- onc/+util/param.m | 7 +++--- onc/+util/save_as_file.m | 5 ++-- 6 files changed, 48 insertions(+), 45 deletions(-) diff --git a/onc/+onc/DataProductFile.m b/onc/+onc/DataProductFile.m index bc918e5..9ff3024 100644 --- a/onc/+onc/DataProductFile.m +++ b/onc/+onc/DataProductFile.m @@ -57,22 +57,19 @@ % * maxRetries: (int) As provided by the Onc class % % Returns: (integer) The final response's HTTP status code + log = onc.DPLogger(); - this.status = 202; - saveResult = 0; + request = matlab.net.http.RequestMessage; + uri = matlab.net.URI(this.baseUrl); + uri.Query = matlab.net.QueryParameter(this.filters); + fullUrl = char(uri); + options = matlab.net.http.HTTPOptions('ConnectTimeout', timeout, 'ConvertResponse', false); while this.status == 202 - % prepare HTTP request - request = matlab.net.http.RequestMessage; - uri = matlab.net.URI(this.baseUrl); - uri.Query = matlab.net.QueryParameter(this.filters); - fullUrl = char(uri); - options = matlab.net.http.HTTPOptions('ConnectTimeout', timeout, 'ConvertResponse', false); - % run and time request if this.showInfo, log.printLine(sprintf('Requesting URL:\n %s', fullUrl)); end tic - response = send(request, uri, options); + response = request.send(uri,options); duration = toc; this.downloadUrl = fullUrl; @@ -89,6 +86,7 @@ s = this.status; if s == 200 % File downloaded, get filename from header and save + this.downloaded = true; filename = this.extractNameFromHeader(response); this.fileName = filename; @@ -101,31 +99,43 @@ this.fileSize = strlength(response.Body.Data); end %save_as_file doesn't work properly! Use urlwrite instead - [~, saveResult] = urlwrite(uri.EncodedURI,fullfile(outPath, filename)); - %saveResult = util.save_as_file(response, outPath, filename, overwrite); + %[~, saveResult] = urlwrite(uri.EncodedURI,fullfile(outPath, filename)); + % neither urlwrite nor save_as_file works properly, use websave + + + savefilename = fullfile(outPath, filename); + % Create folder if not exist + if ~exist(outPath,'dir') + mkdir(outPath) + end + % saveResult -2: File exists and set to not overwrite 0: done + if ~overwrite && exist(savefilename,'file') == 2 + saveResult = -2; + else + websave(savefilename,uri.EncodedURI); + saveResult = 0; + end this.downloadingTime = round(duration, 3); % log status if saveResult == 0 - log.printLine(sprintf('Downloaded "%s"', this.fileName)); + log.printLine(sprintf('Downloaded "%s"\n', this.fileName)); elseif saveResult == -2 - log.printLine(sprintf('Skipping "%s": File already exists', this.fileName)); + log.printLine(sprintf('Skipping "%s": File already exists\n', this.fileName)); this.status = 777; end elseif s == 202 % Still processing, wait and retry log.printResponse(jsondecode(response.Body.Data)); + %log.printResponse(response.Body.Data); pause(pollPeriod); elseif s == 204 % No data found - log.printLine('No data found.'); + log.printLine('No data found.\n'); elseif s == 400 % API Error util.print_error(response, fullUrl); - err = struct( ... - 'message', sprintf('The request failed with HTTP status %d\n', this.status), ... - 'identifier', 'DataProductFile:HTTP400'); - error(err); + throw(util.prepare_exception(s, double(jsondecode(response.Body.Data).errors.errorCode))); elseif s == 404 % Index too high, no more files to download else @@ -139,7 +149,7 @@ endStatus = this.status; end - function filename = extractNameFromHeader(this, response) + function filename = extractNameFromHeader(~,response) %% Return the file name extracted from the HTTP response % % * response (object) The successful (200) httr response obtained from a download request diff --git a/onc/+onc/MultiPage.m b/onc/+onc/MultiPage.m index 1c923c0..3fa8865 100644 --- a/onc/+onc/MultiPage.m +++ b/onc/+onc/MultiPage.m @@ -208,13 +208,13 @@ end elseif isArchive row0 = response.files(1); + rowEnd = response.files(end); - - if isa(row0, 'char') + if isa(row0, 'char') || iscell(row0) % extract the date from the filename regExp = '\\d{8}T\\d{6}d\\.\\d{3}Z'; - nameFirst = response.files(1); - nameLast = response.files(end); + nameFirst = char(row0); + nameLast = char(rowEnd); mFirst = regexp(nameFirst, regExp, 'once', 'match'); mLast = regexp(nameLast, regExp, 'once', 'match'); if isempty(mFirst) || isempty(mLast) diff --git a/onc/+onc/OncArchive.m b/onc/+onc/OncArchive.m index b5cba9e..bafe497 100644 --- a/onc/+onc/OncArchive.m +++ b/onc/+onc/OncArchive.m @@ -51,7 +51,9 @@ % Returns: (struct) Information on the download result % % Documentation: https://wiki.oceannetworks.ca/display/CLmatlab/Archive+file+download+methods - + if ~exist('filename', 'var') + filename = ''; + end [overwrite, showMsg] = util.param(varargin, 'overwrite', false, 'showMsg', true); url = this.serviceUrl('archivefiles'); @@ -61,10 +63,11 @@ [response, info] = ... util.do_request(url, filters, 'timeout', this.timeout, 'showInfo', this.showInfo, ... - 'rawResponse', true, 'showProgress', true); + 'showProgress', true); if not(info.status == 200) - fileInfo = jsondecode(response); + %fileInfo = jsondecode(response); + fileInfo = response; return; end @@ -76,9 +79,6 @@ if saveStatus == 0 txtStatus = 'completed'; if showMsg, fprintf(' File was downloaded to "%s"\n', filename); end - elseif saveStatus == -2 - if showMsg, fprintf(' File was skipped (already exists).\n'); end - txtStatus = 'skipped'; end fullUrl = this.getDownloadUrl(filename); diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index 5e7cc89..7a0b296 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -33,18 +33,11 @@ fileList = []; % Request the product - [rqData, status] = this.requestDataProduct(filters); - if util.is_failed_response(rqData, status) - r = rqData; - return - end + [rqData, ~] = this.requestDataProduct(filters); % Run the product request [runData, status] = this.runDataProduct(rqData.dpRequestId); - if util.is_failed_response(runData, status) - r = runData; - return; - end + if downloadResultsOnly % Only run and return links diff --git a/onc/+util/param.m b/onc/+util/param.m index 72c56b8..b4cbe90 100644 --- a/onc/+util/param.m +++ b/onc/+util/param.m @@ -15,13 +15,14 @@ addOptional(p, name, defValue); end - if n == 2 - % Handle single element separately to avoid problem with struct param + if n == 2 && isstruct(varargin{2}) + % Handle struct param seperately name = names(1); if length(args) == 1 + % one struct given varargout{1} = args{1}; else - varargout{1} = varargin{2}; + varargout{1} = varargin{2}; end else % parse using inputParser diff --git a/onc/+util/save_as_file.m b/onc/+util/save_as_file.m index 456c730..2a6274a 100644 --- a/onc/+util/save_as_file.m +++ b/onc/+util/save_as_file.m @@ -32,7 +32,7 @@ end if f ~= -1 - fwrite(f, response.Body.Data); + fwrite(f, response); else endCode = -1; return; @@ -44,8 +44,7 @@ return; end else - endCode = -2; - return; + throw(MException('onc:FileExistsError', 'Data product file exists in destination but overwrite is set to false')); end endCode = 0; From 94cf7137df2fcd4ab4851c6452f2c3d8ffd0e3c1 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 8 Apr 2024 16:37:36 -0700 Subject: [PATCH 15/35] issue-16: fix download bug in data product delivery --- onc/+onc/DataProductFile.m | 56 ++++++++++++++++++-------------- onc/+util/extractFileExtension.m | 13 ++++++++ onc/+util/save_as_file.m | 39 ++++++++++++++-------- 3 files changed, 69 insertions(+), 39 deletions(-) create mode 100644 onc/+util/extractFileExtension.m diff --git a/onc/+onc/DataProductFile.m b/onc/+onc/DataProductFile.m index bc918e5..1966d1f 100644 --- a/onc/+onc/DataProductFile.m +++ b/onc/+onc/DataProductFile.m @@ -57,22 +57,19 @@ % * maxRetries: (int) As provided by the Onc class % % Returns: (integer) The final response's HTTP status code + log = onc.DPLogger(); - this.status = 202; - saveResult = 0; + request = matlab.net.http.RequestMessage; + uri = matlab.net.URI(this.baseUrl); + uri.Query = matlab.net.QueryParameter(this.filters); + fullUrl = char(uri); + options = matlab.net.http.HTTPOptions('ConnectTimeout', timeout); while this.status == 202 - % prepare HTTP request - request = matlab.net.http.RequestMessage; - uri = matlab.net.URI(this.baseUrl); - uri.Query = matlab.net.QueryParameter(this.filters); - fullUrl = char(uri); - options = matlab.net.http.HTTPOptions('ConnectTimeout', timeout, 'ConvertResponse', false); - % run and time request if this.showInfo, log.printLine(sprintf('Requesting URL:\n %s', fullUrl)); end tic - response = send(request, uri, options); + response = request.send(uri,options); duration = toc; this.downloadUrl = fullUrl; @@ -89,6 +86,7 @@ s = this.status; if s == 200 % File downloaded, get filename from header and save + this.downloaded = true; filename = this.extractNameFromHeader(response); this.fileName = filename; @@ -98,34 +96,42 @@ if length(lengthData) == 1 this.fileSize = str2double(lengthData.Value); else - this.fileSize = strlength(response.Body.Data); + ext = util.extractFileExtension(filename); + if strcmp(ext, 'xml') + this.fileSize = length(xmlwrite(response.Body.Data)); + else + this.fileSize = strlength(response.Body.Data); + end + end + try + saveResult = util.save_as_file(response.Body.Data, outPath, filename, 'overwrite', overwrite); + catch ME + if strcmp(ME.identifier, 'onc:FileExistsError') + log.printLine(sprintf('Skipping "%s": File already exists\n', this.fileName)); + this.status = 777; + saveResult = -2; + this.downloaded = false; + else + rethrow(ME); + end end - %save_as_file doesn't work properly! Use urlwrite instead - [~, saveResult] = urlwrite(uri.EncodedURI,fullfile(outPath, filename)); - %saveResult = util.save_as_file(response, outPath, filename, overwrite); this.downloadingTime = round(duration, 3); % log status if saveResult == 0 - log.printLine(sprintf('Downloaded "%s"', this.fileName)); - elseif saveResult == -2 - log.printLine(sprintf('Skipping "%s": File already exists', this.fileName)); - this.status = 777; + log.printLine(sprintf('Downloaded "%s"\n', this.fileName)); end elseif s == 202 % Still processing, wait and retry - log.printResponse(jsondecode(response.Body.Data)); + log.printResponse(response.Body.Data); pause(pollPeriod); elseif s == 204 % No data found - log.printLine('No data found.'); + log.printLine('No data found.\n'); elseif s == 400 % API Error util.print_error(response, fullUrl); - err = struct( ... - 'message', sprintf('The request failed with HTTP status %d\n', this.status), ... - 'identifier', 'DataProductFile:HTTP400'); - error(err); + throw(util.prepare_exception(s, double(response.Body.Data.errors.errorCode))); elseif s == 404 % Index too high, no more files to download else @@ -139,7 +145,7 @@ endStatus = this.status; end - function filename = extractNameFromHeader(this, response) + function filename = extractNameFromHeader(~,response) %% Return the file name extracted from the HTTP response % % * response (object) The successful (200) httr response obtained from a download request diff --git a/onc/+util/extractFileExtension.m b/onc/+util/extractFileExtension.m new file mode 100644 index 0000000..a86ff8a --- /dev/null +++ b/onc/+util/extractFileExtension.m @@ -0,0 +1,13 @@ +function ext = extractFileExtension(filename) + % get extension from filename (string or char array) + % this function is called by save_as_file.m to decide which download method to use + + filename = char(filename); + possibleExtensionStartIndex = strfind(filename, '.'); + if ~isempty(possibleExtensionStartIndex) + extensionStartIndex = possibleExtensionStartIndex(end); + ext = filename(extensionStartIndex + 1:end); + else + ext = ''; + end +end \ No newline at end of file diff --git a/onc/+util/save_as_file.m b/onc/+util/save_as_file.m index 456c730..801f76d 100644 --- a/onc/+util/save_as_file.m +++ b/onc/+util/save_as_file.m @@ -6,7 +6,7 @@ % @param fileName Name of the file to save % @param overwrite If true will overwrite files with the same name % @return (numeric) Result code from {0: done, -1: error, -2: fileExists} -function endCode = save_as_file(response, filePath, fileName, varargin) +function endCode = save_as_file(dataToWrite, filePath, fileName, varargin) [overwrite] = util.param(varargin, 'overwrite', false); fullPath = fileName; @@ -25,27 +25,38 @@ try matlabVersion = version('-release'); year = str2double(matlabVersion(1:end-1)); - if year >= 2021 - f = fopen(fullPath, 'w','n','ISO-8859-1'); - else - f = fopen(fullPath, 'w','n'); - end - - if f ~= -1 - fwrite(f, response.Body.Data); + ext = util.extractFileExtension(fileName); + + % if result is an image file or .xml file, use other save methods instead of fwrite. + if strcmp(ext, 'png') || strcmp(ext, 'jpg') + imwrite(dataToWrite, fullPath); + elseif strcmp(ext, 'xml') + xmlwrite(fullPath, dataToWrite); else - endCode = -1; - return; + % open output file + if year >= 2021 + f = fopen(fullPath, 'w','n','ISO-8859-1'); + else + f = fopen(fullPath, 'w','n'); + end + + % write result if open file successfully + if f ~= -1 + fwrite(f, char(dataToWrite)); + else + endCode = -1; + return; + end + fclose(f); end - fclose(f); catch ex disp(ex); endCode = -1; return; end else - endCode = -2; - return; + % if file exists and overwrite is false, raise exception + throw(MException('onc:FileExistsError', 'Data product file exists in destination but overwrite is set to false')); end endCode = 0; From 6c46f9c89af8e5108def79eab49b380e1232df83 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 8 Apr 2024 16:46:45 -0700 Subject: [PATCH 16/35] issue-4: update workflow to test before merge to release branches as well and add option to test against QA or PROD --- .github/workflows/matlab.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/matlab.yml b/.github/workflows/matlab.yml index f8ab354..35a5e17 100644 --- a/.github/workflows/matlab.yml +++ b/.github/workflows/matlab.yml @@ -2,9 +2,13 @@ name: Run MATLAB Tests on: pull_request: - branches: main + branches: + - 'main' + - 'release-staging-*' push: - branches: main + branches: + - 'main' + - 'release-staging-*' workflow_dispatch: jobs: @@ -33,4 +37,5 @@ jobs: source-folder: 'onc' env: TOKEN: ${{ secrets.TOKEN }} + ONC_ENV: true From 5af504e5bb5d24fbbbfd8a4e7a8cb4731dad2aba Mon Sep 17 00:00:00 2001 From: Isla Li Date: Tue, 9 Apr 2024 15:47:00 -0700 Subject: [PATCH 17/35] issue-14: remove commented lines --- onc/+onc/DataProductFile.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/onc/+onc/DataProductFile.m b/onc/+onc/DataProductFile.m index 9ff3024..1f961b7 100644 --- a/onc/+onc/DataProductFile.m +++ b/onc/+onc/DataProductFile.m @@ -98,10 +98,6 @@ else this.fileSize = strlength(response.Body.Data); end - %save_as_file doesn't work properly! Use urlwrite instead - %[~, saveResult] = urlwrite(uri.EncodedURI,fullfile(outPath, filename)); - % neither urlwrite nor save_as_file works properly, use websave - savefilename = fullfile(outPath, filename); % Create folder if not exist @@ -127,7 +123,6 @@ elseif s == 202 % Still processing, wait and retry log.printResponse(jsondecode(response.Body.Data)); - %log.printResponse(response.Body.Data); pause(pollPeriod); elseif s == 204 % No data found From 459c14eca4aced6ce1ae826599765a068cc12317 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Thu, 11 Apr 2024 14:35:45 -0700 Subject: [PATCH 18/35] issue-11: Implement restart, cancel, and status functions and add tests --- onc/+onc/OncDelivery.m | 79 ++++++++++++++++--- onc/+util/is_failed_response.m | 24 ------ onc/tests/globals.m | 8 +- onc/tests/suites/Test07_DataProductDelivery.m | 62 ++++++++++++--- onc/tests/suites/Test08_RealTime.m | 25 +++--- 5 files changed, 140 insertions(+), 58 deletions(-) delete mode 100644 onc/+util/is_failed_response.m diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index 7a0b296..a24cf2a 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -76,12 +76,9 @@ fprintf('Requesting data product...\n'); [r, info] = this.doRequest(url, filters); status = info.status; - if not(util.is_failed_response(r, status)) - this.estimatePollPeriod(r); - this.printProductRequest(r); - else - throw(util.prepare_exception(status)); - end + this.estimatePollPeriod(r); + this.printProductRequest(r); + end function [r, status] = runDataProduct(this, dpRequestId, waitComplete) @@ -106,16 +103,18 @@ % run timed run request tic + cancelUrl = url + "?method=cancel&token="+string(this.token)+"&dpRequestId=" + string(dpRequestId); + if waitComplete + fprintf('\nTo cancel this data product, visit url:\n %s\n', cancelUrl); + else + fprintf('\nTo cancel this data product, please execute command ''onc.cancelDataProduct(%d)''\n', dpRequestId) + end flag = 'queued'; while ~strcmp(flag,'complete') && ~strcmp(flag,'cancelled') [response, info] = this.doRequest(url, filters); status = info.status; r.requestCount = r.requestCount + 1; - % guard against failed request - if util.is_failed_response(response, status) - throw(util.prepare_exception(status)); - end % repeat only if waitComplete if waitComplete log.printResponse(response); @@ -140,6 +139,40 @@ r.runIds = [r.runIds, run.dpRunId]; end end + + function response = checkDataProduct(this, dpRequestId) + %% Check the status of a data product + % + % + % checkDataProduct (dpRequestId) + % + % * dpRequestId (int) Request id obtained by requestDataProduct() + % + % Returns: response (struct): status of this data product + % + url = sprintf('%sapi/dataProductDelivery', this.baseUrl); + filters = struct('method', 'status', 'token', this.token, 'dpRequestId', dpRequestId); + response = this.doRequest(url, filters); + end + + function [response, info] = cancelDataProduct(this, dpRequestId) + %% Cancel a running data product + % + % + % cancelDataProduct (dpRequestId) + % + % * dpRequestId (int) Request id obtained by requestDataProduct() + % + % Returns: response (struct): cancel process status and message + % info (struct): cancel process http code and status + % + url = sprintf('%sapi/dataProductDelivery', this.baseUrl); + filters = struct('method', 'cancel', 'token', this.token, 'dpRequestId', dpRequestId); + [response, info] = this.doRequest(url, filters); + if isfield(response, 'status') && strcmp(response.status, 'cancelled') && info.status == 200 + fprintf("Data product with request id %d and run id %d was successfully cancelled\n", dpRequestId, response.dpRunId); + end + end function fileData = downloadDataProduct(this, runId, varargin) %% Download a data product manually with a runId @@ -169,8 +202,32 @@ fileData = this.downloadProductFiles(runId, metadata, maxRetries, overwrite); end end + + function [response, info] = restartDataProduct(this, dpRequestId, waitComplete) + %% Restart a cancelled data product + % + % + % restartDataProduct (dpRequestId, waitComplete) + % + % * dpRequestId (int) Request id obtained by requestDataProduct() + % - waitComplete (optional): wait until dp finish when set to true (default) + % + % Returns: response (struct): restart process status and message + % info (struct): restart process http code and status + % + if ~exist('waitComplete','var'), waitComplete = true; end + url = sprintf('%sapi/dataProductDelivery', this.baseUrl); + filters = struct('method', 'restart', 'token', this.token, 'dpRequestId', dpRequestId); + [response, info] = this.doRequest(url, filters); + if isfield(response, 'status') && (strcmp(response.status, 'data product running') || strcmp(response.status, 'queued')) && info.status == 200 + fprintf("Restarted data product with request id %d and run id %d\n", dpRequestId, response.dpRunId); + end + if waitComplete + [response, info] = this.runDataProduct(dpRequestId, true); + end + end end - + methods (Access = private, Hidden = true) function fileList = downloadProductFiles(this, runId, varargin) %% Download all data product files for provided run id diff --git a/onc/+util/is_failed_response.m b/onc/+util/is_failed_response.m deleted file mode 100644 index 744181c..0000000 --- a/onc/+util/is_failed_response.m +++ /dev/null @@ -1,24 +0,0 @@ -function isFailed = is_failed_response(response, status) - %% Checks if a server response describes a failure - % - % * response: (struct) Response as returned by do_request() - % - status: @TODO - % - % Returns: (Logical) true when the response is a failure - isFailed = false; - - % Fail if HTTP status code is not a 2xx - if exist('status', 'var') - if status < 200 || status > 226 - isFailed = true; - return - end - end - - % Fail if the response is an error description - if isfield(response, "errors") - names = fieldnames(response.errors(1)); - isFailed = ismember("errorCode", names) && ismember("errorMessage", names); - end -end - diff --git a/onc/tests/globals.m b/onc/tests/globals.m index 9293dbe..daa37ac 100644 --- a/onc/tests/globals.m +++ b/onc/tests/globals.m @@ -11,7 +11,7 @@ cd(fileparts(which(mfilename))); end - % grab token from "TOKEN" file + % grab token from "TOKEN" file or get from env f = fopen('TOKEN','r'); if f > 0 token = fgetl(f); @@ -20,8 +20,12 @@ token = getenv('TOKEN'); end + % get environment from ONC_ENV or use QA as default + config.production = getenv('ONC_ENV'); + if isempty(config.production) + config.production = false; + end % Set and save config - config.production = true; config.showInfo = false; config.outPath = 'output'; config.timeout = 60; diff --git a/onc/tests/suites/Test07_DataProductDelivery.m b/onc/tests/suites/Test07_DataProductDelivery.m index ff5073a..6d6f336 100644 --- a/onc/tests/suites/Test07_DataProductDelivery.m +++ b/onc/tests/suites/Test07_DataProductDelivery.m @@ -113,10 +113,40 @@ function testValidResultsOnly(this) end + + %% Testing run method + function testInvalidRequestId(this) + verifyError(this, @() this.onc.runDataProduct(1234567890), 'onc:http400:error127'); + end + + %% Testing download method + function testInvalidRunId(this) + verifyError(this, @() this.onc.downloadDataProduct(1234567890), 'onc:http400:error127'); + end + + %% Testing cancel method + function testCancelWithInvalidRequestId(this) + verifyError(this, @() this.onc.cancelDataProduct(1234567890), 'onc:http400:error127'); + end + + %% Testing status method + function testStatusWithInvalidRequestId(this) + verifyError(this, @() this.onc.checkDataProduct(1234567890), 'onc:http400:error127'); + end + + %% Testing restart method + function testRestartWithInvalidRequestId(this) + verifyError(this, @() this.onc.restartDataProduct(1234567890), 'onc:http400:error127'); + end + %% Integration tests function testValidManual(this) this.updateOncOutPath('output/testValidManual'); requestId = this.onc.requestDataProduct(this.Params).dpRequestId; + statusBeforeDownload = this.onc.checkDataProduct(requestId); + + assertEqual(this, statusBeforeDownload.searchHdrStatus, 'OPEN'); + runId = this.onc.runDataProduct(requestId).runIds(1); data = this.onc.downloadDataProduct(runId); verifyTrue(this, length(data) == 3, ... @@ -133,16 +163,30 @@ function testValidManual(this) verify_files_in_path(this, this.onc.outPath, 3); verify_field_value_type(this, data(1), this.expectedFields); + statusAfterDownload = this.onc.checkDataProduct(requestId); + assertEqual(this, statusAfterDownload.searchHdrStatus, 'COMPLETED'); end - - %% Testing run method - function testInvalidRequestId(this) - verifyError(this, @() this.onc.runDataProduct(1234567890), 'onc:http400:error127'); - end - - %% Testing download method - function testInvalidRunId(this) - verifyError(this, @() this.onc.downloadDataProduct(1234567890), 'onc:http400:error127'); + + function testValidCancelRestart(this) + this.updateOncOutPath('output/testValidCancelRestart'); + requestId = this.onc.requestDataProduct(this.Params).dpRequestId; + runId = this.onc.runDataProduct(requestId, false).runIds(1); + responseCancel = this.onc.cancelDataProduct(requestId); + + verify_field_value(this, responseCancel, 'dpRunId', runId); + verify_field_value(this, responseCancel, 'status', 'cancelled'); + + %update MATLAB:nonExistentField error to actual http400 error for this test + %after api service fixes the issue that this 400 error does not contain "errors" field + assertError(this, @() this.onc.downloadDataProduct(runId), 'MATLAB:nonExistentField') + + runIdAfterRestart = this.onc.restartDataProduct(requestId).runIds(1); + assertEqual(this, runIdAfterRestart, runId); + + responseDownload = this.onc.downloadDataProduct(runId); + assertEqual(this, length(responseDownload), 3, "The first two are png files, and the third one is the metadata"); + verify_files_in_path(this, this.onc.outPath, 3); + verify_field_value_type(this, responseDownload(1), this.expectedFields); end end diff --git a/onc/tests/suites/Test08_RealTime.m b/onc/tests/suites/Test08_RealTime.m index 1ac730c..ce86798 100644 --- a/onc/tests/suites/Test08_RealTime.m +++ b/onc/tests/suites/Test08_RealTime.m @@ -163,7 +163,7 @@ function testDeviceValidParamsOnePage(this) result = this.onc.getDirectByDevice(this.paramsDevice); resultAllPages = this.onc.getDirectByDevice(this.paramsDeviceMultiPages, 'allPages', true); assertTrue(this, length(result.sensorData(1).data.values) > this.paramsDeviceMultiPages.rowLimit, ... - 'Test should return at least `rowLimit` rows for each sensor.'); + 'Test should return at least `rowLimit` rows.'); assertEmpty(this, result.next, 'Test should return only one page.'); assertEqual(this, resultAllPages.sensorData(1).data, result.sensorData(1).data, ... 'Test should concatenate rows for all pages.'); @@ -178,8 +178,7 @@ function testDeviceValidParamsMultiplePages(this) end %% Testing rawdata device - %{ - % waiting for python updates + function testRawDeviceInvalidParamValue(this) filters = this.paramsDevice; filters.deviceCode = 'XYZ123'; @@ -196,27 +195,29 @@ function testRawDeviceNoData(this) filters = this.paramsDevice; filters.dateFrom = '2000-01-01'; filters.dateTo = '2000-01-02'; - result = this.onc.getDirectByDevice(filters); - assertEmpty(this, result.sensorData); + result = this.onc.getDirectRawByDevice(filters); + assertEmpty(this, result.data.lineTypes); + assertEmpty(this, result.data.readings); + assertEmpty(this, result.data.times); end function testRawDeviceValidParamsOnePage(this) - result = this.onc.getDirectByDevice(this.paramsDevice); - resultAllPages = this.onc.getDirectByDevice(this.paramsDeviceMultiPages, 'allPages', true); - assertTrue(this, length(result.sensorData(1).data.values) > this.paramsDeviceMultiPages.rowLimit, ... + result = this.onc.getDirectRawByDevice(this.paramsDevice); + resultAllPages = this.onc.getDirectRawByDevice(this.paramsDeviceMultiPages, 'allPages', true); + assertTrue(this, length(result.data.readings) > this.paramsDeviceMultiPages.rowLimit, ... 'Test should return at least `rowLimit` rows for each sensor.'); assertEmpty(this, result.next, 'Test should return only one page.'); - assertEqual(this, resultAllPages.sensorData(1).data, result.sensorData(1).data, ... + assertEqual(this, resultAllPages.data, result.data, ... 'Test should concatenate rows for all pages.'); assertEmpty(this, resultAllPages.next, 'Test should return only one page.'); end function testRawDeviceValidParamsMultiplePages(this) - result = this.onc.getDirectByDevice(this.paramsDeviceMultiPages); - assertEqual(this, length(result.sensorData(1).data.values), this.paramsDeviceMultiPages.rowLimit, ... + result = this.onc.getDirectRawByDevice(this.paramsDeviceMultiPages); + assertEqual(this, length(result.data.readings), this.paramsDeviceMultiPages.rowLimit, ... 'Test should only return `rowLimit` rows for each sensor.'); assertTrue(this, ~isempty(result.next), 'Test should return multiple pages.'); end - %} + end end \ No newline at end of file From f2eddac8e64140df35ae224abe52bd302268f173 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Thu, 18 Apr 2024 15:53:29 -0700 Subject: [PATCH 19/35] issue-16: Replaced util function with built-in function fileparts --- onc/+onc/DataProductFile.m | 10 ++++------ onc/+util/extractFileExtension.m | 13 ------------- onc/+util/save_as_file.m | 8 +++----- 3 files changed, 7 insertions(+), 24 deletions(-) delete mode 100644 onc/+util/extractFileExtension.m diff --git a/onc/+onc/DataProductFile.m b/onc/+onc/DataProductFile.m index 4d0ee2d..01ffc33 100644 --- a/onc/+onc/DataProductFile.m +++ b/onc/+onc/DataProductFile.m @@ -95,15 +95,13 @@ % Obtain filesize from headers, or fallback to body string length lengthData = response.getFields('Content-Length'); + [~, ~, ext] = fileparts(filename); if length(lengthData) == 1 this.fileSize = str2double(lengthData.Value); + elseif strcmp(ext, '.xml') + this.fileSize = length(xmlwrite(response.Body.Data)); else - ext = util.extractFileExtension(filename); - if strcmp(ext, 'xml') - this.fileSize = length(xmlwrite(response.Body.Data)); - else - this.fileSize = strlength(response.Body.Data); - end + this.fileSize = strlength(response.Body.Data); end try saveResult = util.save_as_file(response.Body.Data, outPath, filename, 'overwrite', overwrite); diff --git a/onc/+util/extractFileExtension.m b/onc/+util/extractFileExtension.m deleted file mode 100644 index a86ff8a..0000000 --- a/onc/+util/extractFileExtension.m +++ /dev/null @@ -1,13 +0,0 @@ -function ext = extractFileExtension(filename) - % get extension from filename (string or char array) - % this function is called by save_as_file.m to decide which download method to use - - filename = char(filename); - possibleExtensionStartIndex = strfind(filename, '.'); - if ~isempty(possibleExtensionStartIndex) - extensionStartIndex = possibleExtensionStartIndex(end); - ext = filename(extensionStartIndex + 1:end); - else - ext = ''; - end -end \ No newline at end of file diff --git a/onc/+util/save_as_file.m b/onc/+util/save_as_file.m index 0b25928..94fe773 100644 --- a/onc/+util/save_as_file.m +++ b/onc/+util/save_as_file.m @@ -25,13 +25,11 @@ try matlabVersion = version('-release'); year = str2double(matlabVersion(1:end-1)); - - ext = util.extractFileExtension(fileName); - + [~, ~, ext] = fileparts(fileName); % if result is an image file or .xml file, use other save methods instead of fwrite. - if strcmp(ext, 'png') || strcmp(ext, 'jpg') + if strcmp(ext, '.png') || strcmp(ext, '.jpg') imwrite(dataToWrite, fullPath); - elseif strcmp(ext, 'xml') + elseif strcmp(ext, '.xml') xmlwrite(fullPath, dataToWrite); else % open output file From 8f94aabc85b7dc085fe48df3b989b59f0e77bc62 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Thu, 18 Apr 2024 17:02:33 -0700 Subject: [PATCH 20/35] issue-11: update oncEnv from logical values to char --- .github/workflows/matlab.yml | 2 +- onc/tests/globals.m | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/matlab.yml b/.github/workflows/matlab.yml index 35a5e17..69ebcfc 100644 --- a/.github/workflows/matlab.yml +++ b/.github/workflows/matlab.yml @@ -37,5 +37,5 @@ jobs: source-folder: 'onc' env: TOKEN: ${{ secrets.TOKEN }} - ONC_ENV: true + ONC_ENV: 'prod' diff --git a/onc/tests/globals.m b/onc/tests/globals.m index daa37ac..be0c5a7 100644 --- a/onc/tests/globals.m +++ b/onc/tests/globals.m @@ -22,7 +22,9 @@ % get environment from ONC_ENV or use QA as default config.production = getenv('ONC_ENV'); - if isempty(config.production) + if strcmp(config.production, 'prod') + config.production = true; + else config.production = false; end % Set and save config From 2a8c3dc982cfa7f93906743a6bfc1d478d8ae4d7 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 22 Apr 2024 11:33:42 -0700 Subject: [PATCH 21/35] issue-11: add back util function is_failed_response --- onc/+util/is_failed_response.m | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 onc/+util/is_failed_response.m diff --git a/onc/+util/is_failed_response.m b/onc/+util/is_failed_response.m new file mode 100644 index 0000000..9d417ac --- /dev/null +++ b/onc/+util/is_failed_response.m @@ -0,0 +1,23 @@ +function isFailed = is_failed_response(response, status) + %% Checks if a server response describes a failure + % + % * response: (struct) Response as returned by do_request() + % - status: (double) http status code + % + % Returns: (Logical) true when the response is a failure + isFailed = false; + + % Fail if HTTP status code is not a 2xx + if exist('status', 'var') + if status < 200 || status > 226 + isFailed = true; + return + end + end + + % Fail if the response is an error description + if isfield(response, "errors") + names = fieldnames(response.errors(1)); + isFailed = ismember("errorCode", names) && ismember("errorMessage", names); + end +end \ No newline at end of file From daf2ece0c2411ea365ded944b8b2df5dda7f8b72 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Tue, 23 Apr 2024 15:20:54 -0700 Subject: [PATCH 22/35] issue-11: add success and failure messages --- onc/+onc/OncDelivery.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index a24cf2a..ff97483 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -170,7 +170,9 @@ filters = struct('method', 'cancel', 'token', this.token, 'dpRequestId', dpRequestId); [response, info] = this.doRequest(url, filters); if isfield(response, 'status') && strcmp(response.status, 'cancelled') && info.status == 200 - fprintf("Data product with request id %d and run id %d was successfully cancelled\n", dpRequestId, response.dpRunId); + fprintf("The data product with request id %d and run id %d has been successfully cancelled\n", dpRequestId, response.dpRunId); + else + fprintf("Failed to cancel the data Product."); end end @@ -220,7 +222,9 @@ filters = struct('method', 'restart', 'token', this.token, 'dpRequestId', dpRequestId); [response, info] = this.doRequest(url, filters); if isfield(response, 'status') && (strcmp(response.status, 'data product running') || strcmp(response.status, 'queued')) && info.status == 200 - fprintf("Restarted data product with request id %d and run id %d\n", dpRequestId, response.dpRunId); + fprintf("The data product with request id %d and run id %d has been successfully restarted\n", dpRequestId, response.dpRunId); + else + fprintf("Failed to restart the data product"); end if waitComplete [response, info] = this.runDataProduct(dpRequestId, true); From 94c9dafbba15aa498f4b9ad3ce02170694587d44 Mon Sep 17 00:00:00 2001 From: IslaL <142735981+IslaL@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:23:03 -0700 Subject: [PATCH 23/35] add new line characters --- onc/+onc/OncDelivery.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/onc/+onc/OncDelivery.m b/onc/+onc/OncDelivery.m index ff97483..bc35aae 100644 --- a/onc/+onc/OncDelivery.m +++ b/onc/+onc/OncDelivery.m @@ -170,9 +170,9 @@ filters = struct('method', 'cancel', 'token', this.token, 'dpRequestId', dpRequestId); [response, info] = this.doRequest(url, filters); if isfield(response, 'status') && strcmp(response.status, 'cancelled') && info.status == 200 - fprintf("The data product with request id %d and run id %d has been successfully cancelled\n", dpRequestId, response.dpRunId); + fprintf("The data product with request id %d and run id %d has been successfully cancelled.\n", dpRequestId, response.dpRunId); else - fprintf("Failed to cancel the data Product."); + fprintf("Failed to cancel the data Product.\n"); end end @@ -222,9 +222,9 @@ filters = struct('method', 'restart', 'token', this.token, 'dpRequestId', dpRequestId); [response, info] = this.doRequest(url, filters); if isfield(response, 'status') && (strcmp(response.status, 'data product running') || strcmp(response.status, 'queued')) && info.status == 200 - fprintf("The data product with request id %d and run id %d has been successfully restarted\n", dpRequestId, response.dpRunId); + fprintf("The data product with request id %d and run id %d has been successfully restarted.\n", dpRequestId, response.dpRunId); else - fprintf("Failed to restart the data product"); + fprintf("Failed to restart the data product.\n"); end if waitComplete [response, info] = this.runDataProduct(dpRequestId, true); From 5b68f2742ffdf12b9a2d3db964a017634313867c Mon Sep 17 00:00:00 2001 From: Isla Li Date: Wed, 8 May 2024 11:23:07 -0700 Subject: [PATCH 24/35] issue-20: documentation for each service --- doc/Onc.html | 145 +++++++++++++ doc/OncArchive.html | 432 +++++++++++++++++++++++++++++++++++++++ doc/OncDelivery.html | 465 ++++++++++++++++++++++++++++++++++++++++++ doc/OncDiscovery.html | 458 +++++++++++++++++++++++++++++++++++++++++ doc/OncRealTime.html | 305 +++++++++++++++++++++++++++ doc/helptoc.xml | 41 ++++ info.xml | 26 +++ 7 files changed, 1872 insertions(+) create mode 100644 doc/Onc.html create mode 100644 doc/OncArchive.html create mode 100644 doc/OncDelivery.html create mode 100644 doc/OncDiscovery.html create mode 100644 doc/OncRealTime.html create mode 100644 doc/helptoc.xml create mode 100644 info.xml diff --git a/doc/Onc.html b/doc/Onc.html new file mode 100644 index 0000000..7ce17c8 --- /dev/null +++ b/doc/Onc.html @@ -0,0 +1,145 @@ + + + + + Onc + +
+

The ONC class

+

The ONC class provides a wrapper for Oceans 3.0 API requests. All the client library’s functionality is provided as methods of this class. Create an ONC object to access this library’s functionalities.

+

Parameters:

+
    * token ([char]) - The ONC API token, which could be retrieved at https://data.oceannetworks.ca/Profile once logged in.
+    * production (logical, optional, default = True) - Whether the ONC Production server URL is used for service requests.
+            True: Use the production server. 
+            False: Use the internal ONC test server (reserved for ONC staff IP addresses).
+    * showInfo (logical, optional, default = false) - Whether verbose script messages are displayed, such as request url and processing time information.
+            True: Print all information and debug messages (intended for debugging).
+            False: Only print information messages.
+    * outPath ([char], optional, default = 'output') - Output path for downloaded files. The directory will be created if it does not exist during the download.
+    * timeout (int, optional, default = 60) - Number of seconds before a request to the API is canceled
+
+

Returns: The Onc object created.

+

Examples:

+
+onc = ONC("YOUR_TOKEN_HERE", 'showInfo', true, 'outPath', 'myOutPath');
+
+

For detailed information and usage examples, run doc command or visit MATLAB's help browser https://data.oceannetworks.ca/Profile then find Ocean Networks Canada API Client under supplemental software

+
function this = Onc(token, varargin)
+    p = inputParser;
+    addRequired(p, 'token', @ischar);
+    addOptional(p, 'production', true, @islogical);
+    addOptional(p, 'showInfo', false, @islogical);
+    addOptional(p, 'outPath', 'output', @ischar);
+    addOptional(p, 'timeout', 60, @isnumeric);
+    parse(p, token, varargin{:});
+
+    this.token      = strtrim(p.Results.token);
+    this.production = p.Results.production;
+    this.showInfo   = p.Results.showInfo;
+    this.timeout    = p.Results.timeout;
+
+    % sanitize outPath
+    opath = strtrim(p.Results.outPath);
+    if strlength(opath) > 0
+        opath = strrep(opath, '\', '/');
+        if opath(end) == '/'
+            opath = opath(1:end-1);
+        end
+    end
+        this.outPath = opath;
+
+    if not(this.production)
+        this.baseUrl = 'https://qa.oceannetworks.ca/';
+    end
+
+    %If a search tree file exists, load it.  If not, generate and save one
+    [source_path,~,~] = fileparts(which('Onc.m'));
+    tree_path = fullfile(source_path,'onc_tree.mat');
+    if ~exist(tree_path,'file')
+        fprintf('\n Loading ONC search tree.  Accessible with onc.tree \n');
+        tree = util.extract_tree(this);
+        save(tree_path, 'tree')
+    elseif exist(tree_path,'file')
+        %Check if it's more than a week old. If so, update it:
+        dir_files = dir(source_path);
+        filenames = {dir_files(:).name};
+        [~,idx] = ismember('onc_tree.mat',filenames);
+        treeFileDate = dir_files(idx).datenum;
+        if now - treeFileDate > 7
+            fprintf('\n Updating ONC search tree.  Accessible with onc.tree \n');
+            tree = util.extract_tree(this);
+            save(tree_path, 'tree')
+        end
+    end
+    temp = load(tree_path);
+    this.tree = temp.tree;
+    %These codes can then be used for input to onc.getDevices by
+    %providing the locationCodes
+end
+
+ \ No newline at end of file diff --git a/doc/OncArchive.html b/doc/OncArchive.html new file mode 100644 index 0000000..2a40b2d --- /dev/null +++ b/doc/OncArchive.html @@ -0,0 +1,432 @@ + + + + + OncArchive + +
+

ONC Archive Files methods

+

Contents

+ +

ONC Archive File Service

+

Contains the functionality that wraps API archivefile services To be inherited by the Onc class These methods allow users to directly download previously generated data product files from our archive.

+

ONC systems auto-generate and archive files of different types at set time intervals. These archived files can be downloaded without waiting for a generation process to finish (potentially faster than Data product download methods).

+
+

Note

+

Archived files have a unique filename (e.g. “NAXYS_HYD_007_20091231T235919.476Z-spect.png”) that includes the device code (“NAXYS_HYD_007”) and the UTC date-time when the data in the file started being measured (“20091231T235919.476Z”). The filename might contain additional information.

+
+

+
+

Caution

+

Due to security regulations, some very recent files (e.g. hydrophone.wav files in the last hour) might not be made immediately available.

+
+

GetListByLocation(filters, allPages)

+

Get a list of files for a given location and device category filtered by other optional parameters.

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional, default = false) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +
+

Output: +

    +
  • array of structs - File list obtained
  • +
+

+

The API endpoint is /archivefile/location.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are: +

    * locationCode: char array 
+    * deviceCategoryCode: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * .....
+
+

Returns([struct]): API response. Each struct returned contains following fields:

+
    * citations: struct   
+    * files: char array   
+    * queryUrl: struct   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/archivefile/location for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'locationCode', 'NCBC', ...
+    'deviceCategoryCode', 'BPR', ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-26T00:00:00.000Z', ...
+    'dateArchivedFrom', '2019-11-24T00:00:00.000Z', ...
+    'dateArchivedTo', '2019-11-27T00:00:00.000Z', ...
+    'fileExtension', 'txt', ...
+    'rowLimit', 80000, ...
+    'page', 1 ...
+    ); 
+result = onc.getListByLocation(params);
+
+

For more examples, see Onc Archive example live script

+

Source code:

+
function fileList = getListByLocation(this, filters, varargin)
+    [allPages] = util.param(varargin, 'allPages', false);
+    fileList = this.getList(filters, 'location', allPages);
+end
+
+

GetListByDevice(filters, allPages)

+

Get a list of files for a given device filtered by other optional parameters.

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional, default = false) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +

+

Output: +

    +
  • array of structs - File list obtaine
  • +

+

The API endpoint is /archivefile/location.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are:

+
    * deviceCode: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * dateArchivedFrom: char array   
+    * dateArchivedTo: char array   
+    * .....
+

Returns([struct]): API response. Each struct returned contains following fields:

+
    * citations: struct   
+    * files: char array   
+    * queryUrl: struct   
+    * ......
+

See https://data.oceannetworks.ca/OpenAPI#get-/archivefile/location for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'deviceCode', 'BPR-Folger-59', ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-26T00:00:00.000Z', ...
+    'dateArchivedFrom', '2019-11-24T00:00:00.000Z', ...
+    'dateArchivedTo', '2019-11-27T00:00:00.000Z', ...
+    'fileExtension', 'txt', ...
+    'rowLimit', 80000, ...
+    'page', 1 ...
+    ); 
+result = onc.getListByDevice(params);
+
+

For more examples, see Onc Archive example live script

+

Source code:

+
function r = getListByDevice(this, filters, varargin)
+    [allPages] = util.param(varargin, 'allPages', false);
+    r = this.getList(filters, 'device', allPages);
+end
+
+

GetFile(filename, overwrite)

+

Download the archive file identified by filename

+

Input: +

    +
  • filename(char array) - Archive file filename
  • +
  • overwrite(logical, optional) - When true, downloaded files will overwrite any file with the same filename, otherwise(default) file will be skipped
  • +

+

Output: +

    +
  • struct - Information on the download result
  • +

+

The API endpoint is /archivefile/download.

+

Returns(struct): API response. Each struct returned contains following fields:

+
    * url: char array   
+    * status: char array   
+    * file: char array   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/archivefile/download for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
filename = 'BPR-Folger-59_20191123T000000.000Z.txt'; 
+downloadInfo = onc.getFile(filename);
+

For more examples, see Onc Archive example live script

+

Source code:

+
function fileInfo = getFile(this, filename, varargin)
+    if ~exist('filename', 'var')
+        filename = '';
+    end
+    [overwrite, showMsg] = util.param(varargin, 'overwrite', false, 'showMsg', true);
+
+    url = this.serviceUrl('archivefiles');
+    filters = struct('token', this.token,'method', 'getFile', 'filename', filename);
+
+    if showMsg, fprintf('Downloading file "%s"...\n', filename); end
+
+    [response, info] = ...
+    util.do_request(url, filters, 'timeout', this.timeout, 'showInfo', this.showInfo, ...
+                'showProgress', true);
+
+    if not(info.status == 200)
+        fileInfo = response;
+        return;
+    end
+
+    outPath    = this.outPath;
+    saveStatus = util.save_as_file(response, outPath, filename, overwrite);
+
+    txtStatus  = 'error';
+    if info.status == 200
+        if saveStatus == 0
+            txtStatus = 'completed';
+            if showMsg, fprintf('   File was downloaded to "%s"\n', filename); end
+        end
+
+        fullUrl = this.getDownloadUrl(filename);
+        fileInfo = struct(             ...
+            'url'         , fullUrl,   ...
+            'status'      , txtStatus, ...
+            'size'        , info.size, ...
+            'downloadTime', round(info.duration, 3), ...
+            'file'        , filename);
+
+        return;
+    end
+
+    fileInfo = struct( ...
+        'url'         , "",        ...
+        'status'      , txtStatus, ...
+        'size'        , 0,         ...
+        'downloadTime', 0,         ...
+        'file'        , "");
+end
+
+

GetDirectFiles(filters, allPages, overwrite)

+

Downloads all archive files that match the filters Uses geListByDevice or getListByLocation to get a file list, then getFile's everything.

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional, default = false) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +
  • overwrite(logical, optional) - When true, downloaded files will overwrite any file with the same filename, otherwise(default) file will be skipped
  • +

+

Output: +

    +
  • struct - Information on the results of the operation, with 'downloadResults' for each file downloaded and general 'stats
  • +

+

Parameters in filter: Query string parameters in the API request. Supported parameters are:

+
    * locationCode: char array   
+    * deviceCode: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * dateArchivedFrom: char array   
+    * dateArchivedTo: char array   
+    * .....
+
+

Returns(struct): API response.

+
    * downloadResults: struct array. Each struct in the array contains following fields: 
+        * url: char array
+        * status: char array
+        * file: char array
+        * ......
+    * stats: struct
+        * totalSize: double       
+        * fileCount: double       
+        * downloadTime: double
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/archivefile/location and https://data.oceannetworks.ca/OpenAPI#get-/archivefile/device all available filters and https://data.oceannetworks.ca/OpenAPI#get-/archivefile/download for full structure of response.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'deviceCode', 'BPR-Folger-59', ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-26T00:00:00.000Z', ...
+    'dateArchivedFrom', '2019-11-24T00:00:00.000Z', ...
+    'dateArchivedTo', '2019-11-27T00:00:00.000Z', ...
+    'fileExtension', 'txt', ...
+    'rowLimit', 80000, ...
+    'page', 1 ...
+    ); 
+results = onc.getDirectFiles(params);
+
+

For more examples, see Onc Archive example live script

+

Source code:

+
function results = getDirectFiles(this, filters, varargin)
+    [overwrite, allPages] = util.param(varargin, 'overwrite', false, 'allPages', false);
+
+    % Sanitize filters
+    filters = util.sanitize_filters(filters);
+
+    % make sure we only get a simple list of files
+    if isfield(filters, 'returnOptions')
+        filters = rmfield(filters, 'returnOptions');
+    end
+
+    % Get a list of files
+    if isfield(filters, 'locationCode') && isfield(filters, 'deviceCategoryCode')
+        dataRows = this.getListByLocation(filters, allPages);
+    elseif isfield(filters, 'deviceCode')
+        dataRows = this.getListByDevice(filters, allPages);
+    else
+        msg = 'ERROR: getDirectFiles filters require either a combination of (locationCode)';
+        msg = [msg ' and (deviceCategoryCode), or a (deviceCode) present.'];
+        error('Archive:InvalidFilters', msg);
+    end
+
+    n = length(dataRows.files);
+    fprintf('Obtained a list of %d files to download.\n', n);
+
+    % Download the files obtained
+    tries = 1;
+    successes = 0;
+    size = 0;
+    time = 0;
+    downInfos = [];
+    for i = 1 : numel(dataRows.files)
+        firstCell = dataRows.files(i);
+        filename  = firstCell{1};
+
+        % only download if file doesn't exist (or overwrite is True)
+        outPath  = this.outPath;
+        filePath = sprintf('%s/%s', outPath, filename);
+        fileExists = isfile(filePath);
+
+        if not(fileExists) || (fileExists && overwrite)
+            fprintf('   (%d of %d) Downloading file: "%s"\n', tries, n, filename);
+            downInfo = this.getFile(filename, overwrite, 'showMsg', false);
+
+            % Skip this file if the request failed
+            if util.is_failed_response(downInfo)
+                fprintf('   Skipping "%s" due to an error.\n', filename);
+                tries = tries + 1;
+                errorInfo = struct( ...
+                    'url'         , this.getDownloadUrl(filename), ...
+                    'status'      , 'error', ...
+                    'size'        , 0,       ...
+                    'downloadTime', 0,       ...
+                    'file'        , "");
+                downInfos = [downInfos, errorInfo];
+                continue;
+            end
+
+            size  = size + downInfo.size;
+            time  = time + downInfo.downloadTime;
+            tries = tries + 1;
+
+            if strcmp(downInfo.status, 'completed')
+                successes = successes + 1;
+            end
+            downInfos = [downInfos, downInfo];
+        else
+            fprintf('   Skipping "%s": File already exists.\n', filename);
+            downInfo = struct( ...
+                'url'         , getDownloadUrl(this, filename), ...
+                'status'      , 'skipped', ...
+                'size'        , 0,         ...
+                'downloadTime', 0,         ...
+                'file'        , filename);
+            downInfos = [downInfos, downInfo];
+        end
+    end
+
+    fprintf('%d files (%s) downloaded\n', successes, util.format_size(size));
+    fprintf('Total Download Time: %s\n', util.format_duration(time));
+
+    results = struct( ...
+        'downloadResults', downInfos, ...
+        'stats', struct(              ...
+            'totalSize'   , size,     ...
+            'downloadTime', time,     ...
+            'fileCount'   , successes));
+end
+
+
\ No newline at end of file diff --git a/doc/OncDelivery.html b/doc/OncDelivery.html new file mode 100644 index 0000000..70521da --- /dev/null +++ b/doc/OncDelivery.html @@ -0,0 +1,465 @@ + + + + + OncDelivery + + +

ONC Delivery methods

Contents

+ + +

ONC Delivery Service

+

Functionality that wraps the API data product delivery services. To be inherited by the Onc class Data product download methods allow you to request and download more than 120 different types of ONC data products, with granular control over what data to obtain, from where, and in what time frame. They are comparable to the download functionality from ONC’s Data Search tool. Examples of usage include:

+
+
    +
  • Downloading PNG plots of sensor readings in a device
  • +
  • Downloading sensor readings as .mat files, text files, or in commercial manufacturer formats
  • +
  • Downloading compressed or raw audio files from hydrophones
  • +
+
+
+

Note

+

If the data product requested doesn’t exist in our archive, it will be generated by our servers before your download starts.

+
+

OrderDataProduct(filters, maxRetries, downloadResultsOnly, ...)

+

Request, run and download a data product as described by the filters

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • maxRetries(int, optional) - Total maximum number of request calls allowed, default 0 for no limit
  • +
  • downloadResultsOnly(logical, optional) - When true, files are not downloaded. By default(false) generated files are downloaded
  • +
  • metadata(logical, optional) - When true(default), a metadata file is downloaded. Otherwise it is skipped
  • +
  • overwrite(logical, optional) - When true downloaded files will overwrite any file with the same filename, otherwise(default) they will be skipped
  • +

+

Output: +

    +
  • array of structs - one named list for each file with information on the operation outcome
  • +

+

The API endpoint is /dataProductDelivery.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are:

+
    * dataProductCode: char array   
+    * extension: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * .....
+
+

Returns(struct): API response. Each struct returned contains following fields:

+
    * dpRequestId: double
+    * estimatedFileSize: char array
+    * ......
+
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'locationCode', 'SEVIP', ...
+    'deviceCategoryCode', 'CTD', ...
+    'dataProductCode', 'TSSP', ...
+    'extension', 'png', ...
+    'dateFrom', '2019-06-20T00:00:00.000Z', ...
+    'dateTo', '2019-06-21T00:00:00.000Z', ...
+    'dpo_qualityControl', '1', ...
+    'dpo_resample', 'none' ...
+    ); 
+result = onc.orderDataProduct(params);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function [r, status] = orderDataProduct(this, filters, varargin)
+    [maxRetries, downloadResultsOnly, metadata, overwrite] = util.param(varargin, ...
+    'maxRetries', 0, 'downloadResultsOnly', false, 'includeMetadataFile', true, 'overwrite', false);
+    fileList = [];
+    % Request the product
+    [rqData, ~] = this.requestDataProduct(filters);
+    
+    % Run the product request
+    [runData, status] = this.runDataProduct(rqData.dpRequestId);
+    if downloadResultsOnly
+        % Only run and return links
+        for i = 1 : numel(runData.runIds)
+            runId = runData.runIds(i);
+            fileList = [fileList, this.infoForProductFiles(runId, runData.fileCount, metadata)];
+        end
+    else
+        % Run and download files
+        for i = 1 : numel(runData.runIds)
+            runId = runData.runIds(i);
+            fileList = [fileList, this.downloadProductFiles(runId, metadata, maxRetries, overwrite)];
+        end
+    end
+
+    fprintf('\n');
+    this.printProductOrderStats(fileList, runData);
+    r = this.formatResult(fileList, runData);
+end
+
+

RequestDataProducts(filters, maxRetries, ...)

+

Request a data product generation described by the filters

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • maxRetries(int, optional) - Total maximum number of request calls allowed, default 0 for no limit.
  • +
  • downloadResultsOnly(logical, optional) - When true, files are not downloaded. By default(false) generated files are downloaded
  • +
  • metadata(logical, optional) - When true(default), a metadata file is downloaded. Otherwise it is skipped
  • +
  • overwrite(logical, optional) - When true downloaded files will overwrite any file with the same filename, otherwise(default) they will be skipped
  • +
+

Output: +

  • struct - Parsed http response
+

+

The API endpoint is /dataProductDelivery/request.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are:

+
    * dataProductCode: char array   
+    * extension: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * deviceCode: char array   
+    * .....
+
+

Returns(struct): API response. Each struct returned contains following fields:

+
    * dpRequestId: double   
+    * estimatedFileSize: char array   
+    * messages: cell array   
+    * ...... 
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/request for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'dataProductCode', 'TSSD', ...
+    'extension', 'csv', ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-24T00:00:00.000Z', ...
+    'deviceCode', 'BPR-Folger-59', ...
+    'dpo_minMaxAvg', 60, ...
+    'dpo_resample', 'minMaxAvg' ...
+    ); 
+result = onc.requestDataProduct(params);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function [r, status] = requestDataProduct(this, filters)
+    filters = util.sanitize_filters(filters);
+    filters.method = 'request';
+    filters.token  = this.token;
+
+    url = sprintf('%sapi/dataProductDelivery', this.baseUrl);
+    fprintf('Requesting data product...\n');
+    [r, info] = this.doRequest(url, filters);
+    status = info.status;
+    this.estimatePollPeriod(r);
+    this.printProductRequest(r);
+end
+
+

RunDataProduct(dpRequestId, waitComplete)

+

Run a data product generation request

+

Input: +

    +
  • dpRequestId(int) - Request id obtained by requestDataProduct()
  • +
  • waitComplete(int, optional) - wait until dp finish when set to true (default)
  • +
+

+

Output: +

    +
  • struct - information of the run process
  • +
+

+

The API endpoint is /dataProductDelivery/run.

+

Returns(struct): API response. Each struct returned contains following fields:

+
    * runIds: double   
+    * fileCount: double   
+    * runTime: double   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/run for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
+result = onc.runDataProduct(params);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function [r, status] = runDataProduct(this, dpRequestId, waitComplete)
+    if ~exist('waitComplete','var'), waitComplete = true; end
+    url = sprintf('%sapi/dataProductDelivery', this.baseUrl);
+    log = onc.DPLogger();
+
+    r = struct('runIds', [], 'fileCount', 0, 'runTime', 0, 'requestCount', 0);
+    filters = struct('method', 'run', 'token', this.token, 'dpRequestId', dpRequestId);
+
+    % run timed run request
+    tic
+    cancelUrl = url + "?method=cancel&token="+string(this.token)+"&dpRequestId=" + string(dpRequestId);
+    if waitComplete
+        fprintf('\nTo cancel this data product, visit url:\n   %s\n', cancelUrl);
+    else
+        fprintf('\nTo cancel this data product, please execute command ''onc.cancelDataProduct(%d)''\n', dpRequestId)
+    end
+    flag = 'queued';
+    while ~strcmp(flag,'complete') && ~strcmp(flag,'cancelled')
+        [response, info] = this.doRequest(url, filters);
+        status = info.status;
+        r.requestCount = r.requestCount + 1;
+
+        % repeat only if waitComplete
+        if waitComplete
+            log.printResponse(response);
+            if status == 202
+                pause(this.pollPeriod);
+            end
+        else
+            break;
+        end
+        flag = response.status;
+    end
+    duration = toc;
+    fprintf('\n')
+
+    % prepare response
+    r.fileCount = response(1).fileCount;
+    r.runTime   = round(duration, 3);
+
+    % gather a list of runIds
+    for i = 1 : numel(response)
+        run = response(i);
+        r.runIds = [r.runIds, run.dpRunId];
+    end
+end
+
+

CheckDataProduct(dpRequestId)

+

Check the status of a data product

+

Input: +

    +
  • dpRequestId(int) - Request id obtained by requestDataProduct()
  • +

+

Output: +

  • response(struct) - status of this data product

+

The API endpoint is /dataProductDelivery/status.

+

Returns(struct): API response. Each struct returned contains following fields:

+
    * description: char array   
+    * modifyDate: char array   
+    * status: char array   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/status for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
+response = onc.checkDataProduct(dpRequestId);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function response = checkDataProduct(this, dpRequestId)
+    url = sprintf('%sapi/dataProductDelivery', this.baseUrl);
+    filters = struct('method', 'status', 'token', this.token, 'dpRequestId', dpRequestId);
+    response = this.doRequest(url, filters);
+end
+

CancelDataProduct(dpRequestId)

+

Cancel a running data product

+

Input: +

    +
  • dpRequestId(int) - Request id obtained by requestDataProduct()
  • +

+

Output: +

    +
  • response(struct) - cancel process status and message
  • +
  • info(struct) - cancel process http code and status
  • +

+

The API endpoint is /dataProductDelivery/cancel.

+

Returns: API response. Each response(struct) returned contains following fields:

+
    * dpRunId: char array   
+    * status: char array
+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/cancel for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
+cancelResponse = onc.cancelDataProduct(dpRequestId);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function [response, info] = cancelDataProduct(this, dpRequestId)
+    url = sprintf('%sapi/dataProductDelivery', this.baseUrl);
+    filters = struct('method', 'cancel', 'token', this.token, 'dpRequestId', dpRequestId);
+    [response, info] = this.doRequest(url, filters);
+    if isfield(response, 'status') && strcmp(response.status, 'cancelled') && info.status == 200
+        fprintf("The data product with request id %d and run id %d has been successfully cancelled.\n", dpRequestId, response.dpRunId);
+    else
+        fprintf("Failed to cancel the data Product.\n");
+    end
+end
+
+

DownloadDataProduct(runId, maxRetries, downloadResultsOnly, ...)

+

Download a data product manually with a runId. Can optionally return just the download links

+

Input: +

    +
  • dpRunId(int) - Run id obtained by runDataProduct()
  • +
  • maxRetries(int, optional) - Maximum number of API requests allowed, 0(default) for no limit
  • +
  • downloadResultsOnly(logical, optional) When true, files are not downloaded. By default (false) generated files are downloaded
  • +
  • includeMetadataFile(logical, optional) When true(Default), a metadata file is downloaded. Otherwise it is skipped
  • +
  • overwrite(logical, optional) When true downloaded files will overwrite any file with the same filename, otherwise(default) they will be skipped
  • +
+

+

Output: +

    +
  • array of structs - (one struct for each downloaded file) with information on the operation outcome
  • +
+

The API endpoint is /dataProductDelivery/download.

+

Returns: API response. Each response(struct) returned contains following fields:

+
    * url: char array   
+    * status: char array   
+    * statusCode: integer   
+    * file: char array   
+    * downloaded: logical   
+    * ...... 
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/download for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
+downloadResult = onc.downloadDataProduct(runResult.runIds);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function fileData = downloadDataProduct(this, runId, varargin)
+    [maxRetries, downloadResultsOnly, metadata, overwrite] = util.param(varargin, ...
+        'maxRetries', 0, 'downloadResultsOnly', false, 'includeMetadataFile', true, 'overwrite', false);
+
+    if downloadResultsOnly
+        fileData = this.infoForProductFiles(runId, 0, metadata);
+    else
+        fileData = this.downloadProductFiles(runId, metadata, maxRetries, overwrite);
+    end
+end
+

RestartDataProduct(dpRequestId, waitComplete)

+

Restart a cancelled data product

+

Input: +

    +
  • dpRequestId(int) - Request id obtained by requestDataProduct()
  • +
  • waitComplete(logical, optional) - Wait until dp finish when set to true (default)
  • +

+

Output: +

    +
  • response(struct) - restart process status and message
  • +
  • info(struct) - restart process http code and status
  • +
+

The API endpoint is /dataProductDelivery/restart.

+

Returns: API response. Each response(struct) returned contains following fields:

+
    * dpRunId: char array   
+    * status: char array
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/restart for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
+restartResult = onc.restartDataProduct(runResult.runIds);
+
+

For more examples, see Onc Delivery example live script

+

Source code:

+
function [response, info] = restartDataProduct(this, dpRequestId, waitComplete)
+    if ~exist('waitComplete','var'), waitComplete = true; end
+    url = sprintf('%sapi/dataProductDelivery', this.baseUrl);
+    filters = struct('method', 'restart', 'token', this.token, 'dpRequestId', dpRequestId);
+    [response, info] = this.doRequest(url, filters);
+    if isfield(response, 'status') && (strcmp(response.status, 'data product running') || strcmp(response.status, 'queued')) && info.status == 200
+        fprintf("The data product with request id %d and run id %d has been successfully restarted.\n", dpRequestId, response.dpRunId);
+    else
+        fprintf("Failed to restart the data product.\n");
+    end
+    if waitComplete
+        [response, info] = this.runDataProduct(dpRequestId, true);
+    end
+end
+
+
+ \ No newline at end of file diff --git a/doc/OncDiscovery.html b/doc/OncDiscovery.html new file mode 100644 index 0000000..96d596e --- /dev/null +++ b/doc/OncDiscovery.html @@ -0,0 +1,458 @@ + + + + + OncDiscovery + + + + +

ONC Discovery methods

Contents

+ + +

ONC Discovery methods

+

Contains the functionality that wraps the API discovery services To be inherited by the Onc class Discovery methods can be used to search for available locations, deployments, device categories, devices, properties, and data products. They support numerous filters and might resemble an "advanced search” function for ONC data sources.

+

Use discovery methods to:

+
+
    +
  • Obtain the identification codes required to use other API services.
  • +
  • Obtain the identification codes required to use other API services.
  • +
  • Explore what's available in a certain location or device.
  • +
  • Obtain the deployment dates for a device.
  • +
  • List available data products for download in a particular device or location.
  • +
+
+ +
+

Note

+
    +
  • Locations can contain other locations. +
    • "Cambridge bay" may contain separate children locations for its underwater network and shore station.
  • +
  • Locations can contain device categories, which contain devices, which contain properties.
  • +
  • Searches can be performed without considering the hierarchy mentioned above. +
    • You can search for locations with data on a specific property or search for all properties in a specific location.
  • +
+
+ +

GetLocations(filters)

+

Obtain a filtered list of locations

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: array of structs - Array of Locations

+

The API endpoint is /locations.

+

See https://data.oceannetworks.ca/OpenAPI#get-/locations for usage and available query string parameters.

+

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return all locations available if None. Supported parameters are:

+
    * locationCode
+    * deviceCategoryCode
+    * propertyCode
+    * dataProductCode
+    * dateFrom
+    * dateTo
+    * locationName
+    * deviceCode
+    * includeChildren
+
+

Returns([struct]): API response. Each location returned in the array is a struct with following fields.

+
   * deployments: double
+    * locationName: char array
+    * depth: double
+    * bbox: dict
+        * bbox.maxDepth: double
+        * bbox.maxLat: double
+        * bbox.maxLon: double
+        * bbox.minDepth: double
+        * bbox.minLat: double
+        * bbox.minLon: double
+    * description: char array
+    * hasDeviceData: logical
+    * lon: double
+    * locationCode: char array
+    * hasPropertyData: logical
+    * lat: double
+    * dataSearchURL: char array
+
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = {...
+    'locationCode', 'FGPD', ...
+    'dateFrom', '2005-09-17T00:00:00.000Z', ...
+    'dateTo', '2020-09-17T13:00:00.000Z' ...
+    }; 
+onc.getLocations(params)
+
+

For more examples, see Onc Discovery Location example live script

+

Source code:

+
function r = getLocations(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'locations');
+end 
+ +

GetLocationHierarchy(filters)

+

Obtain a location tree

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: struct - Location tree

+

The API endpoint is /locations/tree.

+

Return a hierarchical representation of the ONC Search Tree Nodes. The Search Tree is used in Oceans 3.0 to organize instruments and variables by location so that users can easily drill down by place name or mobile platform name to find the instruments or properties they are interested in.

+

See https://data.oceannetworks.ca/OpenAPI#get-/locations/tree for usage and available query string parameters.

+

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return all locations available if None. Supported parameters are:

+
   * locationCode
+    * deviceCategoryCode
+    * propertyCode
+    * dataProductCode
+    * dateFrom
+    * dateTo
+    * locationName
+    * deviceCode
+    * includeChildren
+
+

Returns([struct]): API response. Each location returned in the array is a struct with following fields.

+
    * locationName: char array
+    * children: struct | None
+    * description: char array
+    * hasDeviceData: logical
+    * locationCode: char array
+    * hasPropertyData: logical
+
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = {'locationCode', 'BACCC'}; 
+onc.getLocationHierarchy(params)
+
+

For more examples, see Onc Discovery Location example live script

+

Source code:

+
function r = getLocationHierarchy(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'locations', 'method', 'getTree');
+end
+
+ +

GetDeployments(filters)

+

Obtain an array of device deployments.

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: array of structs - Deployments found

+

The API endpoint is /deployments.

+

Return all deployments defined in Oceans 3.0 which meet the filter criteria, where a deployment is the installation of a device at a location. The deployments service assists in knowing when and where specific types of data are available. +The primary purpose for the deployments service is to find the dates and locations of deployments and use the dateFrom and dateTo datetimes when requesting a data product using the dataProductDelivery web service.

+

See https://data.oceannetworks.ca/OpenAPI#get-/deployments for usage and available query string parameters.

+

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return a tree of all available locations available if None. Supported parameters are:

+
   * locationCode
+    * deviceCategoryCode
+    * deviceCode
+    * propertyCode
+    * dateFrom
+    * dateTo
+

Returns([struct]): API response. Each deployment returned in the array is a struct with the following structure.

+
    * begin: char array
+    * citation: struct
+    * depth: double
+    * deviceCategoryCode: char array
+    * deviceCode: char array
+    * end: char array | None
+    * hasDeviceData: logical
+    * heading: double | None
+    * lat: double
+    * locationCode: char array
+    * lon: double
+    * pitch: double | None
+    * roll: double | None
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = {...
+    'locationCode', 'BACAX', ...
+    'deviceCategoryCode', 'CTD', ...
+    'dateFrom', '2015-09-17', ...
+    'dateTo', '2015-09-17T13:00:00.000Z'...
+    }; 
+onc.getDeployments(params)
+

For more examples, see Onc Discovery Deployments example live script

+

Source code:

+
function r = getDeployments(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'deployments');
+end
+ +

GetDevices(filters)

+

Obtain a filtered list of devices

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: array of structs - Devices found

+

The API endpoint is /devices.

+

Return all the devices defined in Oceans 3.0 that meet a set of filter criteria. + Devices are instruments that have one or more sensors that observe a property or phenomenon with a goal of producing an + estimate of the value of a property. Devices are uniquely identified by a device code and can be deployed at multiple + locations during their lifespan. The primary purpose of the devices service is to find devices that have the data you are interested in + and use the deviceCode when requesting a data product using the dataProductDelivery web service.

+

See https://data.oceannetworks.ca/OpenAPI#get-/devices for usage + and available filters. +

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return all devices available if None. Supported parameters are:

+
    * locationCode
+    * deviceCategoryCode
+    * deviceCode
+    * propertyCode
+    * dateFrom
+    * dateTo
+

Returns([struct]): API response. Each device returned in the array is a struct with following fields.

+
    * cvTerm: struct
+    * cvTerm.device: array of structs
+        * cvTerm.device().uri: char array
+        * cvTerm.device().vocabulary: char array
+    * dataRating: array of structs
+        * dataRating().dateFrom: char array
+        * dataRating().dateTo: char array | None
+        * dataRating().samplePeriod: double
+        * dataRating().sampleSize: double
+    * deviceCategoryCode: char array
+    * deviceCode: char array
+    * deviceId: double
+    * deviceLink: char array
+    * deviceName: char array | None
+    * hasDeviceData: logical
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms + for more information.

+

Example:

+
params = {...
+    'deviceCode', 'BPR-Folger-59', ...
+    'dateFrom', '2005-09-17T00:00:00.000Z', ...
+    'dateTo', '2020-09-17T13:00:00.000Z' ...
+    };
+onc.getDevices(params)
+

For more examples, see Onc Discovery Devices example live script

+

Source code:

+
function r = getDevices(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'devices');
+end
+
+ +

GetDeviceCategories(filters)

+

Obtain a filtered list of device categories

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: array of structs - Device categories found

+

The API endpoint is /deviceCategories.

+

Return all device categories defined in Oceans 3.0 that meet a filter criteria. A Device Category represents an instrument type +classification such as CTD (Conductivity, Temperature & Depth Instrument) or BPR (Bottom Pressure Recorder). +Devices from a category can record data for one or more properties (variables). The primary purpose of this service is to find +device categories that have the data you want to access; the service provides the +deviceCategoryCode you can use when requesting a data product via the dataProductDelivery web service.

+

See https://data.oceannetworks.ca/OpenAPI#get-/deviceCategories + for usage and available filters.

+

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return all device categories available if None. Supported parameters are:

+
   * deviceCategoryCode
+    * deviceCategoryName
+    * description
+    * locationCode
+    * propertyCode
+

Returns([struct]): API response. Each device returned in the array is a struct with following fields.

+
   * cvTerm: struct
+        * cvTerm.deviceCategory: array of structs
+        * cvTerm.deviceCategory().uri: char array
+        * cvTerm.deviceCategory().vocabulary: char array
+   * description: char array
+   * deviceCategoryCode: char array
+   * deviceCategoryName: char array
+   * hasDeviceData: logical
+   * longDescription: char array
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms + for more information.

+

Example:

+
params = {...
+    'deviceCategoryCode', 'CTD', ...
+    'deviceCategoryName', 'Conductivity', ...
+    'description', 'Temperature' ...
+    };
+onc.getDeviceCategories(params)
+

For more examples, see Onc Discovery Device Categories example live script

+

Source code:

+
function r = getDeviceCategories(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'deviceCategories');
+end
+ +

GetProperties(filters)

+

Obtain a filtered list of properties

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: array of structs - Properties found

+

The API endpoint is /properties.

+

Return all properties defined in Oceans 3.0 that meet a filter criteria. Properties are observable phenomena (aka, variables) are the + common names given to sensor types (i.e., oxygen, pressure, temperature, etc). + The primary purpose of this service is to find the available properties of the data you want to access; + the service provides the propertyCode that you can use to request a data product via the dataProductDelivery web service.

+

See https://data.oceannetworks.ca/OpenAPI#get-/properties for usage + and available filters.

+

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return all properties available if None. Supported parameters are:

+
    * propertyCode
+    * propertyName
+    * description
+    * locationCode
+    * deviceCategoryCode
+    * deviceCode
+

Returns([struct]): API response. Each device returned in the array is a struct with following fields.

+
   * cvTerm: struct
+    * cvTerm.property: array of structs
+        * cvTerm.property().uri: char array
+        * cvTerm.property().vocabulary: char array
+    * cvTerm.uom: array of structs
+        * cvTerm.uom().uri: char array
+        * cvTerm.uom().vocabulary: char array
+   * description: char array
+   * hasDeviceData: logical
+   * hasPropertyData: logical
+   * propertyCode: char array
+   * propertyName: char array
+   * uom: char array
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms + for more information.

+

Example:

+
params = {...
+    'propertyCode', 'conductivity', ...
+    'locationCode', 'BACAX', ...
+    'deviceCategoryCode', 'CTD' ...
+    }; 
+onc.getProperties(params)
+
+

For more examples, see Onc Discovery Properties example live script

+

Source code:

+
function r = getProperties(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'properties');
+end
+ +

GetDataProducts(filters)

+

Obtain a list of available data products for the filters

+

Input: filters(cell array, optional) - Describes the data origin

+

Output: array of structs - Data products found

+

The API endpoint is /dataProducts.

+

Return all data products defined in Oceans 3.0 that meet a filter criteria. Data Products are downloadable representations of ONC + observational data, provided in formats that can be easily ingested by analytical or visualization software. The primary purpose of this + service is to identify which data products and formats (file extensions) are available for the locations, devices, device categories or + properties of interest. Use the dataProductCode and extension when requesting a data product via the dataProductDelivery web service.

+

See https://data.oceannetworks.ca/OpenAPI#get-/dataProducts for usage + and available filters.

+

Parameters: filters(cell array, optional) - Query string parameters in the API request. Return all data products available if None. Supported parameters are:

+
   * dataProductCode
+    * extension
+    * dataProductName
+    * propertyCode
+    * locationCode
+    * deviceCategoryCode
+    * deviceCode
+

Returns([struct]): API response. Each device returned in the array is a struct with following fields.

+
   * dataProductCode: char array
+    * dataProductName: char array
+    * dataProductOptions: array of structs
+        * dataProductOptions().allowableRange: array of structs | None
+            * dataProductOptions().allowableRange.lowerBound: char array
+            * dataProductOptions().allowableRange.onlyIntegers: logical
+            * dataProductOptions().allowableRange.unitOfMeasure: char array | None
+            * dataProductOptions().allowableRange.upperBound: char array
+        * dataProductOptions[].allowableValues: array of structs
+        * dataProductOptions[].defaultValues: char array
+        * dataProductOptions[].documentation: array of structs
+        * dataProductOptions[].option: char array
+        * dataProductOptions[].suboptions: array of structs | None
+    * extension: char array
+    * hasDeviceData: logical
+    * hasPropertyData: logical
+    * helpDocument: char array
+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms + for more information.

+

Example:

+
params = {'dataProductCode', 'SHV'}; 
+onc.getProperties(params)
+

For more examples, see Onc Discovery Data Products example live script

+

Source code:

+
function r = getDataProducts(this, varargin)
+    filters = this.getFilters(varargin);
+    r = this.discoveryRequest(filters, 'dataProducts');
+end
+
+ +
\ No newline at end of file diff --git a/doc/OncRealTime.html b/doc/OncRealTime.html new file mode 100644 index 0000000..878b607 --- /dev/null +++ b/doc/OncRealTime.html @@ -0,0 +1,305 @@ + + + + + OncRealTime + +
+

ONC Real-time data methods

+

Contents

+ + +

Near Real-Time data service

+

Contains the functionality that wraps API real-time services. To be inherited by the Onc class Near real-time (as fast as they get into our database) data access methods allow the extraction of sensor data as time-series, either as processed scalar data with Quality Assurance and Control flags (QAQC) or directly as raw data obtained from the device in its specific output format. In contrast to the Data product download methods, this data can be downloaded directly without waiting for any kind of generation process.

+

Common use cases include:

+
+
    +
  • Plotting time series from properties in a specific time frame or in “near real-time”
  • +
  • Quickly obtaining the latest reading from a particular sensor
  • +
  • Obtaining raw unprocessed data from our instruments (data might require processing to be readable)
  • +
+
+
+

Note

+
    +
  1. The methods getDirectByLocation() and getDirectRawByLocation() obtain data readings from a location no matter what device it came from (hence the need to specify a device category code instead of a single device code). You might want to obtain data by location instead of by device, as individual devices are often replaced/repositioned.
  2. +
  3. Each request to our API can return a maximum of 100,000 samples; larger data requests must be downloaded as a sequence of pages. Use the allPages parameter to automatically download all pages required for your requested time frame.
  4. +
+
+

GetDirectByLocation(filters, allPages)

+

Obtains scalar data from a location, from the source described by the filters

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +
+

+

Output:

  • array of structs - Scalar data obtained for all sensors found

+

The API endpoint is /scalardata/location.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are:

+
    * locationCode: char array
+    * deviceCategoryCode: char array
+    * propertyCode: char array
+    * sensorCategoryCodes: char array
+    * .....
+
+

Returns(struct): API response. Each struct returned contains following fields:

+
    * parameters: struct   
+    * message: char array   
+    * metadata: struct   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/scalardata/location for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'locationCode', 'NCBC', ...
+    'deviceCategoryCode', 'BPR', ...
+    'propertyCode', 'seawatertemperature,totalpressure', ...
+    'rowLimit', 80000, ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-23T00:01:00.000Z' ...
+    ); 
+result = onc.getDirectByLocation(params);
+
+

For more examples, see Onc Real Time Data example live script

+

Source code:

+
function r = getDirectByLocation(this, filters, varargin)
+    [allPages] = util.param(varargin, 'allPages', false);
+    r = this.getDirectAllPages(filters, 'scalardata', 'getByLocation', allPages);
+end
+
+

GetDirectByDevice(filters, allPages)

+

Obtains scalar data from a device, as described by the filters

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +
+

+

Output: +

    +
  • array of structs - Scalar data obtained for all sensors found
  • +
+

+

The API endpoint is /scalardata/device.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are: +

    * deviceCode: char array   
+    * sensorCategoryCodes: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * .....
+
+

Returns(struct): API response. Each struct returned contains following fields: +

    * parameters: struct   
+    * message: char array   
+    * metadata: struct   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/scalardata/device for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'deviceCode', 'BPR-Folger-59', ...
+    'rowLimit', 80000, ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-23T00:01:00.000Z' ...
+    ); 
+result = onc.getDirectByDevice(params);
+
+

For more examples, see Onc Real Time Data example live script

+

Source code:

+
function r = getDirectByDevice(this, filters, varargin)
+    [allPages] = util.param(varargin, 'allPages', false);
+    r = this.getDirectAllPages(filters, 'scalardata', 'getByDevice', allPages);
+end
+
+

GetDirectRawByLocation(filters, allPages)

+

Obtains raw data from a location, from the source described by the filters

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +

+

Output: +

    +
  • array of structs - Raw data obtained for all sensors found
  • +

+

The API endpoint is /rawdata/location.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are: +

    * locationCode: char array   
+    * deviceCategoryCode: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * .....
+
+

Returns(struct): API response. Each struct returned contains following fields: +

    * citation: struct   
+    * message: char array   
+    * next(struct):       
+        * parameters: struct       
+        * url: char array   
+    * ......
+    
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/rawdata/location for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'locationCode', 'NCBC', ...
+    'deviceCategoryCode', 'BPR', ...
+    'rowLimit', 80000, ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-23T00:01:00.000Z', ...
+    'sizeLimit', 20, ...
+    'convertHexToDecimal', false ...
+    ); 
+result = onc.getDirectRawByLocation(params);
+
+

For more examples, see Onc Real Time Data example live script

+

Source code:

+
function r = getDirectRawByLocation(this, filters, varargin)
+    [allPages] = util.param(varargin, 'allPages', false);
+    r = this.getDirectAllPages(filters, 'rawdata', 'getByLocation', allPages);
+end
+
+

GetDirectRawByDevice(filters, allPages)

+

Obtains raw data from a device, as described by the filters

+

Input: +

    +
  • filters(struct) - Describes the data origin
  • +
  • allPages(logical, optional) - When true, if the data requested is too large to fit a single API resquest, keep downloading data pages until we gather all data
  • +
+

+

Output: +

    +
  • array of structs - Raw data obtained for all sensors found
  • +
+

+

The API endpoint is /rawdata/device.

+

Parameters in filter: Query string parameters in the API request. Supported parameters are: +

    * deviceCode: char array   
+    * dateFrom: char array   
+    * dateTo: char array   
+    * .....
+
+

Returns(struct): API response. Each struct returned contains following fields: +

    * citation: struct   
+    * message: char array   
+    * next(struct):       
+        * parameters: struct       
+        * url: char array   
+    * ......
+
+

See https://data.oceannetworks.ca/OpenAPI#get-/rawdata/device for full structure of response and all available filters.

+

Check https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms for more information.

+

Example:

+
params = struct(...
+    'deviceCode', 'BPR-Folger-59', ...
+    'rowLimit', 80000, ...
+    'dateFrom', '2019-11-23T00:00:00.000Z', ...
+    'dateTo', '2019-11-23T00:01:00.000Z', ...
+    'sizeLimit', 20, ...
+    'convertHexToDecimal', false ...
+    ); 
+result = onc.getDirectRawByDevice(params);
+
+

For more examples, see Onc Real Time Data example live script

+

Source code:

+
function r = getDirectRawByDevice(this, filters, varargin)
+    [allPages] = util.param(varargin, 'allPages', false);
+    r = this.getDirectAllPages(filters, 'rawdata', 'getByDevice', allPages);
+end
+
+ \ No newline at end of file diff --git a/doc/helptoc.xml b/doc/helptoc.xml new file mode 100644 index 0000000..383b159 --- /dev/null +++ b/doc/helptoc.xml @@ -0,0 +1,41 @@ + + + + + + MyToolbox now + + + + + + + + + + + + + + + + + Discovery Service + + + Delivery Service + + + \ No newline at end of file diff --git a/info.xml b/info.xml new file mode 100644 index 0000000..6c66113 --- /dev/null +++ b/info.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + 2022b + + Ocean Networks Canada API Client + + + toolbox + + + + + doc + + + + \ No newline at end of file From f0465f7164b2cf6b666d0f74201de3a23dff6488 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 10 Jun 2024 16:37:03 -0700 Subject: [PATCH 25/35] issue-21: Add version check function and update initializer to run checkVersion at the beginning --- onc/+util/checkVersion.m | 33 ++++++++++++++++++++++++++++++++ onc/Contents.m | 21 ++++++++++++++++++++ onc/Onc.m | 41 +++++++++++++++++++++++++++------------- 3 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 onc/+util/checkVersion.m create mode 100644 onc/Contents.m diff --git a/onc/+util/checkVersion.m b/onc/+util/checkVersion.m new file mode 100644 index 0000000..07a156e --- /dev/null +++ b/onc/+util/checkVersion.m @@ -0,0 +1,33 @@ +function isLatestVersion = checkVersion() + url = 'https://github.com/OceanNetworksCanada/api-matlab-client/releases/latest'; + isLatestVersion = 0; + try + % get latest version + releaseInfo = webread(url); + versionPattern = 'Release (\d+\.\d+\.\d+)'; + version = regexp(releaseInfo, versionPattern, 'tokens', 'once'); + latestVersion = version{1}; + % get local version + librariesVersion = ver; + localVersion ='0.0.0'; + for i = librariesVersion + if strcmp(i.Name,'Ocean Networks Canada API Client Library') + localVersion = i.Version; + break; + end + end + + % compare + if ~strcmp(localVersion, latestVersion) + [oncFolderPath, ~, ~] = fileparts(which('Onc')); + localFilePath = [oncFolderPath '\..\doc\UpdateInstruction.html']; + formattedPath = ['file:///', strrep(localFilePath, '\', '/')]; + link = sprintf('<a href="%s">How to update this library</a>', formattedPath); + warning(['You are using an outdated version(%s) of the library. Update to the latest version(%s) to avoid potential errors. ' ... + 'For instructions on updating to the latest version, please visit: %s'], localVersion, latestVersion, link); + else + isLatestVersion = 1; + end + catch ME + % do nothing + end diff --git a/onc/Contents.m b/onc/Contents.m new file mode 100644 index 0000000..e22a6ae --- /dev/null +++ b/onc/Contents.m @@ -0,0 +1,21 @@ +% Ocean Networks Canada API Client Library +% Version 2.2.0 10-Jun-2024 +% +% Functions +% +onc/OncDiscovery - Contains the functionality that wraps the API discovery services +% +onc/OncDelivery - Contains the functionality that wraps the API data product delivery services. To be inherited by the Onc class +% +onc/OncRealTime - Contains the functionality that wraps API real-time services. +% +onc/OncArchive - Contains the functionality that wraps API archivefile services +% +% Live Scripts +% examples/OncDiscoveryLocations.mat - Example Usage of OncDiscovery Location Service +% examples/OncDiscoveryProperties.mat - Example Usage of OncDiscovery Properties Service +% examples/OncDiscoveryDataProducts.mat - Example Usage of OncDiscovery DataProducts Service +% examples/OncDiscoveryDeployments.mat - Example Usage of OncDiscovery Deployments Service +% examples/OncDiscoveryDeviceCategories.mat - Example Usage of OncDiscovery Device Categories Service +% examples/OncDiscoveryDevices.mat - Example Usage of OncDiscovery Devices Service +% examples/OncRealTime.mat - Example Usage of OncRealTime Service +% examples/OncDeliveryDataProducts.mat - Example Usage of OncDelivery Service +% examples/OncArchive.mat - Example Usage of OncArchive Service +% +% Copyright 2024, ONC Data Team \ No newline at end of file diff --git a/onc/Onc.m b/onc/Onc.m index 939014a..02cf49d 100644 --- a/onc/Onc.m +++ b/onc/Onc.m @@ -1,7 +1,7 @@ classdef Onc < onc.OncDiscovery & onc.OncDelivery & onc.OncRealTime & onc.OncArchive - %% ONC Facilitates access to Ocean Networks Canada's data through the Oceans 2.0 API. - % For detailed information and usage examples, visit our official documentation - % at https://wiki.oceannetworks.ca/display/CLmatlab + %% ONC Facilitates access to Ocean Networks Canada's data through the Oceans 3.0 API. + % For detailed information and usage examples, run doc command or visit MATLAB's help browser + % then find Ocean Networks Canada API Client under supplemental software % % ONC Properties: % token - User token, can be obtained at: https://data.oceannetworks.ca/Profile @@ -63,20 +63,33 @@ end methods (Access = public) + %% The ONC class + % The ONC class provides a wrapper for Oceans 3.0 API requests. All the client library’s functionality is provided as methods of this class. + % Create an ONC object to access this library’s functionalities. + % Parameters: + % * token ([char]) - The ONC API token, which could be retrieved at https://data.oceannetworks.ca/Profile once logged in. + % * production (logical, optional, default = True) - + % Whether the ONC Production server URL is used for service requests. + % True: Use the production server. + % False: Use the internal ONC test server (reserved for ONC staff IP addresses). + % * showInfo (logical, optional, default = false) - + % Whether verbose script messages are displayed, such as request url and processing time information. + % True: Print all information and debug messages (intended for debugging). + % False: Only print information messages. + % * outPath ([char], optional, default = 'output') - Output path for downloaded files + % The directory will be created if it does not exist during the download. + % * timeout (int, optional, default = 60) - Number of seconds before a request to the API is canceled + % + % Returns: The Onc object created. + % + % Examples: + % onc = ONC("YOUR_TOKEN_HERE", 'showInfo', true, 'outPath', 'myOutPath'); + %% function this = Onc(token, varargin) %% Class initializer % All toolkit functionality must be invoked from an Onc object % % Onc(token, production=true, showInfo=false, outPath='output', timeout=60) - % - % * token: ([char]) User token - % - production: (logical) Send requests to the production server (otherwise use internal QA) - % - showInfo: (logical) Whether verbose debug messages are displayed - % - outPath: ([char]) Output path for downloaded files - % - timeout: (int) Number of seconds before a request to the API is canceled - % - % Returns: The Onc object created. - % parse inputs (can be named or positional) p = inputParser; addRequired(p, 'token', @ischar); @@ -128,7 +141,9 @@ this.tree = temp.tree; %These codes can then be used for input to onc.getDevices by %providing the locationCodes - + + % check if it's running the latest version. If not, throw a warning + util.checkVersion; end From dc147b135c61a299fa094f6e6b8a6f0551f8bef8 Mon Sep 17 00:00:00 2001 From: Isla Li <islali0904@gmail.com> Date: Thu, 13 Jun 2024 09:10:07 -0700 Subject: [PATCH 26/35] issue-20: add documentation files --- doc/AddOn.png | Bin 0 -> 24159 bytes doc/GettingStarted.html | 1259 ++++++++++++++++++++++++++++++++++++ doc/Index.html | 158 +++++ doc/Onc.html | 5 +- doc/OncArchive.html | 2 +- doc/OncDelivery.html | 14 +- doc/UpdateInstruction.html | 151 +++++ doc/UserDirectory.png | Bin 0 -> 296590 bytes doc/helptoc.xml | 18 +- doc/update.png | Bin 0 -> 89406 bytes 10 files changed, 1595 insertions(+), 12 deletions(-) create mode 100644 doc/AddOn.png create mode 100644 doc/GettingStarted.html create mode 100644 doc/Index.html create mode 100644 doc/UpdateInstruction.html create mode 100644 doc/UserDirectory.png create mode 100644 doc/update.png diff --git a/doc/AddOn.png b/doc/AddOn.png new file mode 100644 index 0000000000000000000000000000000000000000..c6ac1c22fff6b4eb7a61fd90f9a93c468432437f GIT binary patch literal 24159 zcmce-1yCGM^ae;0G`O?4yF0;QaSyV%ySqCCmf-FX9D)URcMrimxVyswM}Gg)s;jHI zs;k?osjcarnd<&}-kW~!eP4vKq7?FH{LfHOP{=aUz^_nH9|2HMAL!s=-&=&htZnaq zA6&jli9uCO5+1&vKwF3^h(bZt#3DkBVBXIW9Hq5fprBCt{v98N97;{0p!9BJfTC)i z`lo9MhFEhia2MyWVj^hDXv%R6q`{)LOn6w(@#1{JFz5{MYL@8rq9T8~M5eW4xOHKZ z3t%KrV9>35^M1ghB|%w>_5waagE8zeoJpQ@@6Fvk+&S8o6x?OFAN_A?IIhjt$L-DC z{h!w}0hq0doFQN^czEn%J&64MS8W_83Iqa$dPx5@`v!}`qNAffLWdx|_gx{t0^a*} zFp=2*-9m$BiiVCJuf#e``resq`2YKjtS?t%EarA;{{~~DnfQMh_XHI-_^N48@P4%* z8a-KlcQhFt4UIHWm?Lvycxp;YUq6R?fH;<bUJhaxU>c_qbTO9DUL>1LKcDC#DjLK+ zC!8)%4PcE}$jTzL`-%L&UFd><?gh+>lL(B@%sjsT5N7DbvZdb6Lw-g4j?51Fv;es^ z>nOpr?$@%fRCZC|_Mmt8ynxVv-8|U7_|g$H1#0Y`nz~fSyDc}ns9_I0Q{@)-m)0kV zr+FO*qxUhgM;P@aNU5o0wRnEwm_Hlr+2OS1i;D`VSTEZ}dz37Sz@+)P(X4h>R8+Ki zx8krcINF6wz&-4`HxA&dIytu7=oGv=TZ=4^iZvcfVPgMnxz^e+PIC|TN1UwczbF>8 zn7L@GPP}-WX0Y_PP@k<<kr=xqD!A9kiOEE5B<_y$k1cS2d1~Izfo=AsAcAS(vs455 z1?0PLFECg&S6X93YnacdXze&WQ&cmTiOBw8@Y>OlYalz<xtpi88}^y6)CuqI77@5# zb&-~ruScW=(sVsMc&_^0uYqG?Qb4ju_?*&XMfqx#+SpoJTFYtoMTNVDXOom_<@n&# zFI?jOL4Yy$TuFOHVrqA*;HRc%=0#R-hxMb0Hydm2PJTb^66TU^Z}Tc{b@euF(u{@5 zn4yfdh&CHoE7cB%^?>aQu`Zgpg!tI3_K$_H=O&!P{9!-3WqEV;;1C{|f~{90C=g`u z*7l7!%MEmN5=K7<w6*r1lA4^a3V9OD{PNnOSWenv%e*(%-<Y#(r~Dj(|5*GoV=ELp zH5fhkea6~GS+veb6XTW<-|P3fH$&sK2E)iC-&V8-oB1D4K3zj@3YIRY$H!3{(I9qP z4Mpg!xfiRHO-zHzp)0L`_+9U@xpEMj-;-<m{kji(AX*HGa12Z5gV-GvS_6Rm0F4Io zvfS_$^62?;yMQcA;3n)zz+dkpiiO452R1&z-0N^b=k}ATxf`e*1c^#|D++NFLa+^p z+oGHV&!wabmf5?9M<=9;6Fd$eTosFcpZ!Qm!#|v!N#4@0zZIQEl5T5Dq6ocQ3eYo% zo=0ZuY@aR9sT9@v$+@}P6Hgj+M9j6t=8+1MObM>Sd#vug7#>Ogp(2!3l#pKGW+i$= z^MKyVKTTxm(~bMK?ISGlXT%fQ{gKAr+;po=&nfNZq+mH=u>Dd`XL)>o!D#hB@8E=H z<MtKD6k1;A%A>vJ0J*TZ#47PKW<cni%-U}zE3Wx$mKAIg=kP;*e2Z|~-oa=Bvt_Ig zCrc$0A_HIJvdcQX*}BoHQ=B^vC;88TiPQ>?Tm1-p%)!xl;^D@(M{^H5iAt<Sz0kfF zJ#fS0<Nb#-CA;lasLO^(I#?9<MN|}lyYac3?N@xwa<KFcL;1(Ec((ei!_}XV4Dg%o z0*2W#FLG1G5Ml7NMrE3(vzv?{s+CSp*3^UkSBZ^kOE|f{L@rH4JtVo7k!4-yfz)me zO^B?FL#n&7AK<GD2xefzjHOGSciD}#9OPQ!gPKEVE{>NHhub{iyH2kI;48GnW#*=f zuU$qbGa{qp5QZl(Q?FsI<p2yU8x6&hA-@c-KLQNFCT{k*7wiE!*EAmr!tZ;>7ij+G zGLSdOe4{#Ff^j8|>d6k$^GRqZGmDM-Ns(GGQm>Hq06vY>JpqQeZtt`}vg8@l?s(eo z_c$5-pP3*QgBzEd6#<53JFdP07Sux7Z%P#g7c9Uo9)e8ViJnxsz0KpIbHnFwmBriX zw#B+5!INiCGJowhJmG*w=x`ng+)zR4sB?$i&B1iD>mi1inApXPlJMqstngsR{dy#q z&HONBnD86Kg_4r;Z&lk_Z;Q+R4*Qwq!wH(J+$zizYKS4HeJOH6UjL2_D?``TOr6U+ z#Occy(NTmuJ3Ct^)n;8YRi$2!kdivho01$$XOM#3PeGNsl#=%S@e@K_r700f4Q}mq zRk-uc8%l0S8s*qU7}73BHlzn6Ei*Q7J>@F(gAcpmsA1N506|?wwp+E!NzT-wkZkit ztKLQ%G{N0{uI&sGDZ(FF3@}FgnEVz6&XyU(BO=H*k^-1%1`KEwbh^1rR~rbY_bz0o zdIeh=*T|o9cvN$%Q;q83uEV+9FOy5E6s^+u68UT5+UqHHRe-blo=eT{4mogrhyoO- z&wHx+?GI)}33z_6h*P%R9$yXmxoc$pq<3E1)lG#vAN=W2(jw20Uz`sLH`lB?uw%?7 z3JQ2Tc4N%p`VeUzGxR(&w7J&w7F^n--vhBSVf8q&9M6H!XjL^e*e+q5w_nE)zP>)6 zn{7lb)maqyzdXHv8`$jLUSDdhegAd`HE+l8??7^XoxHj1hw0oS482fRkt*8Q^F?Eu z^i~XoPrvRcdOba65qYGTj3rns4MmT!=QMF*?d<$`4vGGC6Dhvv#@nJC=tRl}lY9Op z>=}QZY@cbYYIVF<YJ+$HlG<AEJrN~oD?w{F;Pf41LpN0fcIGwdWG(`iFpoqtaINf7 zK{d(`yK-~SgFNnGF|(ajcb1sfUkFwU{wmJb$+wZuIXj!H>8jEb$i3@+aHfXj33(X4 z3)=S^9gV*69{Tqk4uXo`IjS`f^GH10#x<{m1T6w8?sDpu4*5nCGseF&8&2gp{PJH@ zf%uJc+9iCd;mG4i!V`Z4ET{mSA=s(lT?_t^pS5XadhyM^m5?h8;`C;%Y+?@VHRIDv zZTVtJPj_ja{<Frp%F`91NPF>|fpb`<U(5>)KNyM?4oE#hy=vFwD>GIKZO@LTko*;4 zdBW;QqO1YdH%wy&oJcYbv2|ymPwnu#euK+Q`-81xeA9)08M!Qfi%?G=x454!&ttYq zzq_G2x%|8C1Yc3tlX|p!SG3cUr)Ltd5t{;<XqY88TWfZG{LYjH1-B+YaUqbBE2evI z0(1Jq^XF3<l4^%ggi(=&VDs7$vz{N45+_PkV>440uB#&kY1@(}pnWQKCCW>=nZqyl zl>=AQGbejYOph&mrK)xKl7cU!^e|~?4Mr>p)vNt1vf4GbP|it)1t3c~Dv=7t_q9xM z5DpHY-EffnAbHZ{b1@qzyw#NbTwro9iYH)9h(i2@I#Ut&E4~0)gAU|Cs*J$7j`xtp zSYC*dB|Uh)+$bVz-FR}5Zu9fI^+Znh*+Gk}V`51K53bam-9W>vyjuB+Jc5|d*1iG9 z#nTqk<fmw3|An7PFCJWIHCBnM0Uq+G;)Pe04Et`pv7X%343ksp!6P@|wVKx5TOq|M z727LUgYFy_>%RuoFRBDg@^<uxw8CoWc;L~fU7Ooz`yM<tO+*WRS1}&S&5Aog+I%5& zwy<vsO*y|#!H*^$HU=?1HT+i4j1maXdmYGBz1<XBs2RQ*bbKn3X|>~r{Bf3A@%md@ zc=GBa?6%WQrOO0=m{ivE<8f_ux+-u$aBBu0FjPN%nPhxrj)sU5ceQX+b`am5H{LFW zgkM!)3G~|BC9=P`v06+L>b5vbP_r=>b2+T*!s3-{RQ5hzH)aI(+6FvNk7XKW=nXX* zYK_sfwB<HuO|4yJ5qd1MjFU}$@qOWEC^s^J9_q9MVSd&A>|8rXjX}lL_KboQa71?U z#S!1fUnoRBb~Su(lvD0BEUl^HiwB<qZ0!UARuvKEhrx%p%$TG|kaC%`nOFGq7^rGH zx@$@t5|4THfW9v{ZE?83u<*OpNpNRxcZ6Mzyj0dqt?H{fGV9e<d}2!Q_>EfDmqrqV zaQE%ih?m6{FJ$(lDV|fv2bH1dluGUVvo+)z+Cdqb$SwZ`+0j>mJR+&lR|dtC`Iq%g zfvu(XDqdj_AJv|VQ%rt73{cT=9ar49)Fzc?>*hP#RisQI8-pT))c2>nHu9gNgLG`Y zvuSw!{fxa}Lnd)4U`&V<<%ogW7Orsu&Nw`|2s)^4@vZiVdJHqZRQg+$D>@fbPt9+b z9DTL^Rt8$XZbJmpEExQl4`I@s7l$Re`5KklSN?eUdxbhp_O+7YoQYt{Fn;$F+I@5) zVF`sO%|Sk$AtjYQ(h&WU)itGd!Cd~&sYUMID-{stsH7neE1py^6ouS^{GZ)T9M2n` z9#)3jmd?jQMxIpLmqW_e)wT{d65OE>i5>nojk_+{gZUzg&X`wtKX1W27=q-Q-Aut+ z?t<<L#*%h(hMoZ!Dk#AE3s3EMLaAOItiAdE2owbi9nOc1u856>^Y3gNLQ;;$&(qCb zs!`crK6O01O5UMf$LHcPeM*p2$oxB0Afrw9Md+o9iC;InU|8^OL4|L*iJ)e*`dOlt zg__II(PaNC`4UjhEd%04Rf3a$cdZ%OpxuQks?jhai=;PP3fZy_*3@%zGD@MwQ^_`8 zh$)5^IPP!O2s2w5xS6Zbu4lT!NbUP7Ls333C)zZxhkh6W;}>XzWr_!bNB$@#EBn1- z0*wnhpRZ6Zl^KuK5Q^CU!ARidxA?(&M_YS7aA&Sk2Q<l$LdWKDkLfT~QsVcBt6dDP z#Yff-l<3PK8|lam6(aix=NCv8wp*TX^C2uvKP4pUVFp+EEoLP-vEErM6{K30%`Z_q zYZyhq@i9m=$Wzc4E62N*<74nox^pE$O!8snSTeSNtKIU_k|e58Mg%8_8AGm~`w@&O zq#3D?Tu3By<J(6skRiRas*o>Ly2B5vNN>E`)Ys<v0Brjl;Zol+jjvxfXMho%Hh#rq z_;AP8a{Z5T1dIp;E?6y7W^rW8xxqx_JPjk1i&fd9%HchDLA!XEIANXf7SsJdsKw*v zEESB=S4_dT_-51cwG@VM#SCNL4M6z?3hZADgWLTb>l-u%YB<Uay-oAyUl$g>7;H%Y zD5!NA<K`(slG8U>lC0z&8g92b5~a8zpVoR@D@iV60?oFLaSXMQ9({uGgW8k{Buij9 zBcyu@0-GmzZ1~}pm6h>2{tY}~_>(Vz2+##*L?zNFjqW8mbUsS{1Dx)E0H^7K6cp!0 z*aMs}95qskWK=1qvD8Y_cX1X2zMxcB5k`opGSB<hpn_)DvtjY94wqz=Jqgt(S|02* z9dw`k+cadCoHj?1)hfR(;cJ4E%8UH?-y#JKs{69t&XkLBX=z?{b(>SdWYvFeMkscv z+OQ>wh;ycbg=kx3M?t~ZD&{hUMHZWuTVBwFS`jokUI6t^bw;CIKM99rTVNK9QVwCq z9~aQosNj_Dtx#RI_Su!caw{?n=sR`U_(_mF47;7-xOwEDudJ12E>~Fc%|}hD>~yj_ z4JkQckDe*srHaMhC+|=*BjPZ2S7_Dk{1TFOL?RV}T!=>z@_n7hz}w|7jum=>-`w1+ z)pfvJdEQMm7+sF6vzU5MEr{Lqpn-BYZRX`+Nt6U{vDQ7ek?jzi!<*~}-PpKb&I7m% z9?MJyf78Ggm^U10wvrLA-0Mr7>l6KM_Y!Y|q9EH8@CWmU{<@pE*e9+;^W*}AzY!JL zD!YZs`x49@;W}*0Uk^?+O9HC~p3+&yNXbQB1E<-sw#MeauH0X?PVhQkF~;P+Vslw9 z^k$V6BttD05^`8y#OK6EX9BdEJG9l?8w~}8d~DLRrP*%Yx=@q0C!&7gPd{XSP2sz* zs3qIFyyF|SDNbNdBBelvd9)fHQT~_}<qK@TL?2h`jC>$L{d)}%Z%Cjou62#MYRYs< z_KqWawx^wT2+iGqnI=gx-N*76z~cIl!Xk}MdSGxXlhrMu5TughpMf_yJly?od6W(G z+gvaRNNz$6xS5vPb&qhPrlJ~=(;4t%@87N3Nl$<U94;Md)>&XTlDy!v2=ZaX3SO{Y zC1L7TX~~S*Tn#X!)lnjp0X%;ARL2Z|^;a0Oj~4ICP`|iG*K<^gh9YGkQXWOG#tm2w zH<^Buc&X}`c3#9&tI~(;fAORk_H-Jw_WfcLwYmU=Q@(5{hA><w2^uWjCxdo#_a$G| z=M7zt|9t3Z6AIRDC?D$vy55WrkEh5$<0mty_a;$Ik4E?xG8Rw@89d=e<#4J;uqe`* zc#VdEMJQAeSpV!|^S7jrJ|!m=6l$FVw<C|0Mt@k`2k5IJmIjV4^L-Z$%VbPlW>P|8 zp0~>waiLn`lL#Mq4@<N|pf9ZfjZu*xCz=VB0!cD{{uS1ZOD=l)&+pOXpLwy@ABCcW zBsfSw%>#~ug*=vzpRP|nMzsg4J!X`*`@i)eGa6)vkCq03Hw7<%;M#NRpl{R15sR8x z{3&2!o9`Q;ThXKi2K~nU?bjI^k$KbvI&qg<<!>S)%IX!~`_)(Gx_q*Z@u?uv@Jdlh z^Ase`y?`q&ZpqGyWEEe;;v311uxRDDT&ib(aApoRxb4c?W0Na#Q@~8qOE43{u*bAg z$)t6eH0P4k1p}z!_kW7B6eg%Q<lwexaw)1+xXDISAR&+FL`tDNV<G$aIle!&E{!@& z0{NTt;o)Jk*LAV{79Sb;TC<Zl^(C~L!Oh5z+EYnyeEM|y5s_Z4Kr(%swOhpCfF|7P zeLE=~)$e0apVF;HSuSl&*X8Htzj~ilpofOm(bZ~*ZLo+_Q-OcoOrw1WD;<#@8&0?% zL<9Mon$w+&783$&P0jbWd`Gdhig`k(7K8VPUI|zrW-wu4)%_O>8k@10plu~|lI`6$ zoe(zF`7IU)|L+Uy`k=f|NJ0Cw=d=x^A&^LTSm3F+iXY>5*_bho;Zo15WK6pu?$cks zE1!M+NE?*{<DFl~ajG{$`Vkj?GZ&(q`QIR{w#P*^KRRsx$s_p;gO`dCL&ogQac1X> zYdzblpd)vPVCBw(LMUj5%(!D#kYdCX0kt!+5N0&WFf~F-!9WA5>`)GljFP8n{{1nU zkt+L3fJ%zYPAr~joDL%w;0daSEy7m?+13h$ZPX)ckhEY6UH!Vj2G;mtrbD?d3?VXq zf&BFbq0n4k^rlIe>~5&w;O;@t^3RRCZhJ}*G!>uaat)@~8(|ECg`&}02DUUPIOZm@ z%h13Tsn%XsDtw3-$fX+N{E_A5<?voFAo6zQ&NAp*<(?RcEtu0~NfKf+0OGwKQ!li6 zVd*dDT2%gseEB2}q0^#{7k*FE+SkmQ^2((^^=id!GKv_*sa(E)TvmgRhex_%{`%Pb z{Z>NU-7*%TSz`uwW}^ag8lZ#f#X2U{WzdpSxh^Ik#~HEO|3bu{zm}*(ZuF*43Ay;R z>}DAmc5Bm{<xe!+tU`TPf^$DF-l5%Ow3fOtg8z95E1z<DUrgYSAOk;WUJY8Uj5<^9 z>T}Y4Mtsq2*L$kQkOHnP;7gD>vh^5y1Oz<<$vLuI8_6$+=6zpB9!rli%_0ho#|N{J z1frs=?(+KarPrHN)UZMJ-AHIYMcwG$!hX%C7Kg?g{;G;i1?^SZCvJKF`vrb{tR5C` z?}kA3;wyLX{0K$guczx%uyA~6{f)d=?)OYtjJ_iqoOQn!zHy%hmZN$2gqi-`pX|St zzlJ5mQ0WckQ4E=B0bjq1!nO=(DTJ9oZE7ZN(s!dpZ~?Gmn<>AN7@F>H{DQ@Pf)Z~x z-=`Cmv~T3<j-%sHhs81nXfA$?f<z(R?x~n{uX(Hml?8ai&g}VyQXp8wdvmB3b6(Pi z#K;qV@xp;iCf(U;AdntY4nd8#Umcf(lrb#c?7C}((MAp%unm(od1{N3CGbDy>;BaI z39B(gqvNq9IY^cIVQ}f%s`<)BNRcFZ=#c_05{Y#y3G<pO@p6q$PCWGv^>1ZO2&+pE zJ<#D<5rL82)RF8HGQhEviy%cCMJ3VcQWB+e$px=wqu<#4!B7h}UYG&X15&6{K)C>N zSZPFl-$Tz0wwHja^$(WnO1LH8-QN93bGjF1WE0~+V+h;Bi|WL0f#wvwK&RIQ*OTX0 z&`o<6i~gD5=b%S(-!|V5U+)}-60?`Lt5)cjVDM-r4SHf!LDN4slm&#y2}QYN@6B~% z{AF5#%g!r$%Up1$`Ra)>csk&2&wo<bxB}sR+wS`1Dt1OCTKEra_DTINeq2j?T~=OI z?TXR(7$4oWMiU|`3A5$EZz1#Y>j-r@u44oF1xS#;MQasj<OK2k_<DQjt2@b82A!!8 z7oQp{DC?-g-vxMmTJ@~AHVxpJN2H0}io7@fp|R{GK&*?pH_q8lC@U#419y2-uKN3j zgpJ+g*0sdHXQ{DkNH`3=iX%MiZmHY-Jj(I*$oE@G!CQVqsJGVlM&0x_ThaugWJe!~ z&Na}f&9e^wU@s?!1-ww7{vK2#u<)1*i(-SK%V-KligZ9Z=@(v@OzeB(@%)(MTN+8| zzBhbU{p)fK;M}}nQ2axogxGnJz!zZp5VBsE)7#;}-LtysqEcXuY)79=g~VPuZXA~f z3qZZif^rcuWQMvLnAuBK`%zf1F<}z73F`m{FhdB5Dq($_8%gVO$JRe52*N?uw&YXO z_-|PGFn|qaKb(-ayKL@a?dRB`dNPyP*e7`catl1uho%7EdpJ`w99lX9uj(V4Vl!Q@ zHSTMd@wX=~--c_#z0L;|?e&Rp_!O#L`eD}plHN@<6y5IVvI}KwW=HWSN8DACCgE_4 zV5w`x4V8zj^kSnIqbG=kYgHhsS-GX?U@?r*!%W4?a$3&fE@Bd{Q%gbVAGFlzy-i_N z?|cW(sI;CKuXEi{1&|H!^XFFM<zfWSLOdlCSAm?*pEJB5f2k~<pDX)G`??}XP3+%p zM>~^ZKbmcT3=nrd&3sN07jLhE93p3RCB>ZbCtgf~J)Aby?ycm?A)Bj){W?R=R##0g zY=5_#lb3&R^x!qp!V>V<1IK5pz<xf&cTYWL;j!|o74|OUYOd;?<4ot9Yr@gJ!4tlJ z6}+f2q#4V4vggdM!ON)PCw1gMhE+QC{v<tYv5&XNuv(BvitgRhN^b<ux>8LA`Ho+& zbkE|sy)D%jvQ3`Nup@(6Hd_38YtGv1O#0mgm;fIbV<AZUdW1?6sZu+9mj{pAbjOYd zsi+ryOCA?5WdWqzo9BzpuK3)98T8l3vsGcwE2|MQ3|WFyEhpIox<o8F#A8jeUc!T) zzB-{e*rnx1<K&6cxQb&;Qrm0;&EgKi^OPEnHo_f1Q5t{neA}+necO)QPPAWmY`;HY za(6tpIwx7s2T8$x<@gK-kQR#U|2z2W=AMTOKU7rzsbT(NiR>Vy8PUg6AU>7|^7xBO zD^31`EG?NedD4qklUyW}c$9uyPK1e6mGRxLCF?MTS4aDc%^LYh7)|2&?G(Q@bb?g? zQF2#;$xRVS6H0Yv<a<7H1grC`J!>l7a{kx&jK!HgUuEg81Q35+O3!}P!lI$<jBRzY zqw#9*jB6XxdO^OhQZl96RXR=fS8^0#6>}9GIl~?J;=`YB-xpIlLyD!af|B^?b59c5 zLP}%>%LTX^<8b057iNH*9ySa2WA|IB50}&!%cr>oxTkK{klrbk>{11o>owJxjDh;M zUnCO6yySy|f|lDD4Kg_GqDs8oq^fh2MlWk@azuAh)WK^0(^IeKO<>3k)Sj;|)U^if zQ1I2pu1)%4=QUxzWIL#|tUvB-m6Z3nYE}u=psDJ@qo(H(7(<X`!JRwQ>bSzjK~n|Z zo*Jn+v0j@uTI1_=Zf_aIyjfvP;B6W{Ty}oX!xng)^RTu+Zvb9@T-miCv-<tctyiIl zxSFU|4*T4yIIss3J6tA_Yk*k;IYF~s=T&J8x%Km5x)aiAev#w0kyjJ;oStvDcZ3sQ z@KD>{<u@eRi`I{!p5ZnM!ua+*(6FBU9==AphW1!%4IsyDC)Ve8jm9mAB-4juv^^*Z zd%X5-QZDJ1n|-9+X>{^w_=lu6pBj#->8`anxAAgpja&oUr^mzLv8tHaC|kSW=#d+E zYFq8#_u`gh7xssFcZ-&;FK4L71Z37ToZS;bm?OEBDF)+m^(^K?CYyCVDx<BZW0+ns z&lUeL&o3xw$h+GAhO7TOY%~?3ds_nq002fiZ;MWRwxn+cJYE0vHM??QzCE*HQt(I7 z<<FGVxrFr8<oSZ!J-J&nH`Wx#Y}#?gGUe;4K&)-NuUSN65;H^&vW~*`u9Wj`QMK76 zNY^J*s^ow1c)SVc=~m3Nn9D9PY?t!0Eb6yAIG?p1zjn*%>A~OyFQ4JmS>gqoc=%i# z3*u2E1&TVWBvZTNq3?eCrXW?pt*~qQxKk(nnfQZTN`<oqT%?SaQh%K#W#^CNTktDE zHq&PFws%8_to`{7k+f->O1jDH4p|i|0MfK3`-BrxVh{SWfG4mkM`f3A{bqL+aIqB` zKR7}4Ik5~KmT8eOHmI=a`Dd5(_YUF36hKEiLa~I^b58GL&EH}FT&8I2qal)jcHQDD zS%Hrmg(oa6EiKYAGVu-EG5z|qXF^YF_vxBkR>()tbLt#f&d&CZ?zUL>Z7W({$OH_> zek%nT0(~Ye(v8~+oHa;?DW&}DSvw<kXJLxVK3v+9-Z^yppAGysLm%SEB`J*>L>ru( zMh+B@!I+qJ@D#xfQS9ZJ4Ks1lnKaAfmh=R(lbKt4xLaf5h57tGF##^v`5J^tBiOfi z@RBF?at<|HC#a2+&Y3()_47gx8#N-YlpGwYuz>fXPZAgYP%KH44{six5Ee<Sq{nLH zZgn-V62AfY6FSA<KCD9k2!~mz!lP$z0xVL9B(#c%r}iz@>>f;=Q75wu{si*EPG1oX zBPE}r9;3)>)Z+qf8|s--FYnZgHqlMzG*BpB5ueB=sp_fbFHlE})o85nm?qbKInXig z7|m!0n8x3aEW@L#rMWaL*zW$FQcJk{rWKbLWkE0F<2JvfI@Iow-Ppy@H<~(3Y(|4@ zUvW~izE1Mpg%PbqhBI-8p+`c$6X13<n~X{m1q%Ltl10e(GCW<-?0rk0607<#>Zl=E zr2oV{j%+cTAd85AxvNbtOX)lB{QsT-(@-!RKCIE*X<<ZfW9+Egt+6W4bId5QtD_1- z7be#jI!Z0)75K~!%$zqot!*>iMZG?WvtMM>tL!~$)9KG3K4QhA_(f>a+xwg6iZP@4 z@>rp<T%oR#2P0e1z=3V}cGLz%YV7vA8ZrMN_)gT1hBkoWi^F%tEc3dQB%|S^;=)Y! z^nr4%_AiGgWea(1lQCxuZ|g=zCZ+@z!J^SwXQ;;BCHB^HRZ`F4i6(iAyU7V8xE+DG zI4`Bq0FKOn{(M|&3hI^%p*?z~DabZC649604C<j~p`O*xlQBddF?0qb9y|`k3?C$N zYP(7(xR|gfv{%CgsG7l%k$p`Y{tO{;+^F>uVq(GLxIt1HDHz~3nUj)67jd|fp|HAh z`{}676W^^9%{oq&@01zD;Q}kllgBrnPTq|C22J#M3X?w@sEkZBevEMXz0qt7jB!U& z1GI`yRE<|1Mt8YWKecaLz-&z_=*qTXewA5xYf4?&7S8o6M^gWqu-L#fLA5km4*%tA z@+JZ6zJY|k2CP2d1;zhupX%Y%A%Fpgh6j9PUGR#yw}U6|B@DRVBE;`x|73(5{pL>| zrzv16h(F0J5L+&Qh;E3K?t?OAbDcIZvdC+Ou_b0<Vy-!|+(N)*9a_&xMLOqnzb7?$ zr{{5J^^S;v-5XAa_Z?8f{0lv(GH5iJflP#N69yWLneRRF^MOVcfm<<GUL^8a+vqWz z#BlL9nX{Jx?ddtbNAvRFpJo59HbCl~tQs?TFSe&cJb6}MhA3$kJ>=Q7=dZsY8}G@z z=WF_=r@sjAE9(JMYPR5rOBVzWE;Njc5exi$iEH=MV<gbH<Eq>-p9!8V9Y24AVd|5O z@kPN3(F{Whq+P(Yu!IaQXn1l=N<)#j)@3e<B7vQWrwJ<gQ~B0<aSw00<Hx1+GoDm5 zzV}@Ds>Xv5%8}dA6ACE*bDh$|7cbng{3^_*hS;Cmxj76=e$>!%aEeM8Hf*wrSrD_R z%L~EgeItMwsg_4CZUbSWfu|_9o&1vJM*Svzb)11ea5a7M;O_%X+rCjKw_vy_Rbvfz zOaEeq8sh|=F~13Q`7wsobZnCl?KBCl<o!wwF^S??mogzu4ADSWDujT9(Hr;8%R>l9 zYGUB|djIcQOC35F4aWKSEAHOZYl(d1x=x@10T0<sh!6lc`A#!xI&_#@XL9EflGAwJ zJ@BzS|DU>^g!tNv{0{q7LX8viN|qV_Ua{5uO84~<kubU9EBrSMlTsRAv+=L#WSJt= zl|3DpAd|VD>YfrKD@Eol<1Rm~#5sS%o@R?)!PqGS^b=P_Q(BxMCcGwPyAO1*HfPzi zC6SzaMh+mC73PL|$``7U+V6U8`ysr{{dPoA{G8vPS)kA}xkpUk=27kkFke$a-;;f1 z2+uLc9w>-)?Fxi#1GKu|u{ZZ5fpf}*J;nFBglXlMX+!B8KJG6QP|1`fmK0w)tRw@P z4Q8a}){mQJ**ppK)-Q+qJRt)u+<u$obcStz!^K(35Sygz!<SpM`W`laP(YW{g!Qz7 zBAaf_1c%QFoY8afTU42KkEo>@`Jp?e9*d|$x&?WquR5C$*%AJi(#TpH5(Qp|G}!D6 zP+7@j^J_aWOJIkTMuW9nU@e4S${PS%)www^?xzeYBnYZ~tmBXe6Rquw%OR7CUyIeI zb;HajGh4U}OHs}&_&C!flVA53JiBHy<ODjxq0hTSUZdW_>!ATZLVR~Mf1fk$$c8q< zw#e+U<NglESZsQJ|K)H!h1{VojjDQX@e18X76AtY*fT4z&s0TFgR#lBw@xCsT;Nk} z;(qt!B9})ES6~fi%il*<E;J|czF+AN3og-4iW&~9ViK#@J%e){05AkD1c}{nql%F~ zyQR4#qGHkxBXW^iyy7&mHsD+0aerhhb*F#<hd%L3y#sEBwE`86b)t;w$=7_O#6zQY zff|m^%(wgsK~Ivrd1`c!*JK(oamXBI&?C#wvG#{8U&AfyCT4@V4Fi)u89r>kHYz)? zemm=8`E?P2?#)TBNZOU&W7e_b@_}TUHhw$j>mc!+DIj)$m*1q6%vs_lQ>}|7peq16 znRuNhgr0B-%lPm@1_&%PiW40$Z&3=f{ahn}odgC;n`n3WceI!c#Vpe%TfAyaXb^S` zbyXvO(An$Sy5z-<o}dC24Q<>F$%eq8`X8_RoX<&?31AxJy!+%fZVjO#=vk4mc_uUO z!ozIhSk-C8EZ!h$g$zrR-AGR?Z^f9G$~}f&C-K+5_eVfo4jbfOk+bmNwk$0T&nRN$ z#9$^{)CsLe7}W{6FhqDo$kLPQJO)$Ivs?kY<1$SU$pr{$=%-?+^?E^wuUi@z*BHra zA}Iu@JvFWub@~f-UQj8!qC!;7C7leD^T*Y`FJAGb>BFM-jR}mRq2b#xvt8--BsW_d zN?pRubq<biWDW#R^HPhA_odu>oqyJGnTCq$d=9e=aP2)SzRR5wrA`Y!sN}w09qy5D z6sUNm*v+IC1%OQ@FfY0fkqEtA==>kbD?erBv}e0+O!M*s{eHwsXOagBHd+`z0<9`j zA(`-avl$2tVTv&fA41ofBYjO8_f>|UX(jyk7J8WDB}V7e#`Ry^YC@v_U`PEeock6G z<&<F1rt2YR9PM4^$K&dvDf#wSYOD`1@DMEO*1#9V$Dm~PJgH2A!dLx!#+~7Nprq0( zN;;p`Fe2@5>LqYS=oI-Jjn$DuE#=t-?{GMe9)0C)ikoVQqFcIb<}~-=Oy!SxdDE2z zHQEoMeiPrWA^DuX?(nTtXTiHMQ)WTa7L`h`mUkyh%<t^PCxSy&t6$Ir1nz{tiyz>o z-xj@}-4HL+g6&5~3<w&e*C}#*Sn)yzRMFZUq1yCv+LL|1e)H?r+x>LhRA9fYEiKbo ztng?0EM2&NB9n1s`MqlF^o0}(21bv~F43DoSEY#4FWg%$Cb&v<_frtCp6<+=<}P$` zk$T>Xif6vuAoaJKbrg~`<1Tm3JfLk|<62_<Z{0Sl`G6IlL!D7%5^Y1g)b;18b*XK1 zg<r-4DCs2zl3m#oVaTfP+{s9V|Iy^`R?bIn4rj9UTPc}s=<Upmo`DlUks>H6b^7_{ z_iAlZGQzh#mw^LKXLsJD+n0Ra_qR3lojPb^au-8<+hnkMH@dY^zE4rfc5;YP8epMd zCwrN^BXH3a9lP1)Ps0Bq<TmShfo6E4ed4E~7Y@<a%ML|H7kA{Izf<F5(;I|FN1j$* zZ5DDyofOuA_&j^6<sf;78M?r9_}Fw4xqU=;)xkD3{c@OT<VCB2zB5UltCYv>V4DGZ zEFO3>r?O^zt1cHIZA}<7kx7Ho$<h^h`}6p#%@^A_mF<&Jy{eO@cW+N-ZVh^jijoGF zUej+!j3sCP(RSN?ZLeA%x~j|m%(UH{jlO8+gSOb&pt)|Ek;R<Q*0jz2gh4MylkjJ~ zvt9RA7F|c-o5i*Sx>80o@)^>Y%inikvZp|4<t8KPwVei7;VP_~=O4l(v>tsT{u<Be z^s!k<dz?e#>GPrD1?1u%2P&@Fq8cX&D<>y*?mpE2QF2&R0ni)Sna1xf<-E<_+Zis0 ze)r+u3H&J==yc`D?yTJ00+ba%Y<k5Rv4}5xHtZ`tSH@9K<vh<WS47M_yQrTqTv6pG zYSFINO+76Oz51ZH=Bjk7HcDjF^2sb*u{L|6mDsF3Q*SQ$`MTAcgo5#YcAkZzkz>)l z%}#5s3T2eO{_kSbTzIUP^qZL)juK^2i(ku93%lj7+m;L4)ik><;{QUUCI6b{HV6LP zslZ5+k>vlTDpX3#@^7jSK3)vXzph5Tx<~HIFo|GeMgCYf<j!_BjK;Q-P2oHR{p7ZD zO&Y576e;j@yt!%^IR6WB^=cFXWTtQq9(6vE^kB<%*A(nKQcz$jbw2*&mXQKl_O#O0 zNUyPSNxm3LB+MD*AIV4T^xveVN#N!Ac$cUWS1;UuzZKF&3z`m|$VC5eD-)S>Cxl}l zYxW5Is=Y#EO%1FB+AG@E3`Q??vfeb<pPgY2tayATkvpS3ewJ_o|IKfQ!NX~KI-e`| zle>WrSg4$B*0-~xQ}Q|#_{%J((AznMl$%Fs4FXF2o?#dqKG%*nb@4noGj<!iX%_Gj znt6k-()`F=QoLE#G?XVhfxk>i@IujYOCws-SK%T+H#*5w^R3)1d6;|p&kfnL_HY?9 zc8k89UJ5Bt-hjxaeCZ;>xE-}6J7UZT!O={;?Th7{<?oM-`143I*lwsd?9)SH(8yb_ zxC4NDaNBce$#YDdNkl0$d#y|5eW&N+xBZIh$uO1;>7k{_h27?rc28o*RPRp9VC)%? zrVZ{1SO~p`;+Hh;LursATfnflc8+gXk0s-V?*OLb*5t=NsJ`BtVPNHyxPi^=JP*df zfuk5tI&lxQm*0lvvG3K>CQ1m~$1yf)MtQBX_pk@h)2dx<rk5h{7+6Ks8dK1z9Cc6D z<dT8U7;ze<wq+;h5>a%dOsN7RytDMV70x?-`6jPWw{q%R_%^YVNA88=#(O}4j-3e4 zYF@Q$g^Z6A04ckjTl%HBmpyei3^HjnM~?^2R5wk1vR54?nXf3{yg%q%tATfi7n-Gx zG3>_ym|^+Ho+Vr8C<+RzuMXX1!lDw}<_HILa?9?fm!{m7z#U@^A!6?Js?k9uf221W z=;{?DF3FEDu=f?o2uN=|u>lxrTGIp3i~#P1Q<#1EOQui5XU<u&xm~BRACOo}1?Xsp zr8+%{BQ!WR4|!F*3afk2WQ0%BZoGnr6sUn;sHy1L56Z-LRU}GBNH;LK0Pid#F_A#; zsgSE)TW)cI_>5TZlG^ceYxaMP{3e0xaSmxErFW`#?D)7mz!EL~{vY8!Hcg(Il4|L! zSW}<V>JM~FOBJ&jHM!Dzk%2sRXLmQx=l+b>_u-eV_Qk%zoAC+<JG<k8o=4t0!+n@} zvS=K*gY|5xMrx}=?eO{YXE8&=9~Da%7UaLtf>bq9E(@?dSCzH4-f7+;QJ+H%Qg)EX zQdt(lz@?0MY{sG7YIm%|r6TWJN**xj_H6`a0~<NLg3I0{(~KzW^Z%VDV6#>!>~R=h zUhB4w8+P{m6@SpJoF-gvFFn@qbSL>iYvFhm@>hA>yEFQWZQR@6-vG}}g#q8d@yf69 z&!)U9`>;(y^d%&=_xXLVkJv}is8S(|BM*-~>F&?Pi}y4E>ZsK(MM8~Ae4%g_D3Ug% zyUoibYkcNec0-sR*z1asku@r5Z`i-Zd2(saud5bXxBu{$pTvS({Iv9&yc?}>P7+1c z+#l?6ksc*lG4Q^az?x5H(IxI8s`!>2UYn15BHN)(3=!DG4Ew5oat)YB*`P2hn(>Xt zGmJauTiM6|Avy{IcWCmi+rJp{6G9$Kxr@I%U5nNqUqT-pDvr{x2?^hbzLUssr0RX7 zn|;Q4S5V4BgmuQS#`hw@!mgqObr&ao8S-`)kP59)ZsdUwSx2&zY%ZHDqrgo&ekFa; z#XlYFFP^Vq+{xfk#6D7SUnjdadWlCW4m>-;PU$%ouFLX~6btsbKFolFAXpTGKpb{q zh(tZVW<M^i3Z2zT0TYT}EfFr!{l+{h{d1*V7f#n}fY2feYGX>lWW;X0s8S4|WQB}N zq|Ke~!TOoXPS=SOCw%$tS5-M})mWFCe@FbcX_7avQh-1RPp*ALS%>!DjW&!O&Uh){ zZith@V38-Gm`><wQS@;{JL2thH`{p?TD_ek8jA3f>ruXb2x7CR7Qq0F@5>~Xe2xIX zp}l61m6z;_8TVOtjplbjCk8bCN!J$WHRROw`F1+j>DOAww_pdU)W(2sA;?E`J{@?M zf76_5iEwUPZ$)0jFXu@&52olW3I2$nta!c(IV9It=rS&OeWVbApuCV+2X+bh37=Ky z!!&^^qo!kdh6;Kb*jx{p`C`*j!H~>Uet&Ke!N<xY6rJR=3au&J$07wa=c@ab`49u> z&Sexm!JtA1_IL#<#d0=Vn)^pwAH(@(dsqefn9n2}la1nY_^8&R!H>p_onoj0DhER% zm+SkLtdI?UM?nh2H!nIYvS@3HuI{LcRbSJ+9foQzOV@onyf-x)LdDMSxHt|ADdgk< zW`w4zb5OS|gktT}O>x8GpP700_?{cg$*$K*&8g|B^5^q)R>U7n+r&x2=huFV-<k0S z=c;=D$ei)h6l~FXBCX`hpCk439Oqp_Q8>02jLU}>Ox;4w^JhaT%^$rl3UvV)PEJXA zyW8hMQK%Ah#>a<bW$9+Ad_*R{atIR*gJ2xxK^CVQ*1k6$EG|Yiwm&v1+SQ^C(d7I1 z@buv$EJf<M2k=bN&@-HQ=ffQZxWUu4;=oS_kQXvJN-qtmE{9=h@f#gF#OJ#~7$@0G z>WMV+(<KnRg<2NpCAzmW#;*KINonBLNNhuk3<!Ix`bNHejQSKo_u#w0wz_bE!pDOC z$Wt;wb=w-<=efHu$*($lv@wzxAo;0MUt{l9x`&?0VKm9ZvGmmQc#ei%XYMkIt~?Oe z4pdTV`$#T9_W>#10lQ-=BGB+6^46(mQ|eWZd{nu(f$OAHEv-zS2O`QRsllxL$?ZM{ zKwz;#HcVP9<+m&1igSVW=J%xSZ;x^`TM?$BBn+1QKn=88jND=1xr|KEuoVm>q*^?{ zUd9LtO5SY;?rc1qBzz8?VkUE-9r0s7Be)gHw?Izj!qw7d8r<I?7S;FvK<xhmVO;jN zY1!Jt)N(d&%?-Al3^{wRMJgJ)6%Z3F)Q#4sM{FM?6@Y1rYY0AEw`FFd0d8LYAXTd= zWLDuV<I+p+pRbYCGHJ3l864lM#3Pu6Q9<~&u>YQ^Yj>-#TS>n0R0~cKS8HT@_q&>r zqD2bODDSmuq%jcH;U^@vH676~c-GcX+wSfM#vN0OvHHuPZRy#o=w_EI+}%lD0gM8a zDMof_S_E`M=x;=Wwsy~Tbz5wX;_#o4uMpqGT*LdF{I5*<nygSk#kv(Q#w1n6W?zt5 z|NN=D?0O@TQg>nIzB>l*5LMZH)@94Y{AH*HEoSU)s4J)QmaLD6n-4-K@{CMqHv7bC zC_s$_HSfSzrf|#L^1_j7lw|*`P@Dp9fR6wiAJSl%9YlLfpkrrG@S#I*VPavKIu!!o zR=s@>c)ceXo|x+Sf5+ka*1cj=u$_6W{BkC#J#waE!xm#AJO8X0^4Tp1zJH`99z231 zF5mE~Nk4>5VG>vOE0sGxf#$8MAh3uZEe7TwAIbk01tC+t+rb!8bQDm!AGZEG=o1Xc zD<;dXYwbzLwvR#GB42&yQyNx{{9d@^;P#3WQ^TVetBjwE?5~7x-#Vg%;jWbOl_cM_ zTMad}L#7&*eL$c@2A7RSyr`tMIlfTT3u+_80aM@GnUdJ&uh9;6A=yF&<u2Fb7WTMS zLg;K1|L+cvl<Dp+g}V(Q{(MDnSL{Ksk2N%u)}csaLefH{@M&Mo!CU^J>Zgmp2MDFk zK1_BBRU?V@%uu|5IT$<gokOC!WX!f(XgdU`#u$lIlkFM~NYa|C)RS|F(;x5NRI{`u z`mwMN%LsaUG_J=SlML2^DNvHXpx<rXV)G@(I$f^8P})xa12=t;%#>X<DQ#;&9%;lV zD!OU=<siYb=90<x=(T@xz*QXFd%yQ-O*Q3+bV)rG7=(AiBaPP~vR-}ux@%K)_4I<u z^UK$bn7#m(JnX(3lk8se6Jo&vW=#!m00b*%!(CY?(MFQ%gEiW_O0gEFS35FKMR9)V zyzia4861-OOKl!Ub8v+)w<2eU=wpc3u}gAExk|ifuMFG7L<W+bPV{J~MxE$xEIhlI zILX}LDDk{0TD;V1*~r1gQy<>6AGEgs1n(#G9sw-g)@^^w^<w=qC+q;skF`>#(v>Zt zk`J)#GmbYaYtjOq&@88X1(hRQF9-`5j95Yl1lj$FEEait-<C2|D_ny_*@BV!GLZD5 zzjdaIlL*{~UX%8HEiQr$pP<@R(yAUY98w~`YK63abhVv98EdNSUVt-x*SOFvuoz!H z2}-v+BA<#K{XLV)?Vdm!0cXB(GZQ`Ky=yJ#Hu1LddA8RFJ@O<gSLz$ECQOgMA;fnV z#(|>vWg44F$TY(Mhyn-AEll`w;uKDlW9|*#o3~8d57>bYs#g-}PUvYgVb~Ff=F1;3 zKwhw>G*crKHJsy(FYMsB2F&g3I}WE=<5fk%2qXyz+lH$$m2=oX1)|=2>Er)v-V%!Q z^>uwivs9L0ok^g-diki2JhVEpxbM!_M+O6Evh$%x1}-t%`#iihb;WaGc0~lmBs0RZ zkQyd$fEe6O<1qzUaFEa^u^P1qcGGk=a#rPqdkk2^BsZb`_e7jG6Jz~LzEU{<1j*C0 zO?`wXlxnYzB_FT}Hd78fOmW7U8XDz=Mqmy><a=C*S9MhI>Iic{B^<2bp!0;px1noR zV*GKrN=l0D5Z3RP1Cb1h`{jOMclfBq6YuiE9&-`}<6Jl0s^9{>XZAl_ry#qwSfhtK z)#VH@JvVnMn##AtRFL7jw_ex~P$n`G%vglMJ8XFz)<`HF`2~$ft}aSUd~|`fEa=*$ z7igr|6}0+s%9<Tqdh>5@UOhGi3P#ckjL#0}!&f`_gmjsaT>=egS(=9uFCJF|D5sej z8oiqh2YXz>xDxR7Kb5Fn13lNp$b5ElywiwTpwpc%ew99Lce+Wq)9Y{#`KPF6Rgj|~ zsk9Cvda~O;mwoI$^@7iJLAsvSMdT!GK#ygZ^~Ob{!;>@Uw^y}zx0j0d*h8JAFxEFD zmr71`=$Z$$-T%m-c_+^PF_-ZBW#(H+<u~x?mw&odH?H!9{>;8&!`(tI-U}1t_BSH| z|BkE(L=Z=foec)_z(z#!CdrsrfBT&Ed@n~pc7(-#MK=!(Gbyz@kG*au_!z`&vir)x ztGq1~rF|QnB{eShKeKuq|D>Q}@}g6I(Iol?9Jfflyxm{8klX+`XAHZ{9=tYso`&GL z!oSf73Ah5rl*|hjHr|*@A_T~<SlUCA!2(;8R24v1n+pt$cN*}|xc^7NF(~!j8}!dn zy^CMx2f?MBOj@;}?``PlDg*DOkN=aHIh2mu9qv6&iC@{;>a@s3%4Zk58G%RkQzKyT zkzc4buy_|T+v_wt=B<bhZV^RjVyA{?YI(gYL(5be*u%oOd&cxa8t8zOU{aHl#hQN( zvbErz@gI<lGTGzyFn|!;b5T)4(l6nw3?ZQjXriN44=(V-69dbs{MM=w($Ii9kIed- z+VFp-*`G~na(S2du(zWw@VH{m>&8a}`cvn`C-`0qlwUhiS1$2J`=@ht@c$A`qq7>3 znroT2i=l37CNwOv5b^Itu;cKVr(+-XJUKV`@rFtE@R+K$Iy^d8oFZTOGsyEICj-1r z9DBa*tDPyUR`brZxoTv1A9G*%yCEIdvU9{GWPGzZ)S?}p@<{)}RZWqok|PvR3rx4N z;%R6=Q_&iF$F6-cD=|clhuv^;%p=2E4W+v)$I2qLpR>S=NhT#dvGV_TllTCD=2B>A zNiK|(`mG|VOV2UyWsJB!<BaL{6v|Q4IMIKl2(<WxbeB5h5NJPdqf3+%0e?}QkItI% z92uZo;1Y0$<i9H-_Au(;;dKkC`bY*69AXT&Xq^5j;3h2f+X|CTnd=^H<V#iI+^Bsk z6>2=Jr&UW;_vskFsJlOR1qk*$-szN{&ph}wkIrxe2#P*3Cb?N1mPwS<6XtK3yf3eQ z$-F66v-~|*>9^P+_ddT{n-R+JWGl(*qr`nK!0GhsaF!U2meZA=!;!yTg)Muob|{}z zm`QWbozHvb;Rr=2`0$x!`@I<0?CT}`B-Lc`LzHUpA5e-nnY6=W9_jYhsf{sb^V-y+ z|4r-r3{8Oo0jc+~m7V<c1dcDKE?<yMf!Xw7<+R8f=+ZhM<n$h+?hy-T>Jh$g!9R#? zV(ytKO@89?s`s#a_Wq)w<z)U!dFg*$i(H-Nba6SZpK85hN{v0;Ee3|qo7evX^DyQ$ z9#c8>)Op+V)!f3gq(`rsQpG6CJ;-Ow32}+j$cp`U25rRza-{79!jr*+<QRND&KBJ< zB=RJK@y5&TNS;+7KGH6UO|shDa$Zgnz+055WH2}riCJGp5Ayn!wf_C!rEmIK#%?uV zi{-{402)EocKe6}ZKdUaZp^1F1i^rVmW<$^E%?cj8qQi>M{wU89w)Iz9Rh-HF>?p^ zeK6V1LbCs@q{2?byGN0HR}u=|Q+lJm!RvHROAbU}zvN|gox0|FNZ2rIMsAWEX42l7 zSc^GuIh;D4EWj{Ij)4=e`tMYy%`2B7zm&CBq@3+<Lj`L(YTe~#`n3%wjYG6Qzi@xY z>|{4D8>emc-4-ZWZUVa4{a*K{)ZC_{$?f4eH?q!baBh{pZcSZlQ~Fc+AFhhC+`O=G zF98ckDlBfI(LaNni7)AgLg>d#lW0<$7)yA$0KJLTibL^yk!E(?Jm+*Y?}Ym>@hGEH zh-TB7VK}CXk9>gobJ?4z15)@Cq5-S!p6kb$`dpMT@(F$awRuL0tA2zwKRvgW9ulLj zQ+fL$?&KRWmqZzEgLlna*}0X<SCw7<5f|-{THz0a9W2WQMO;sgR{&0jh&vKw^EYJn z{{Ku-H%_&bW#H*NW_ylmgOo|N;|uVA>E$ZJqH5bMuOgrV0s;<74kaDZDL8ZpGK6#u z(g-L55>hgRgbdw-bjmPvcOyur#2^yV(s=gZ_nz~8*Qp=py3XI3z4ttOo>=Q%_kFMW zP-nh5?KBHf<fi%OQ9Lgc$Teb8y_Iqa_x!-rbPLm0zPx<!OaJ}tj_2}%hTIk>hrTf5 zHx9MRqw;X|{IlH3iEI91);wbQJ{28hHXTMes}?)iuvFdE%sR5>ya8~nKJD$P@DV&N z8b&_+IR1O)MYHNc@lmvZE5u&od8;?S@zw>&PbYW$TD42uZHH5(#=i&DVaGiz_NZ|l zPYeGkdYoiZH1^#^oYi#?|5z;}*Gg4XoHfdqy@=vY*!M|WQAirU)g;86K`gs6J>sJF zF@(sx!ZagqFBL<jAsxSXY`p`q!?Cb&X*tjxd)!Vm(B&0!p^SLl{;cE4C#?H~F>8{* zEhA5T)6PO~->}%br%SWh&=dB~j#t3a?ParyVvsy3a6!^WOqd8AdvNdZQfzIE%gueh zX}zpo92f&r&H0&7r;}1W#uEK`&B>uW%Hymf_Cclot*$duFBFEc;tfIIC`-(*W5p2u zP|gLVv`0BV_bnHqT6)h&`rtWqMGfIRU7(}UFJBi-vMxr2I@7td^}KFzU{CqnGCXN1 z!Z(#wO)krkk~3!ObhKYP?Q?whQoUZs9W7P{Oed_bUvep)y9EiY(pjRE&v5H~JW6H+ zuS0%*)6xscTOu7`M*a@u_AbM))}IereS%qEa3gg2xO3`yT{&~B2bi;!UJ0Ou3Q4r- zulT{}>c?~0AAR08-8sFe=AYBCnsii)dz?a%s~-*8cjrk1r0++dP3jG+=?FAMuXaF* zJo@p<i@Cs>#|Ir{PlX+=%r9%VF@>xi;1GVfDOl>7G~cR9pEh+ZhbWvKbj2KaBp2`# zU-*o4)+->`dRf4~O>2EF#Ke8bqGu?%4fQO$o@O3>8&<4F1k5B|5dQ_#)aG|+MWsfB zf0fR_7-^Tmw#XdVNkbyif%GSq(qkV=`X+#IF;$MvY^vZ;u`aPhjV*1)4%*e7d3|>} z0m<FTRG<eSgl5f>5-{hD+T#I)zk2?62NGi=SqLquZv4Uag2@9$<On$p&43E<zn+uG zbZ*>bwY7jilUDmv`+(2j@Vq4;OZ#8gpkQB2LE^{p$zbJOy~+*3XOCRbY#mxCeR_E} z$IuDS`CK&yaAwh)a{%cew9dla?zZ#X2^_j|6Hz(U4Ym{xw!5ET7*mCFs)W7r9ZcZh zG!%?AT)~8j%e>EPnRGe8OFLELRX6JCj6IM@49!wM?By3My&K5$J03n?Z1-6{K(P%w z>Q+)UrpQWL_#A8L@?@#7Gn?S;8z&xaY?2s(l2kZKg(`lKGU+KNM=uEsJ9mGBD$LRf zjFBfUS?HISNh9L~eR6&}A9j74xJreQHs4O9R1wLkx%#2vl>-+9I*!$nOF6m++dD=% zSH6E2ReO@=j`OH8r6ue4sU{1bM9z>C;deBXX3oQ8`1y70Sx~zf{>rdE&CkEyunyt8 z$mEzZ%Nnz@>)TWo5oXrH&%OHE&^Rs;U}N1T2|ylO((RlHT$P=ZLpimJYWZ?RLOlYA zp^38%+-V*MJ`Vlpp(g3~i6$oFo%UqQM~kfmx@bORsM;$)Cq?B5>HJFQzXh1T<SC-8 z2H5$#^NwciajV{{K0uu;ZX2N)zAcCkej74MwzXjIvT1tj8Z2ZP<Gv$qc>e06&}!0D zJw+*$sO^~pH9^PbF%4*9<kN?`r(AX{`V_7nPaS9;1p4$<kfwg=cJ~r5$rf6by7(1b zHR-0ZaQh^Jfd8rkt!UE>>j#s%CcHQ~$}r;1Gl<IRFkznj@IdVmd)vMg6}YThR^3e~ z0&*=zo~v0&`q*L2&a85Fb+ZT*KGG1pgbRXX2VqGd@CdU}=l%BHo8t)2)pv8%!vb0S z$|J0dB3}IR9S+T_G1Iu<J+`YIw`#boqI;-b!acjPC^C>os99MBX9;1K(Z64(oy?v@ zNk%f(5hv_c=sgf@?FlM0=(G{Nsp)Q*eCZBFl&ju@Fz3O3>=)pE=+L=itGgMGUXa4# zx_-t?Bd!C|nJR9moj=`ULl63c408`H3-$a%*Y;g*%|TU|o>Ij!^m3Q9-+1&{;1$kk zg+|v_5>wm&;;(liiQH@V{SU7%!O|3Ozx{E>l>*&sdzZku!nw(u3yMcklm<fRA^o{4 z-tUOU8yRfp@d!tg9+z9Zqq;p?Xza`>EG|X1Yi2|=kw3)2NgQK!jm{F*b3($`3!}QN zUitVq0u%`8*S!XY(P9`Us{zqQb@QvtAa;pv_uT^;HZoV(+V~OWl36LLPYQZXRvf^z zW#W9jCd<7C^xogU#2A!GIWpx0+C{?y4zosaAaw4acvr&R%;<zKS~Rh0g6kPcxicjh zWiYt7k8&TUzo8q`sU0RsKcWp0?Hm<W*UP~~j*2fx52}MDs5b00l93#0&9j=%EAZff zptx5vV?}BS5_s+2i=C4f_Ngqc<@fZTh9i|S!j1*GeR^JWSh(e-7zT<k2Tk9=?ch)V zvBhgvsVM0eE838tg}aFD7$L@25U(y^1A0Ae&*vFrw0^m%7#I}P!}OkJ|3mLXCD)Kt ztuE4g)3;j8^~R06^B;%JgFv<YO8asT@wn&wJ`kV|&0gvcUJ!(YHP<_==h+u%;*Uv) z7$}fdz_QRTa#4>g5_R^!0o7X~MGMGclfnkJ0>UW-_<8||ev=~dG+LwMY6wG0K%30z zDGCM;35ixBd@!(_AmPOAjQsB2FONG7Ee_4l>>@>uJx);NLO0?wl(Riy>KcrZT!`#y zCQ@!(JDzNNE{e1<V~Ts9uLkBZdxx%ptoHbjRK8vl53e<UE@aFhtoUn7BbnO}LqQoD zwVYLP0-+<EfE|pUBHI-rbXPY3T_kw8w9wa(ST#FXco__itag1=GBXpD*}~W~(YZO7 z>_hU#GCjTxT>a&);Qdx~hP;SwLn^h~E3<9iXtysuqQ3OW+OmKkNO{H|b+lt;2!Uc7 zq|PPU1h^$;_1`Xb^BeVBR1_&17xq+lR1QRz2?E$ja)q6i>EZRjb&iWV;U?#?LNCm~ zPybxH5wmC!aWuVFWzWQO^6A!92xl}fQ$R2Mh+@^>tF6NAjN#yTL-`YI(y@s7eTP8w zi;8eXq^f46G>Nx(=hkQmwR3fOP#*G%uN<xK_*Hv&HVIh)Mhhy|zt^8pE7dZ^fGEEj zlEOmEL%OA}<b-62pHHo|OWB`AZatQ9s}(|*jUL#)iqvC^0lCQ|7<$S6T)VSQ2Ht~< z>&EN#ho9b=KQkqA{4_V3L;kdQ#_ro#eA<h5GAkKHCPu9Qjg<HUo*jSCPWJz7`ZW`J z7XZeZ;$!g{b<?SmM~VaeW56#D*!qE{YS@f7Jko`N;J8wCf$(06H$Y3v>Xv_vi}oub zo6wm;o#7nHr}{d?ZtdxQY&^G3)YppCn1PlX2(+a7t|k0_IG2LcxBLa%<<VGsL#3gZ ze35l%DW}%Hn9T8>Z^+tQEv20RT)^w`eNt@^WXQ^}4$<ecmDki~hb-LLR)C?=)12fc zmT%J`BJoQ77KtYR8z`=gEVSw`HrKTovG7GMyZjG`NTF<&$%U>-!Ny!1z2vaF(Y{yH z8lM^+5jOEiBP!nD;myoPONJ~h*3X|?5d#qEixpDqflx#56e_}!=)`N3Za4@?jo_xg zzX0J8D1SV``+C@ek)R#5Oc*fW6M9IXU6g+tNf!D>CRJZ&H=ZY?*do?}u1@;_;~w3g z1*`U6#x+=xf5Eg?swSmtIVoJDKVs-#(5KdAA%!G}Dp<jMbTKiT>>Eie*41rKOmoI` z)LDzE#TvLXDVNEc-@lF30y>LlFO{#hb3MdB2<LjIMJtZ!1*P=#OYn`Wdt4nCRdl(O z6vbV?z{tYmD3lOeT;)`)BM78j1aI=)zafaoA5A6yF9>Ah8YWe${6)`RFwcl|=JWFq zKD=L!e&6Pm5ueS%(3G9iUMTIRh(Pc@+>!YY+|^SrUy>`6sTZF}$1Cyb>o94$IWu!7 zgk)!4|B@RdHV+`Gy?oDLXiFZ<)-_P%GtWQ4P~zx~Pch0qAd;A%l%R$c@@1FGrPwHf zK==uw{!ZCnDwtVYk{#u4EEG9kK@p)Xo4R9*r}fMXQW%dNHaXGSZZ@L&Eue_gvP<C_ zY1S(>_L4ogBN29J-Y4MhZb4N_HN49?-sivy`1o+<QE!jXr-F0A1(v11>}N?MC|Lxp zd7WrDa`Cl^P<S|d?X<#VTCHfs_LfskTO8yaiSRzr_s3rpRoC((dUNi-))@HepsO*- z-%cZ)4V%tWV{X9wN>b$-eu2Ylb1B573viX}^)o&+bub&_vMEQWHtlfn)xsI%^d}6+ zA&$O$kel}7<9L%z0xn<Va5*@nT+(9WI5DPyq=EA<d0Fz>z`q`J@LUwR_Y=p)gwg+8 zB(=RqLS9O3_Q_Cwj+@yA4W>j^S{Os9m%y@?^hi9V-qUzFaR+@-H@yeW-`FF&<Nt^= zEJRuA$zZk9m%{qt#td4^FJ5G5PLe0Km%(Zix&Y@D<q<>k@1xG`L6x#)pg8nBmx5_d z(%Sy&6WN=*e*=~C-#{f%yd)zumKR`4n^OD)^+)=K+=J)I^z%auI36w8r^=x3CtT_e zgltG44Fa%?DLpKS&|B<miaaGUks$^ol+?xNF>km88QM+wKv0pdPa%^P!3ZhzBN-rD z6gMY97RtQbJf7OWa3`G2Sa}oD+Cw|o`y=ScLf+gaVVY@=3{Njv#WHP^)yyDx*_*dg zj^|0<IMh5-C^67HU$B=zu6tM0<%E9f_p-O0+J~!AM0&CUkhGt7^dFFf$;kn5K%3a) z*gV1uZM}1_v4?(!P9i9JZbB?xTXxi>C=SZ{aB^p=h|GmrtGwQ|JU&&Sa1c^>#XlP* zbUmPrJDS`7j#K1<m!edLB6uMGfBdWUIx)^+4#{+8b~+3N^j9;{BSq!m@!n>(wHVZN z%;7ND3Q4<~fckOPwl3;z^sv*EVjYJ8oc-F>b`o?d1SdoKZ=Afh+4}WlZFeG8aiDBY zPlYhd20Ua<6%9#5+WXR<J`JDAHxdQMZ1qw)kz9yTT5Sv16FbK$yyCbD3f{gxempDD zVDjLR+i^ehEBDuI5lluOm4Jto!2c=QP@_F!ttil?$nSE?pcgkv*4MN36slDyLMRc6 zGyX?p;{F<7(e0^)Dx6mG7x>%WWq86Pj<#B%x#L@cJL@V#kDBRSG{#H0u^}1lE)zic z7M1{67y^MZU`O-cT2Gd8Gk_!Eg({~<+oc~!HElv8B36O>pgw?{j4THdPGo>K9E7Di z|Jmpg8<|A9kL<esx`!&W{0^S&uFnMGQ2jAmvsdwa2?wvHw!X<j?;pPt0JH1P67i?O zHv=VHrP6%z?$|E41*eRkm#m7s{sGOLKpGBJzvm&gmxpOF+ec0ot1%<XX)U3iDw#xg zNhxfOe$KfAh7D*w3slwlT?HQMHdJQ7Zr=x!mwV>deAK1j?{JtEMQ9Dy1Z8^O#FgZj z1RXOUSof*JrSC;@<j3zM@T)?akKX>uaQ!}rm34ti`IXndBaFg-I=lt{gi@=2N@>O< z>(Z~QhQ+j(BMCL*9%>=f{?0jA>9CZ*44>F`5@kFNArDPl*Def-(nn(oAF3ccmaTeD z-;fL!W7YHeL8xgfX0(qt%yh9&x%%j(R^mtDOWR}ij|orvos{0N`E?vrI(%WPi}0dY z2I!6u=?VVTf)f?3ss89Dca!p6Mh3lr<7{;|)9P)9`QfBmA)=P2(kAWw+0wleo_;LP zS%CF?^5<k#erc8;P2zKci3i8*T!d^F+q_+3keFOoSEW5H^HS?!*XYy2iVZ+nJpiTx zHgJ8yXbH3D@}F+!Pw<%^>K?BIr(+61_r8XGH8fX;w=T=b<e4iOAzwZ_VCTX^d2n>% zy_SLcU+fL$yls5|Lj(c=&&&&Q0ZN0g6RJ7(_3zndb#dQN99u(;^;l{&&*~rUg;Gr` z<79kx*u1XCUqA;AmSO`070w}`9tRg>Br9ZU>P6{Nj)F}eH#;-gp2)K=-Bj>VH*4<X zJap}ia0;@Rspx+OJy-yfqtH!T(Tb)cc{e(U>3hzw+xVy_iO|3`q)x1I&05XdKr(O{ z-=`&Gq6twtP=H^6@gM<sz)d|~_G=7$;=Co<4mH@Udwhtu_-2Y&MD-UPf^m5@t}Zh} zp5Le8{{-I|&;BUJh|-jAXsbwj%)J~<I>Iid)w7?IN8=So{e0)EmvuX@a#{8ct<tJb zAzU*KtW~Dovx*1X`5zvXIVn?x@!W1~=g@8|BX>?9e@3C*={UA}&_DjU*4C?-u&;FQ zvqfF^>yTA~i_<zz5ti?F+xIN03S^R&OFe4Bb*!AnEhfoFP)#oW5zQ*MH;29ijTb+t zB6dQ@UH}yh7hZTC{ujT<eM;9WkL2`jUQ)`Zf1vjt%Hs~2aL9BFaG=V?tj)JAYif=U zb?^<H3O_V&zyPKK;5{iLHF?juS5QYiDwz)fQ99xSVqS;83iHN4-RIVA;?$Z>wHb#& z#5{h0FKhWJ{bUmNw8O)GqzT18KH509M2I+t@VL(??NJzMDZ3H!?$4Rlr&9!I#@QYR zHB@9DR>Y(oGLZ$+d+=BMKx;T8^-#jNl5HeU;IL%_F6})^Bx@zx#yvr<^;79)JUc4M zv&i-l>*5A;1A(O{euoC5IP}hacp2KRqMMhVn+x9wgH2m4*R$)l0q`LKFGQZPKE|LD zZhA$<25lZI(wigZgg}`5^tvtYu=?Y&61<tln|yMYT=r!5`rAjo{I&K~mPYv0-f~N4 zf~1I!gl8Y3Z>?+L`mE<pK)LzGX?Wjf-#e#Gslz_Z(%TOEd_Vj^tQ%bESK#nm%twb` zTeczTP=hUljN7;g4s^8_x0!na7PosroQ(+dr!gPBky0Y|<-%TJOd%|(i$;3c{(?sz zIRDcgRye0fymxm7k6wEZ1jfCaa?&bt3wN47ZuV;HiD`=A(V0*AHK0)$dcM|7EY^Zt z<+Ua>xJgyAYl{};zAcq&Z6Fa3oHDa8{<L=k%Hd{gZCi)cyHY?o2&n3-%Sh?ERYs;4 zrApgytK~;EPA&P)7M+S1i5khu`z%?Qq8VeRnKRqFyEsBWH6~a=K0^9i<A|5bdlQk* zu9JA<m>NceHKn4449?Z!gQmvT5O1(N_zYqC7#DO$;Fin|V@vh(-z@%53^EQaii_Lg ze)tV=7{m-4N#AC5p!sR-EG_#I)MZ#X99iM!hRBDT^!+5!#>A;3rk?L6&=kPjk#bIi zP#+p6sT!i;;8>IIk{#7#ydg16qb3_^#a$OiZ0e_UkoVKJ&t{oyZ${9J%TrhPa!`3U zzu2(Ts&A4>`6#<}t!(Kx*KObVCD#ibs>{bW6(Bn;t7KrLIS`in<Nx%=k%<j>xz^7h zkmoJDKId~!orzU1I5I^tG?_{`(+TX%>M>#nPQqb<a}diK^EFay;W6~x5~M*SG~UfV z$8hFSvW(N+^YfUlG1NIK3@F#h9KzY{^JH1VKhW_>4cl#lr}<JxE%$!^*5euKp1xYF zIlg*}6zDr93D%fm`bu3a`x;F+gQT%lT`C$72|8;Q>G@jOMb-wtdlC*SIU98EpL)UQ zU#0OP{U74OmoXs`uC9}XlDr{<(L5SW|7!P%VW*m_Q}}1}nK*skM>5kCslYnB1;%7~ z$U9AxzS>5aJ6=emP5a!6jcbTKIOMNW?XiNA!uJePF8TG-kY7)tyl;&95b%GPW6wRJ z%h!JMc5+H%U6d9@>L=7I79dZf0FN<ga=G9G>Ks((D&u*ZOL~~AtH@vvSp`+T`hg-% z+$P5nz#9_I=cc9|EmvoIHrc{A#do%<<M=0UrrXbSW>`-;WQp(vQ|tOB;`d11+TJLc z<r_rVM_PZ>+=u+Wap5A=acLlOV!v`WMH)ad_hL~m>&w1(u~TSuy7HYD7?IyIqG$Do zM+~HD;)6-{y?0}t|H1C@qUY}3OAv?tNvHRcfpq~7GCjxEt4qyPsGtOKX2Yym)#{ye z3VZU0#F@}qOZ={aN5ky%mt<xw+QuGCf3%4>=du+Jpmet5fm40vhgiuXK*=txb3Y*~ z(9MsCd&42qA<EqR@Ex_fvS=8haEYDNU?4E}<_YF^pxot)nR9}=v+yXu)&wZ=xR^d1 zUP_BoY&^g1vcI=dM!@}%J4O524YZToX1A1MgILbetWHYz4E46hKRBUc2NpiLrFrOB z2dTS)IM}S&u7{ITOTU@r);ng#6d07AB9ddn^sB}Ir=)DP14+GvhOcF!?ZD_wYi1`r z58*$1Da)~}%viX7`z7@UY5z*KCo2?8T|;Ra{<vpWk&@E+Uqd~|atnKOdG`{dr}g1^ zMOW!pVY5kGfyOMp#u@Yj{K(%$xCFlh$-wzCkl|7=28LN0`9UsFI-?qgB`Q~W{n?t@ zcJs@<6TQmI>mD_>N}~muw;Ayp19ura?X=*E4>xq<ud1Tm$pAEU+WpshfwG!FxCA&! z1)jHQnvOLxFL*g=DEnW?`vA23|GJ#x?EFS})b5XW<xm5r@Hk3x>W~syQ~!Sh99kd` literal 0 HcmV?d00001 diff --git a/doc/GettingStarted.html b/doc/GettingStarted.html new file mode 100644 index 0000000..8e5cca3 --- /dev/null +++ b/doc/GettingStarted.html @@ -0,0 +1,1259 @@ +<!DOCTYPE html + PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html><head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <!-- +This HTML was auto-generated from MATLAB code. +To make changes, update the MATLAB code and republish this document. + --><title>Getting Started + +
+

Getting Started

+

Contents

+ +

Before using the library

+

You'll need a token to access all the web services.

+
+

How to get a token?

+
    +
  1. Register for an Oceans 3.0 account at https://data.oceannetworks.ca/Registration.
  2. +
  3. Log into your account at https://data.oceannetworks.ca by clicking the Log In link.
  4. +
  5. Click the Profile link (top right corner) to access your account profile.
  6. +
  7. Access the Web Services API tab and click Copy Token.
  8. +
  9. If you forget your token, you can always find it in your Oceans 3.0 account profile.
  10. +
+
+

Then, use the token to create an Onc object like

+
    +
  • Directly, run +
    onc = Onc('YOUR TOKEN HERE');
    +
  • +
  • Save the token in a file named 'TOKEN' and run +
    onc = Onc(readToken);
    +
  • +
  • with other parameters like output path +
    onc = Onc(readToken, 'outPath', 'YOUR_DESTINATION_FOLDER');
    +
  • +
+

For more information about creating an Onc object, see ONC Class

+ +
+

Note

+
    +
  • It's important to check that you are using the latest version. Outdated version may results in bugs.
  • +
  • When you run Onc() to create an Onc object, it will run a version check and prints out version outdated warning if fails. How to update to latest version.
  • +
+
+ +

General Tutorial - 1. Searching with discovery services

+

Check sections in the left panel for full documentation, source code and examples on each service.

+

To download data from Ocean Networks Canada's database (Oceans 3.0) , you need to specify the type of data you are interested in + and where in particular (i.e. location, from specific instrument (device)) it originates from. + In the Oceans 3.0 API, there are a unique codes that identify every location, device, property, data product type, etc. + You include these codes in a group of filters to retrieve the information you're interested in. + The Oceans 3.0 API Discovery services allow you to explore the hierarchy of ONC's database to obtain the codes required for your filters + to obtain the information/data you are interested in (they work like a "search" function). +

+

The example below uses the getLocations method, which is querying the locations database tables that include "Bullseye" in + their name (i.e. "Clayoquot Slope Bullseye Vent"). It returns a list with all locations that match the search filters provided.

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationName', 'Bullseye'};
+% 2. Call methods in the onc library
+onc.getLocations(params)
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params.locationName = 'Bullseye';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+
+% 2. Prepare HTTP request
+request = matlab.net.http.RequestMessage;
+url = 'https://data.oceannetworks.ca/api/locations';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params)
+
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+
+% send request
+response = request.send(uri,options);
+response.Body.Data
+
+
+    ans = struct with fields:
+            deployments: 38
+           locationName: 'Bullseye'
+                  depth: 1.2569e+03
+                   bbox: [1x1 struct]
+            description: ' Bullseye is a location at Clayoquot Slope, where gas hydrates, seafloor cold seeps, and hydrate dynamics are observed.'
+          hasDeviceData: 1
+                    lon: -126.8480
+           locationCode: 'NC89'
+        hasPropertyData: 0
+                    lat: 48.6706
+          dataSearchURL: 'https://data.oceannetworks.ca/DataSearch?location=NC89'
+
+

Each entry of this list contains more meta data information for that location, e.g. the locationName, the geographical coordinates and depth, + a description field and the URL for Oceans 3.0 Data Search tool. The parameter locationCode contains the string "NC89", which is needed for the next steps.

+

1.1 What device categories are available here at the location NC89?

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationCode', 'NC89'};
+% 2. Call methods in the onc library
+onc.getDeviceCategories(params)
+ +

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params.locationCode = 'NC89';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+    
+% 2. Prepare HTTP request
+request = matlab.net.http.RequestMessage;
+url = 'https://data.oceannetworks.ca/api/deviceCategories';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params)
+    
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% send request
+response = request.send(uri,options);
+response.Body.Data
+
+
ans = 13×1 struct 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Fields + + cvTerm + + description + + deviceCategoryCode + + deviceCategoryName + + hasDeviceData + + longDescription +
+ 1 + + 1×1 struct + + 'Acoustic Doppler Current Profiler 55 kHz ' + + 'ADCP55KHZ' + + 'Acoustic Doppler Current Profiler 55 kHz' + + 1 + + ' Acoustic Doppler Current Profilers are hydroacoustic instruments, similar to sonars. ADCPs measure current speed and direction at multiple predetermined depths simultaneously. ADCPs use the Doppler effect of sound waves that are scattered by particles in seawater over a depth range.' +
+ 2 + + 1×1 struct + + 'Acoustic Doppler Current Profiler 75 kHz ' + + 'ADCP75KHZ' + + 'Acoustic Doppler Current Profiler 75 kHz' + + 1 + ' Acoustic Doppler Current Profilers (ADCP) are hydroacoustic instruments, similar to sonars. ADCPs measure current speed and direction at multiple predetermined depths simultaneously. ADCPs use the Doppler effect of sound waves that are scattered by particles in seawater over a depth range.'
31×1 struct'Broadband Seismometer''BBS''Broadband Seismometer'1' Broadband Seismometers measure seismic waves over a broad frequency range depending on the device (e.g. 0.00278 Hz - 250 Hz). A broadband seismometer facilitates measurement of seismic events in the widest frequency band possible.'
41×1 struct'Bottom Pressure Recorder''BPR''Bottom Pressure Recorder'1' Bottom Pressure Recorders (BPR) are instruments that can detect small changes in pressure on the seafloor. '
51×1 struct'Controlled Source Electromagnetic Method''CSEM''Controlled Source Electromagnetic Method'1' The Controlled Source Electromagnetic Method (CSEM) measures sub-surface resistivity structure through the measurement of the electromegnetic fields resulting from stimulation by a towed source.'
61×1 struct'Conductivity Temperature (and Depth Sensor)''CTD''Conductivity Temperature Depth'1' Conductivity Temperature Depth (CTD) is an instrument package that contains sensors for measuring the conductivity, temperature, and pressure of seawater. Salinity, sound velocity, depth and density are variables that can be derived from sensor measurements. CTDs can carry additional instruments and sensors such as oxygen sensors, turbidity sensors and fluorometers.'
71×1 struct'Current Meter''CURRENTMETER''Current Meter'1' Acoustic Current Meters (ACM) measure current speed and direction, using the Doppler Effect. Aquadopp current meters have a sensor head that contains 3 acoustic transducers, a tilt sensor, a temperature sensor and a pressure sensor. The instrument transmits a short pulse of sound, and then listens to its echo to measure the change in pitch or frequency. The change in pitch can determine the velocity of the current.'
81×1 struct'Gravimeter''GRAVIMETER''Gravimeter'1' Gravimeters (or gravity meters) measure the gravity field of the Earth with such a resolution that they can detect very small changes in the underlying or surrounding structures.'
91×1 struct'Junction Box''JB''Junction Box'1' Junction Boxes supply power and communications to deployed instruments. Junction boxes have a number of serial and ethernet ports, including 400V ethernet ports that enable connections to other junction boxes and high-voltage instruments. Junction boxes can convert high voltages to lower voltages (15V, 24V or 48V) required by many instruments.'
101×1 struct'Oxygen Sensor''OXYSENSOR''Oxygen Sensor'1' Oxygen sensors measure dissolved oxygen concentration in seawater.'
111×1 struct'Pan Tilt Lights''PTL''Pan Tilt Lights'1' Pan Tilt Lights are used for cameras and allow remotely controlled operations such as changing the camera's field of view and illuminating the subject matter.'
121×1 struct'Tiltmeter''TILTMTR''Tiltmeter'1' A tiltmeter is a sensitive inclinometer designed to measure very small changes from the vertical level, either on the ground or in structures.'
131×1 struct'Video Camera''VIDEOCAM''Video Camera'1' Video cameras record video of characteristics of the surrounding environments and can be deployed on fixed and mobile platforms.'
+
+

1.2 What properties are available for the device category CTD at this location NC89?

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationCode', 'NC89', ...
+          'deviceCategoryCode', 'CTD'};
+% 2. Call methods in the onc library
+onc.getProperties(params)
+
+ +

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params.locationCode = 'NC89';
+params.deviceCategoryCode = 'CTD';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+    
+% 2. Prepare HTTP request
+request = matlab.net.http.RequestMessage;
+url = 'https://data.oceannetworks.ca/api/properties';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params)
+    
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% send request
+response = request.send(uri,options);
+response.Body.Data
+
+
ans = 8×1 struct 
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldscvTermdescriptionhasDeviceDatahasPropertyDatapropertyCodepropertyNameuom
11×1 struct'Conductivity: siemens per metre'11'conductivity''Conductivity''S/m'
21×1 struct'Density'11'density''Density''kg/m3'
31×1 struct'Pressure'11'pressure''Pressure''decibar'
41×1 struct'Salinity'11'salinity''Salinity''psu'
51×1 struct'Temperature: sea water'11'seawatertemperature''Sea Water Temperature''C'
61×1 struct'Sigma-t'11'sigmat''Sigma-t''kg/m3'
71×1 struct'Sigma-theta'11'sigmatheta''Sigma-theta''kg/m3'
81×1 struct'Sound Speed: sound velocity sensor'11'soundspeed''Sound Speed''m/s'
+
+

1.3 What data product types are available for the device category CTD at this location NC89?

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationCode', 'NC89', ...
+          'deviceCategoryCode', 'CTD'};
+% 2. Call methods in the onc library
+onc.getDataProducts(params)
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params.locationCode = 'NC89';
+params.deviceCategoryCode = 'CTD';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+    
+% 2. Prepare HTTP request
+request = matlab.net.http.RequestMessage;
+url = 'https://data.oceannetworks.ca/api/dataProducts';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params)
+    
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% send request
+response = request.send(uri,options);
+response.Body.Data
+
+
ans = 9×1 struct 
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldsdataProductCodedataProductNamedataProductOptionsextensionhasDeviceDatahasPropertyDatahelpDocument
1'LF''Log File'3×1 struct'txt'10'https://wiki.oceannetworks.ca/display/DP/4'
2'MSQAQCR''Manual Scalar QAQC Results'2×1 struct'qaqc'10'https://wiki.oceannetworks.ca/display/DP/106'
3'SBCTDRF''Sea-Bird CTD Raw Files'[]'hex'10'https://wiki.oceannetworks.ca/display/DP/78'
4'TSSD''Time Series Scalar Data'8×1 struct'json'10'https://wiki.oceannetworks.ca/display/DP/1'
5'TSSD''Time Series Scalar Data'5×1 struct'csv'10'https://wiki.oceannetworks.ca/display/DP/1'
6'TSSD''Time Series Scalar Data'5×1 struct'mat'10'https://wiki.oceannetworks.ca/display/DP/1'
7'TSSD''Time Series Scalar Data'5×1 struct'txt'10'https://wiki.oceannetworks.ca/display/DP/1'
8'TSSP''Time Series Scalar Plot'5×1 struct'pdf'10'https://wiki.oceannetworks.ca/display/DP/2'
9'TSSP''Time Series Scalar Plot'4×1 struct'png'10'https://wiki.oceannetworks.ca/display/DP/2'
+
+ + +

General Tutorial - 2. Downloading data

+

Check sections in the left panel for full documentation, source code and examples on each service.

+

Once you determine the exact filters that identify the information you are interested in, there are different methods available to download data.

+
+
    +
  1. Near real-time scalar data sensor readings for a given timeframe
  2. +
  3. Near real-time raw data for a given timeframe
  4. +
  5. Download archived files containing raw data or processed data
  6. +
  7. Download data products that are also available via Oceans 3.0 Data Search Tool
  8. +
+
+

2.1 Near real-time scalar data download

+

In this example we want to download one minute of Pressure sensor data from a CTD at location "Bullseye" (locationCode: NC89)

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationCode', 'NC89', ...
+        'deviceCategoryCode', 'CTD', ...
+        'dateFrom', '2017-01-20T00:00:00.000Z', ...
+        'propertyCode', 'pressure', ...
+        'dateTo', '2017-01-20T00:01:00.000Z', ...
+         };
+
+% 2. Call methods in the onc library
+result = onc.getDirectByLocation(params);
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params.locationCode = 'NC89';
+params.deviceCategoryCode = 'CTD';
+params.dateFrom = '2017-01-20T00:00:00.000Z';
+params.propertyCode = 'pressure';
+params.dateTo = '2017-01-20T00:01:00.000Z';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+    
+% 2. Prepare HTTP request
+request = matlab.net.http.RequestMessage;
+url = 'https://data.oceannetworks.ca/api/scalardata/location';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params)
+    
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+
+% send request
+result = request.send(uri,options);
+
+
% 3. Return the field names of the query to get a sense what is contained in your returned message
+fieldnames(result)
+
ans = 6×1 cell
'citations'
'messages'
'next'
'parameters'
'queryUrl'
'sensorData'
+
% 4. Read the data from parameter "sensorData" - this is the data from your requested "Pressure" sensor
+struct2table(result.sensorData(1).data)
+
+
ans = 240×3 table 
+ + + + + + + + + + + + + + + + + + + + + + + +
 qaqcFlagssampleTimesvalues
11'2017-01-20T00:00:00.025Z'1.2707e+03
21'2017-01-20T00:00:00.275Z'1.2707e+03
31'2017-01-20T00:00:00.525Z'1.2707e+03
41'2017-01-20T00:00:00.775Z'1.2707e+03
51'2017-01-20T00:00:01.025Z'1.2707e+03
61'2017-01-20T00:00:01.275Z'1.2707e+03
71'2017-01-20T00:00:01.525Z'1.2707e+03
81'2017-01-20T00:00:01.775Z'1.2707e+03
91'2017-01-20T00:00:02.025Z'1.2707e+03
101'2017-01-20T00:00:24.775Z'1.2707e+03
â‹®
+

2.2 Near real-time raw data readings

+

In this example we want to download one minute of raw data from a CTD at location "Bullseye" (locationCode: NC89)

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationCode', 'NC89', ...
+    'deviceCategoryCode', 'CTD', ...
+    'dateFrom', '2020-06-20T00:00:00.000Z', ...
+    'dateTo', '2020-06-20T00:01:00.000Z', ...
+   };
+% 2. Call methods in the onc library
+result = onc.getDirectRawByLocation(params);
+
+ +

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params.locationCode = 'NC89';
+params.deviceCategoryCode = 'CTD';
+params.dateFrom = '2020-06-20T00:00:00.000Z';
+params.dateTo = '2020-06-20T00:01:00.000Z';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+    
+% 2. Prepare HTTP request
+request = matlab.net.http.RequestMessage;
+url = 'http://data.oceannetworks.ca/api/rawdata/location';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params)
+    
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% send request
+result = request.send(uri,options);
+
+
% 3. Return the dictionary keys (fields) of the query to get a sense what is contained in your returned message
+fieldnames(result)
+
ans = 7×1 cell
'citations'
'data'
'messages'
'metadata'
'next'
'outputFormat'
'queryUrl'
+
% 4. Read the data as a table
+struct2table(result.data)
+
+
ans = 60×3 table 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 lineTypesreadingstimes
1' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16666</c1><p1>1269.229</p1><ser1><type>sbe63</type><oxph>38.099</oxph><oxtv>1.089869</oxtv></ser1><sal> 34.4819</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:00.843Z'
2' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16666</c1><p1>1269.223</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089873</oxtv></ser1><sal> 34.4821</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:01.842Z'
3' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16667</c1><p1>1269.217</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089870</oxtv></ser1><sal> 34.4820</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:02.840Z'
4' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8524</t1><c1> 3.16667</c1><p1>1269.223</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089870</oxtv></ser1><sal> 34.4820</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:03.838Z'
5' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8525</t1><c1> 3.16669</c1><p1>1269.216</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089874</oxtv></ser1><sal> 34.4822</sal><sv>1482.012</sv></data></datapacket>''2020-06-20T00:00:04.837Z'
6' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8526</t1><c1> 3.16670</c1><p1>1269.225</p1><ser1><type>sbe63</type><oxph>38.097</oxph><oxtv>1.089869</oxtv></ser1><sal> 34.4822</sal><sv>1482.013</sv></data></datapacket>''2020-06-20T00:00:05.837Z'
â‹®.........
+
+ +

2.2.1. Downloading more data

+
+

Pagination of response due to too many data rows

+

If the row of the data is above 100,000, not all the data will be returned. The rest of the data can be queried based on the next key in the response.

+
    +
  1. If you use onc library.

    getDirectRawByLocation supports a boolean allPages parameter. When set to True, it will try to retrieve all the pages.

  2. +
  3. If you use MATLAB's HTTP library.

    You have to manually query the next pages until the next key in the response json is None, and concatenate all the data together.

  4. +
+
+

Using ONC library

+
% 1. Define your filter parameter with a longer date range (2 days of data)
+paramsLongerRange = {'locationCode', 'NC89', ...
+    'deviceCategoryCode', 'CTD', ...
+    'dateFrom', '2020-06-20T00:00:00.000Z', ...
+    'dateTo', '2020-06-22T00:00:00.000Z', ...
+   };
+% 2. Call methods in the onc library
+result = onc.getDirectRawByLocation(paramsLongerRange, 'allPages', true)
+struct2table(result.data)
+
+
+    
Data size is greater than the row limit and will be downloaded in multiple pages. + Estimated approx. 1 pages + Estimated approx. 5.79 seconds to complete + + (100000 samples) Downloading page 2... + (172796 samples) Completed in 2.25 seconds.
+
result = struct with fields:
citations: [1×1 struct] + data: [1×1 struct] + messages: [] + metadata: [1×1 struct] + next: [] + outputFormat: 'array' + queryUrl: 'https://data.oceannetworks.ca/api/rawdata?locationCode=NC89&deviceCategoryCode=CTD&dateFrom=2020-06-20T00:00:00.000Z&dateTo=2020-06-22T00:00:00.000Z&method=getByLocation&token=YOUR_TOKEN' +
+
+
ans = 172796×3 table 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 lineTypesreadingstimes
1' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16666</c1><p1>1269.229</p1><ser1><type>sbe63</type><oxph>38.099</oxph><oxtv>1.089869</oxtv></ser1><sal> 34.4819</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:00.843Z'
2' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16666</c1><p1>1269.223</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089873</oxtv></ser1><sal> 34.4821</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:01.842Z'
3' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16667</c1><p1>1269.217</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089870</oxtv></ser1><sal> 34.4820</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:02.840Z'
4' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8524</t1><c1> 3.16667</c1><p1>1269.223</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089870</oxtv></ser1><sal> 34.4820</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:03.838Z'
5' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8525</t1><c1> 3.16669</c1><p1>1269.216</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089874</oxtv></ser1><sal> 34.4822</sal><sv>1482.012</sv></data></datapacket>''2020-06-20T00:00:04.837Z'
6' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8526</t1><c1> 3.16670</c1><p1>1269.225</p1><ser1><type>sbe63</type><oxph>38.097</oxph><oxtv>1.089869</oxtv></ser1><sal> 34.4822</sal><sv>1482.013</sv></data></datapacket>''2020-06-20T00:00:05.837Z'
7' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8528</t1><c1> 3.16670</c1><p1>1269.229</p1><ser1><type>sbe63</type><oxph>38.098</oxph><oxtv>1.089862</oxtv></ser1><sal> 34.4820</sal><sv>1482.013</sv></data></datapacket>''2020-06-20T00:00:06.838Z'
8' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8529</t1><c1> 3.16671</c1><p1>1269.226</p1><ser1><type>sbe63</type><oxph>38.098</oxph><oxtv>1.089857</oxtv></ser1><sal> 34.4820</sal><sv>1482.014</sv></data></datapacket>''2020-06-20T00:00:07.842Z'
9' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8530</t1><c1> 3.16672</c1><p1>1269.224</p1><ser1><type>sbe63</type><oxph>38.099</oxph><oxtv>1.089849</oxtv></ser1><sal> 34.4819</sal><sv>1482.014</sv></data></datapacket>''2020-06-20T00:00:08.837Z'
â‹®
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+paramsLongerRange.locationCode = 'NC89';
+paramsLongerRange.deviceCategoryCode = 'CTD';
+paramsLongerRange.dateFrom = '2020-06-20T00:00:00.000Z';
+paramsLongerRange.dateTo = '2020-06-22T00:00:00.000Z';
+paramsLongerRange.token = 'YOUR TOKEN HERE'; % or readToken
+    
+% 2. Prepare HTTP request (the url is still the same)
+request = matlab.net.http.RequestMessage;
+url = 'http://data.oceannetworks.ca/api/rawdata/location';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(paramsLongerRange);
+    
+% prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% send request
+result = request.send(uri,options);
+
+ +
% 4. Read the data as a table
+struct2table(result.Body.Data.data) 
+
+
ans = 100000×3 table 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 lineTypesreadingstimes
1' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16666</c1><p1>1269.229</p1><ser1><type>sbe63</type><oxph>38.099</oxph><oxtv>1.089869</oxtv></ser1><sal> 34.4819</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:00.843Z'
2' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16666</c1><p1>1269.223</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089873</oxtv></ser1><sal> 34.4821</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:01.842Z'
3' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8523</t1><c1> 3.16667</c1><p1>1269.217</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089870</oxtv></ser1><sal> 34.4820</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:02.840Z'
4' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8524</t1><c1> 3.16667</c1><p1>1269.223</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089870</oxtv></ser1><sal> 34.4820</sal><sv>1482.011</sv></data></datapacket>''2020-06-20T00:00:03.838Z'
5' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8525</t1><c1> 3.16669</c1><p1>1269.216</p1><ser1><type>sbe63</type><oxph>38.096</oxph><oxtv>1.089874</oxtv></ser1><sal> 34.4822</sal><sv>1482.012</sv></data></datapacket>''2020-06-20T00:00:04.837Z'
6' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8526</t1><c1> 3.16670</c1><p1>1269.225</p1><ser1><type>sbe63</type><oxph>38.097</oxph><oxtv>1.089869</oxtv></ser1><sal> 34.4822</sal><sv>1482.013</sv></data></datapacket>''2020-06-20T00:00:05.837Z'
7' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8528</t1><c1> 3.16670</c1><p1>1269.229</p1><ser1><type>sbe63</type><oxph>38.098</oxph><oxtv>1.089862</oxtv></ser1><sal> 34.4820</sal><sv>1482.013</sv></data></datapacket>''2020-06-20T00:00:06.838Z'
8' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8529</t1><c1> 3.16671</c1><p1>1269.226</p1><ser1><type>sbe63</type><oxph>38.098</oxph><oxtv>1.089857</oxtv></ser1><sal> 34.4820</sal><sv>1482.014</sv></data></datapacket>''2020-06-20T00:00:07.842Z'
9' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8530</t1><c1> 3.16672</c1><p1>1269.224</p1><ser1><type>sbe63</type><oxph>38.099</oxph><oxtv>1.089849</oxtv></ser1><sal> 34.4819</sal><sv>1482.014</sv></data></datapacket>''2020-06-20T00:00:08.837Z'
â‹®
+
+

Now check the parameter field "next"

+
+result.Body.Data.next
+result.Body.Data.next.parameters
+
+
ans = struct with fields:
parameters: [1×1 struct] + url: 'https://data.oceannetworks.ca/api/rawdata/location?dateTo=2020-06-22T00%3A00%3A00.000Z&locationCode=NC89&deviceCategoryCode=CTD&dateFrom=2020-06-21T03%3A46%3A42.044Z&token=YOUR_TOKEN' +
+ans = struct with fields:
dateTo: '2020-06-22T00:00:00.000Z' + locationCode: 'NC89' + deviceCategoryCode: 'CTD' + dateFrom: '2020-06-21T03:46:42.044Z' + token: 'YOUR_TOKEN' +
+
+

Update the dateFrom parameter to get the next page

+
+paramsLongerRange.dateFrom = result.Body.Data.next.parameters.dateFrom;
+uri.Query = matlab.net.QueryParameter(paramsLongerRange);
+result = request.send(uri,options);
+struct2table(result.Body.Data.data)
+
+
ans = 72796×3 table 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 lineTypesreadingstimes
1' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8635</t1><c1> 3.16756</c1><p1>1269.622</p1><ser1><type>sbe63</type><oxph>38.117</oxph><oxtv>1.089511</oxtv></ser1><sal> 34.4807</sal><sv>1482.064</sv></data></datapacket>''2020-06-21T03:46:43.045Z'
2' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8636</t1><c1> 3.16755</c1><p1>1269.626</p1><ser1><type>sbe63</type><oxph>38.124</oxph><oxtv>1.089509</oxtv></ser1><sal> 34.4806</sal><sv>1482.064</sv></data></datapacket>''2020-06-21T03:46:44.044Z'
3' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16757</c1><p1>1269.629</p1><ser1><type>sbe63</type><oxph>38.125</oxph><oxtv>1.089508</oxtv></ser1><sal> 34.4807</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:45.043Z'
4' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16758</c1><p1>1269.626</p1><ser1><type>sbe63</type><oxph>38.123</oxph><oxtv>1.089506</oxtv></ser1><sal> 34.4808</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:46.043Z'
5' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16758</c1><p1>1269.629</p1><ser1><type>sbe63</type><oxph>38.122</oxph><oxtv>1.089506</oxtv></ser1><sal> 34.4808</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:47.047Z'
6' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16758</c1><p1>1269.620</p1><ser1><type>sbe63</type><oxph>38.123</oxph><oxtv>1.089511</oxtv></ser1><sal> 34.4809</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:48.048Z'
7' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16757</c1><p1>1269.624</p1><ser1><type>sbe63</type><oxph>38.123</oxph><oxtv>1.089504</oxtv></ser1><sal> 34.4807</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:49.044Z'
8' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16758</c1><p1>1269.630</p1><ser1><type>sbe63</type><oxph>38.121</oxph><oxtv>1.089502</oxtv></ser1><sal> 34.4807</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:50.058Z'
9' ''<?xml version="1.0"?><datapacket><hdr><mfg>Sea-Bird</mfg><model>19plus</model><sn>01907035</sn></hdr><data><t1>  2.8637</t1><c1> 3.16756</c1><p1>1269.632</p1><ser1><type>sbe63</type><oxph>38.120</oxph><oxtv>1.089501</oxtv></ser1><sal> 34.4806</sal><sv>1482.065</sv></data></datapacket>''2020-06-21T03:46:51.042Z'
â‹®
+
+

Now check the parameter field "next" again

+
+result.Body.Data.next
+
+
ans =
+
+    []
+
+

2.3. Downloading archived files

+

A faster way to download data products and processed data files that are available in Oceans 3.0 (if it suits your needs) is to leverage how ONC scripts +auto-generate and archive data products of different types at set time intervals. You can directly download these data product files from our files archive, as long as you know their unique filename.

+

In the following example, we get the list of archived files available for a camera (deviceCategoryCode: VIDEOCAM) at Ridley Island (locationCode: RISS) for 5-minute timerange.

+

Using ONC library

+
% 1. Define your filter parameter
+params = {'locationCode', 'RISS', ...
+    'deviceCategoryCode', 'VIDEOCAM', ...
+    'dateFrom', '2016-12-01T00:00:00.000Z', ...
+    'dateTo', '2016-12-01T00:05:00.000Z', ...
+    };
+% 2. Call methods in the onc library
+result = onc.getListByLocation(params);
+result.files
+
+
ans = 4×1 cell
+
'AXISQ6044PTZACCC8E334C53_20161201T000000.000Z.mp4'
'AXISQ6044PTZACCC8E334C53_20161201T000000.000Z.an'
'AXISQ6044PTZACCC8E334C53_20161201T000000.000Z-VideoQAQCResults.an'
'AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg'
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter
+params = struct();
+params.locationCode = 'RISS';
+params.deviceCategoryCode = 'VIDEOCAM';
+params.dateFrom = '2016-12-01T00:00:00.000Z';
+params.dateTo = '2016-12-01T00:05:00.000Z';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+        
+% 2. Prepare HTTP request (the url is still the same)
+request = matlab.net.http.RequestMessage;
+url = 'https://data.oceannetworks.ca/api/archivefile/location';
+uri = matlab.net.URI(url);
+uri.Query = matlab.net.QueryParameter(params);
+        
+% 3. prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+        
+% 4. send request
+result = request.send(uri,options);
+result.Body.Data.files
+
+
ans = 4×1 cell
'AXISQ6044PTZACCC8E334C53_20161201T000000.000Z.mp4'
'AXISQ6044PTZACCC8E334C53_20161201T000000.000Z.an'
'AXISQ6044PTZACCC8E334C53_20161201T000000.000Z-VideoQAQCResults.an'
'AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg'
+
+

Once we have the file names, you can use the method "getFile()" to download individual files:

+

Using ONC library

+
% 1. Call methods in the onc library with the filename. The file is downloaded in the output folder.
+onc.getFile('AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg', 'overwrite', true)
+
+
Downloading file "AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg"... + [==================================================] 100% + File was downloaded to "AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg"
+ans = struct with fields:
url: 'https://data.oceannetworks.ca/api/archivefiles?method=getFile&filename=AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg&token=YOUR_TOKEN' + status: 'completed' + size: 113511 + downloadTime: 0.8380 + file: "AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg" +
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter with the filename
+params.filename = 'AXISQ6044PTZACCC8E334C53_20161201T000001.000Z.jpg';
+params.token = 'YOUR TOKEN HERE'; % or readToken
+% 2. Define your base url for this query
+url_location = 'https://data.oceannetworks.ca/api/archivefile/download';
+request = matlab.net.http.RequestMessage;
+uri = matlab.net.URI(url_location);
+uri.Query = matlab.net.QueryParameter(params);
+    
+% 3. prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% 4. send request
+result = request.send(uri,options);
+% 5. Save the file
+% f = fopen(fullPath, 'w','n','ISO-8859-1');
+% if f ~= -1
+%     fwrite(f, char(dataToWrite));
+% end
+
+

2.4 Downloading data products

+

Other than using Oceans 3.0 Data Search, we can request the ONC server to generate a data product. This is done through the data product delivery services methods.

+
+

Hint

+

This service should ONLY be used when the requested files are not already provided using the ArchiveFiles services (see 2.3 above). + The data product delivery services will re-generate files using ONC's web machines and this process can often take very long time to generate these results. + If you request data files for very long-time ranges and large file sizes, ONCs system will sometimes slow down and stall and requires some manual actions.

+

We therefore encourage you to check other services before requesting data through this service. If you are unsure what to use feel free to contact u.

+
+

This process will require three steps before you will be able to see the downloaded data product on your computer:

+
+
    +
  1. Request the data.
  2. +
  3. Run the Request.
  4. +
  5. Download the data.
  6. +
+
+

The following example downloads two PNG files with plots for 30 minutes of data from a CTD (find them in the "output" folder beside this jupyter notebook). + The filter includes codes for location, deviceCategory, and dataProduct, as well as the file extension and a time interval. + They also include a couple of filters to configure this specific data product type (starting with the "dpo_" prefix) which can be obtained from the Data Product Options documentation. You can download more than 120 different types of data products including audio & video.

+

Using ONC library

+

ONCs library contains all three steps (methods) in one call. So this is the preferred library to use over the requests library.

+
% 1. Define your filter parameter
+params = {'locationCode', 'NC89', ...
+    'deviceCategoryCode', 'CTD', ...
+    'dataProductCode', 'TSSP', ...
+    'extension', 'png', ...
+    'dateFrom', '2017-01-19T00:00:00.000Z', ...
+    'dateTo', '2017-01-19T00:30:00.000Z', ...
+    'dpo_qualityControl', '1', ...
+    'dpo_resample', 'none', ...
+    };
+% 2. Call methods in the onc library
+result = onc.orderDataProduct(params)
+
+
Requesting data product... +Request Id: 18690549 +Estimated File Size: 185 kB +Estimated Processing Time: 20 s + +To cancel this data product, visit url: + https://data.oceannetworks.ca/api/dataProductDelivery?method=cancel&token=YOUR_TOKEN&dpRequestId=18690549 + + queued + data product running....... + complete + +Downloading data product files with runId 40531301... + + Search complete, waiting on the file system to synchronize (ClayoquotSlope_Bullseye_ConductivityTemperatureDepth_20170119T000000Z_20170119T003000Z-clean.png).... + Downloaded "ClayoquotSlope_Bullseye_ConductivityTemperatureDepth_20170119T000000Z_20170119T003000Z-clean.png" + + Downloaded "ClayoquotSlope_Bullseye_ConductivityTemperatureDepth_20170119T000000Z_20170119T003000Z-clean_PNG_META.xml" + +Download process finished. + + +Total run time: 0.17 seconds +Total download Time: 0.688 seconds +2 files (124.37 KB) downloaded
+
result = struct with fields:
downloadResults: [1×2 struct] + stats: [1×1 struct] +
+
% display results
+downloadResults1 = result.downloadResults(1)
+downloadResults2 = result.downloadResults(2)
+stats = result.stats
+
+
+
downloadResults1 = struct with fields: +
url: 'https://data.oceannetworks.ca/api/dataProductDelivery?method=download&token=YOUR_TOKEN&dpRunId=40531301&index=1' + status: 'complete' + statusCode: OK + size: 111106 + file: 'ClayoquotSlope_Bullseye_ConductivityTemperatureDepth_20170119T000000Z_20170119T003000Z-clean.png' + index: '1' + downloaded: 1 + requestCount: 6 +fileDownloadTime: 0.3850 +
+
+downloadResults2 = struct with fields:
url: 'https://data.oceannetworks.ca/api/dataProductDelivery?method=download&token=YOUR_TOKEN&dpRunId=40531301&index=meta' + status: 'complete' + statusCode: OK + size: 13264 + file: 'ClayoquotSlope_Bullseye_ConductivityTemperatureDepth_20170119T000000Z_20170119T003000Z-clean_PNG_META.xml' + index: 'meta' + downloaded: 1 + requestCount: 1 +fileDownloadTime: 0.3030 +
+
+
stats = struct with fields: +
+
runTime: 0.1710 + downloadTime: 0.6880 + requestCount: 17 + totalSize: 124370 +
+
+

Using MATLAB's HTTP library

+
% 1. Define your filter parameter with the filename
+params = struct();
+params.locationCode = 'NC89';
+params.deviceCategoryCode = 'CTD';
+params.dataProductCode = 'TSSP';
+params.extension = 'png';
+params.dateFrom = '2017-01-19T00:00:00.000Z';
+params.dateTo = '2017-01-19T00:30:00.000Z';
+params.dpo_qualityControl = '1';
+params.dpo_resample = 'none';
+params.token = readToken; 
+% 2. Define your base url for this query
+url_location = 'https://data.oceannetworks.ca/api/dataProductDelivery/request';
+request = matlab.net.http.RequestMessage;
+uri = matlab.net.URI(url_location);
+uri.Query = matlab.net.QueryParameter(params);
+    
+% 3. prepare MATLAB request options
+options = matlab.net.http.HTTPOptions();
+options.ConnectTimeout = 120;
+    
+% 4. send request
+requestResponse = request.send(uri,options);
+result = requestResponse.Body.Data
+
+
+
result = struct with fields:
citations: [1×1 struct] + disclaimer: 'Software Developers are implementing estimates of processing times and file sizes for data requests. These are extremely rough to begin with, but bear with us. We expect these estimates will gradually improve.' + dpRequestId: 18690550 + estimatedFileSize: '185 kB' +estimatedProcessingTime: '20 s' + messages: [] + queryPids: 25848930 + queryURL: 'https://data.oceannetworks.ca/api/dataProductDelivery/request?locationCode=NC89&deviceCategoryCode=CTD&dataProductCode=TSSP&extension=png&dateFrom=2017-01-19T00:00:00.000Z&dateTo=2017-01-19T00:30:00.000Z&token=YOUR_TOKEN&dpo_resample=none&dpo_resample=none&dpo_qualityControl=1' +
+
+
+%% requests continued
+% Run the request
+% Note: you have to execute this cell multiple times until the return shows the "status": "complete"
+% Note: Depending on your request, you can have more than one file ('fileCount').
+%       You will need to individually download these files by using the index parameter.
+url_run = 'https://data.oceannetworks.ca/api/dataProductDelivery/run';
+
+requestID = requestResponse.Body.Data.dpRequestId;
+params_run = struct();
+params_run.dpRequestId = requestID;
+params_run.token = readToken; 
+ 
+request = matlab.net.http.RequestMessage;
+uri = matlab.net.URI(url_run);
+uri.Query = matlab.net.QueryParameter(params_run);
+runResponse = request.send(uri,options);
+result = runResponse.Body.Data
+
+
result = struct with fields:
dpRunId: 40531302 + fileCount: 0 + status: 'queued' +
+
+
%% requests continued
+% Find the RunID for the next step
+runId = response(1).dpRunId
+
+
runId = 40531302
+
+
%% requests continued
+% 3. Download the data
+url_download = 'https://data.oceannetworks.ca/api/dataProductDelivery/download';
+params_download = struct();
+params_download.dpRunId = runId;
+params_download.token = readToken;
+params_download.index = '1';
+request = matlab.net.http.RequestMessage;
+uri = matlab.net.URI(url_download);
+uri.Query = matlab.net.QueryParameter(params_download);
+ 
+% Start - Rerun this part until the response code is 200.
+downloadResponse = request.send(uri,options);
+result = downloadResponse.Body.Data
+responseCode = double(downloadResponse.StatusCode)
+% End - Rerun this part until the response code is 200.
+ 
+% %downloadResponse.Headers has field Content-Disposition, 
+% %and Content-Disposition has the format "attachement; filename=XXX.png"
+% contentDisposition = char(downloadResponse.Header.getFields('Content-Disposition').Value);
+% filename = contentDisposition(23:end);
+% imwrite(downloadResponse.Body.Data, filename);
+% %Use other download functions if content type is not png/jpg
+
+
result = struct with fields:
message: 'Running' + status: 'running' +
+
responseCode = 202
+
+
+

Another option to get the data

+

Obtain your downloads from your user FTP directory (More -> User Directory) in Oceans 3.0. Navigate to the folder that contains the runId: You will see the files in this folder.

+ +
+
+ + diff --git a/doc/Index.html b/doc/Index.html new file mode 100644 index 0000000..8a11bfd --- /dev/null +++ b/doc/Index.html @@ -0,0 +1,158 @@ + + + + Overall Info +
+

Ocean Networks Canada API Client Library

+

This library serves as a toolbox to access ONC Web Services which allows users to discover and retrieve Ocean Networks Canada's 12+ years of oceanographic data in raw, text, image, audio, video or any other format available. This codebase provides a class that wraps web service calls, complex workflows, and business logic so that users can download data with a single line of code.

+

Check left panel for more documentation and code examples. You can also find code examples under Examples section from here

+

Introduction to ONC Web Services/API

+

What are ONC Web Services?

+

A group of public web services that can be used to explore and download ONC data.

+

Documentation pages

+

https://wiki.oceannetworks.ca/display/O2A/Oceans+3.0+API+Home

+

https://data.oceannetworks.ca/OpenAPI

+

Tutorial Page

+

Web API Tutorial

+

Oceans 3.0 API overview

+

Check here for more information.

+

Glossary of terms

+

Check here for more information.

+

Main documentation

+

Check left panel to select and view documentation of each service and function.

+
+ diff --git a/doc/Onc.html b/doc/Onc.html index 7ce17c8..a0d6a6f 100644 --- a/doc/Onc.html +++ b/doc/Onc.html @@ -84,11 +84,12 @@

The ONC class

* timeout (int, optional, default = 60) - Number of seconds before a request to the API is canceled

Returns: The Onc object created.

-

Examples:

+

Examples:

 onc = ONC("YOUR_TOKEN_HERE", 'showInfo', true, 'outPath', 'myOutPath');
 
-

For detailed information and usage examples, run doc command or visit MATLAB's help browser https://data.oceannetworks.ca/Profile then find Ocean Networks Canada API Client under supplemental software

+

For detailed information and usage examples, run doc command or visit MATLAB's help browser https://www.mathworks.com/help/matlab/ then find Ocean Networks Canada API Client under supplemental software

+

Source code:

function this = Onc(token, varargin)
     p = inputParser;
     addRequired(p, 'token', @ischar);
diff --git a/doc/OncArchive.html b/doc/OncArchive.html
index 2a40b2d..e1edfb1 100644
--- a/doc/OncArchive.html
+++ b/doc/OncArchive.html
@@ -10,7 +10,7 @@
 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outine:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
 
 html { min-height:100%; margin-bottom:1px; }
-html body { height:100%; margin:0px; font-family:Arial, Helvetica, sans-serif; font-size:10px; color:#000; line-height:140%; background:#fff none; overflow-y:scroll; }
+html body { height:100%; margin:0px; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#000; line-height:140%; background:#fff none; overflow-y:scroll; }
 html body td { vertical-align:top; text-align:left; }
 
 h1 { padding:0px; margin:0px 0px 25px; font-family:Arial, Helvetica, sans-serif; font-size:2.0em; color:#d55000; line-height:100%; font-weight:bold; }
diff --git a/doc/OncDelivery.html b/doc/OncDelivery.html
index 70521da..77d8c04 100644
--- a/doc/OncDelivery.html
+++ b/doc/OncDelivery.html
@@ -128,7 +128,7 @@ 

OrderDataProduct(filters, maxRetries, downloadResultsOnly, ...)

  • array of structs - one named list for each file with information on the operation outcome

-

The API endpoint is /dataProductDelivery.

+

The API endpoint is /dataProductDelivery.

Parameters in filter: Query string parameters in the API request. Supported parameters are:

    * dataProductCode: char array   
     * extension: char array   
@@ -198,7 +198,7 @@ 

RequestDataProducts(filters, maxRetries, ...)

Output:

  • struct - Parsed http response

-

The API endpoint is /dataProductDelivery/request.

+

The API endpoint is /dataProductDelivery/request.

Parameters in filter: Query string parameters in the API request. Supported parameters are:

    * dataProductCode: char array   
     * extension: char array   
@@ -255,7 +255,7 @@ 

RunDataProduct(dpRequestId, waitComplete)

  • struct - information of the run process
  • -

    The API endpoint is /dataProductDelivery/run.

    +

    The API endpoint is /dataProductDelivery/run.

    Returns(struct): API response. Each struct returned contains following fields:

        * runIds: double   
         * fileCount: double   
    @@ -325,7 +325,7 @@ 

    CheckDataProduct(dpRequestId)

    Output:

    • response(struct) - status of this data product

    -

    The API endpoint is /dataProductDelivery/status.

    +

    The API endpoint is /dataProductDelivery/status.

    Returns(struct): API response. Each struct returned contains following fields:

        * description: char array   
         * modifyDate: char array   
    @@ -356,7 +356,7 @@ 

    CheckDataProduct(dpRequestId)

  • response(struct) - cancel process status and message
  • info(struct) - cancel process http code and status
  • -

    The API endpoint is /dataProductDelivery/cancel.

    +

    The API endpoint is /dataProductDelivery/cancel.

    Returns: API response. Each response(struct) returned contains following fields:

        * dpRunId: char array   
         * status: char array
    @@ -394,7 +394,7 @@

    DownloadDataProduct(runId, maxRetries, downloadResultsOnly, ...)

    • array of structs - (one struct for each downloaded file) with information on the operation outcome
    -

    The API endpoint is /dataProductDelivery/download.

    +

    The API endpoint is /dataProductDelivery/download.

    Returns: API response. Each response(struct) returned contains following fields:

        * url: char array   
         * status: char array   
    @@ -433,7 +433,7 @@ 

    DownloadDataProduct(runId, maxRetries, downloadResultsOnly, ...)

  • response(struct) - restart process status and message
  • info(struct) - restart process http code and status
  • -

    The API endpoint is /dataProductDelivery/restart.

    +

    The API endpoint is /dataProductDelivery/restart.

    Returns: API response. Each response(struct) returned contains following fields:

        * dpRunId: char array   
         * status: char array
    diff --git a/doc/UpdateInstruction.html b/doc/UpdateInstruction.html
    new file mode 100644
    index 0000000..50f3601
    --- /dev/null
    +++ b/doc/UpdateInstruction.html
    @@ -0,0 +1,151 @@
    +
    +
    +      
    +   How to update to latest version
    +
    +

    How to update to latest version

    +

    When using Ocean Networks Canada API Client Library, you may get a warning about outdated version. Follow the following instruction to update to latest version.

    +
    +

    Note

    +

    If you would like to download a specific version, visit Ocean Networks Canada API Client Library File Exchange - Version History and then download your preferred version.

    +
    +

    1. Select Manage Add-Ons under Add-Ons from the HOME menu.

    + +

    2. Select updates at the top, new releases of installed libraries will show below. Click update to the right of Ocean Networks Canada API Client Library.

    + +
    + diff --git a/doc/UserDirectory.png b/doc/UserDirectory.png new file mode 100644 index 0000000000000000000000000000000000000000..efb1033c6eca3b646c06b08e50a57a2db39e651b GIT binary patch literal 296590 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%0DL&u@LyJui;OpT~CHsrugN* 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≫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®4 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�GPO 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 literal 0 HcmV?d00001 diff --git a/doc/helptoc.xml b/doc/helptoc.xml index 383b159..6c8b939 100644 --- a/doc/helptoc.xml +++ b/doc/helptoc.xml @@ -3,7 +3,8 @@ - MyToolbox now + Ocean Networks Canada API Client Library + @@ -31,11 +32,24 @@ --> + How to use + Onc class + Discovery Service - + Delivery Service + + Archive Service + + + Near Real Time Service + + + + How to update to latest version + \ No newline at end of file diff --git a/doc/update.png b/doc/update.png new file mode 100644 index 0000000000000000000000000000000000000000..4d23447a51fc013d5dca4f6aa248c4ecce1e4213 GIT binary patch literal 89406 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ΜNXpM5o2I=41?yg- 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 Date: Thu, 13 Jun 2024 09:13:29 -0700 Subject: [PATCH 27/35] issue-20: add example files --- onc/examples/OncArchive.mlx | Bin 0 -> 6732 bytes onc/examples/OncDeliveryDataProducts.mlx | Bin 0 -> 5076 bytes onc/examples/OncDiscoveryDataProducts.mlx | Bin 0 -> 7719 bytes onc/examples/OncDiscoveryDeployments.mlx | Bin 0 -> 8539 bytes onc/examples/OncDiscoveryDeviceCategories.mlx | Bin 0 -> 9266 bytes onc/examples/OncDiscoveryDevices.mlx | Bin 0 -> 5867 bytes onc/examples/OncDiscoveryDocumentation.m | 48 ++++++++++++++++++ onc/examples/OncDiscoveryLocations.mlx | Bin 0 -> 12007 bytes onc/examples/OncDiscoveryProperties.mlx | Bin 0 -> 7100 bytes onc/examples/OncRealTime.mlx | Bin 0 -> 6718 bytes 10 files changed, 48 insertions(+) create mode 100644 onc/examples/OncArchive.mlx create mode 100644 onc/examples/OncDeliveryDataProducts.mlx create mode 100644 onc/examples/OncDiscoveryDataProducts.mlx create mode 100644 onc/examples/OncDiscoveryDeployments.mlx create mode 100644 onc/examples/OncDiscoveryDeviceCategories.mlx create mode 100644 onc/examples/OncDiscoveryDevices.mlx create mode 100644 onc/examples/OncDiscoveryDocumentation.m create mode 100644 onc/examples/OncDiscoveryLocations.mlx create mode 100644 onc/examples/OncDiscoveryProperties.mlx create mode 100644 onc/examples/OncRealTime.mlx diff --git a/onc/examples/OncArchive.mlx b/onc/examples/OncArchive.mlx new file mode 100644 index 0000000000000000000000000000000000000000..091ba102ac8ae4798f49773b678d864a5d3e6883 GIT binary patch literal 6732 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 literal 0 HcmV?d00001 diff --git a/onc/examples/OncDeliveryDataProducts.mlx b/onc/examples/OncDeliveryDataProducts.mlx new file mode 100644 index 0000000000000000000000000000000000000000..9b8ffe63f2811732d18a24903d9b58c0182edcb0 GIT binary patch literal 5076 zcma)=2T&9J*2Y7JfOJs0NN=HsD!nF@fJg@k5Fj+^MS2HCsvt$_NJo%2Nbe#|igb`7 zAgG~8@A$>JckUJEeeZmm*<`Y_=b7E#p8vDw92gV_ml^;75Mp*#z-;f`QgJK*pb7^7 zpu!w6Q-0{`g>dzHVBqhD@U#H=xj3UzKj?G|kw@+X0SAqqHMl7da%_dM#1X5M%66Iilc%-;QuI@e?*}E$J>lQXW_{x^aS z4Ag-qKZn(xiuH||xssE{Cz8UP9O#e53HsQ&vZn&=ZmBq;Hyn;+YRiLUSMhkZrC*Ww zt{|T|wh$FoR1u?RRM6lAr6ql+`?$GtK^O$50OyR>%ybdI`IS1cKRN4RQtJ~H)wM?|h$Z*K#h zGj>}gum&n2Hyro%F6`CO&pGEkd>DqZz<($=9!M{9V<1gC&qpfI{-)SB_RgKB>}C>k zl)A~_5|rmzj_{zb{E9VjUs>Ky-k z^+SscIq!-1(SH&Hu2z&WS$87QJkw@pPaqWFBD~AUI557{)axwe=%bd% zy{H8{@F%2&Hr}7sSbPd0U1rOwU=iaYJJN;rVqa+ycn%xaOsF1^UWXiMhixs32LSld z{7PkNfD7Eq8E!3T`_RVQ1(VUgQu*&-Z)Lc6&PkHLU)s3$Rd$>;lV~OhtclblaMloM z#pP@`p7mW9uP;L8vEm9J;;8m`Y@2h+g=)eZ_uq@=dttYZxJ&+mui_ z&7eZ0|0lAUpzf0upMj0uk|&9EO(U&HjSMBL5!;|Cpu=zVu%J(b3~WP zpKJ?&^hNZ~vKr0B)&eQ5g}?FfQ)dV>rbN5%pLa0LOleNmnla&k2!gx&%;Oe%(UYpr z{rgzO0Ich!x;@Iv6b5RfxxxdriHwy(--)($?{XZzydU@z)%-RyH-JiXSm@xpc6qFo zF-5j0Dn;bru|wI8(9;2CGPcTaxB`xN;-Q%J(oqIFX{Rp{c{|qmmalllqXe6m#jih> zsDQW;WRc%V+wB)EtRdceWqlxKCAt&B;@SbR)J;>-RVvG(^k%;AK3ja@-o9IcPJ4m^ z?t7YNIu^2V539J>??hU-8yu?(<*2KShH7``Z(^G&St#0kIPG_X+lXso~foR6>po@>p&fPu|`o|Y!Y#Y9LerS_{4cy z@mYWn-Lg`C8>M6e3!lXz6#D~<)kN?t_`$XiHS>KP~3U9DOT z4{A;IL9yJV{8u)|NxIhYwjxfQ!FHZWd8fBzzs+muXx_|5cOzcyJA-26a($@n9UMWPkwnC82WIP@b*kvp19$OEWV`*sm<+AyAbMvCjr3cT+5 zj9jW~O-Sm6^v}IXpDfpXGy|!OB~E9Xukl&k`4`g0g^?{YugNy2=LvFw=jqcFf}9jL zHC711Co+mC!>lB+BCFdHA?}hKUZwq=B|rs<2eqr*>&$>3?+_+s1@?23wXIF`RZ>aT zktNi5)ik>|H^?({l* zky-db?Tc^Yl5Dy2oKgn^-}1~s_*Gr~h)g_X;jNHJxc{TJ4wf-ei`t!dg0Z;5EOIcY$!y%nf?ws`1ys#L%}(BZtk-ST49}b1Mm6 z3XU$=5yx%LFVmgUolFi-UR#??J(!L`yT3)ZSt3uUJ5EIWcN*a2lb;3})^ zboNCDJ)2*_7_lqY_W9yKT^Gst6M$urz#uT0#g+DiM^6>7)sG=8xBcrHGm>#gCq>s77rfZ5Ee z)anIu7ZGdXPhhDAQgEqVLN@<|&ft_uqfb4RE?OaiW&`0QF$(PBXR(z6OCLiSHC=3~ zQmb!&0lE*FUwlMX2dlQ8FkCm_ZB6b6_c3oc4orDL@m~Xe=O^o8+ZO`lgF^c3RAoFOC7z=x6~PQSf6Wv$_7?^{3ilZg$67+e62UvGsJEn@u$^oC_Hx?gPE$w*`dJelTN&O7+9iIPP1@&(to*ArvEf z)YM}1B^S}fFM82*oK!=(>=JQVj(nFH4OeZGwevaPd>4|?#|}+mhv}b2ZG&Mi;8#|z zp?#SKNfhtgdkV^yNpvGy=(xiM0{5ug+%rc-c_$qrHuq=GbtB|bA=FJ)ApLSqbK63y zVXydp?*cpJJ`Zx^25cQxqw!>$**4UUv9i-ukO|>tR31&SpQYL`=y+=XO&|W0#(rAQ zjB`s@hnfz}+#Qew_zd#7tWHITwU@s0yvU)vBBu0IppImoi}DVMg5i^0>kxmkWZKr^ z=zEjP49#eUHfXTaqS<$wDmHtEXhL$9C+io}_EgOH5(cDDik=P43#YEzFGdaSkhz+g zj>+qr`ovfIp^&;kbPKPg!064if|YaZS@S-EnGrQ!3z2-2aWbbpE*Qty^LEIHdXj4S z8rJEDt9`PVuk^7KJ55QBxhezI2AjnLI>;bMR?Z{F5uJ+Tpz*V3q-)08>!h}C`%epR z^qoIHVtMKpbG6@+vpTy}xWRbOJ*{gq@(rDRVcP7N%N=!f3c(+t1^03a-QD#G^O5)5 zTnr>PZ)Uw-W} zqE?ZvrljkQyJe_?Rddp93wun59(o{P9uM6R9$rX<=RXyQ zPm>3K^*^e|m%zdEo?0qP!xWH$MOdT?IgQLYA+zAPYDZNfXrR2rlQnuamPn-PG(+hRQdzbAM~09=#Ln{AA+0%VSx<~^ zq`2w_C+;B8t_P0ki5Mkkbj2c)Vr9H4j%H80GOUKbnVmk|L6zKAP;1k+hXBFHRUG8I z!0o^hMkK5ZiMld?sS*K!(sVr^bDHB(B#jRHQ8D;T{4>Cp*?%HKIZs zy-f*4(LCy3#W*6W8A83owPDdP8a{T3U zxhTJ#rd@-_P8!5gsN%>i94)Uth!=HQ(fJYTAZ20xhv?7uLXJPFWSik2(8oUC%MQAf zxT!J3+S2&$x6C^IF#Zz_$vr$``+$WqHwocYqXZ&PZ)4+#()hq?@m4~;p?E9^OWyEt z#_M7U;aJ>t;7w|e8O_>l&jsOET1AfyN;vYPpS6g><`FAuM`4bsF`iTcyt~G;qXw{w)OAR(8;F>Qh;1&7>EPaTUuC~JOWoa1tP zc+YiO^ik-3q4*6u_i&0^$VrDY{0D+u`tY>~A;{2_LPYMe@b|e`w6-aMz5Pu$IBw!1 z>nek6WDO(tp$9-9uu}CF7|qE7t@w6ljr~y`vdiNP&2kJ__Y9jSWNoW1bVQqFh1&WS zylLU|*8}P=v2tYcKKU!u+<<2F;ECFcD;Crk@pS?#L2#;W%-u_1vV;475zt3CBjBD0 zO;@{z|HQyM0ZJDBYa(&+I4$5Cj-nQ%(O+oSI*^ely*$$1RO~9yOmFqw{H8=*-C&*i ze1`?{-l4_!@z9ez>DlM^eKjvHU85-FshD$FabtM!?)z?go5kyx;bmL5Fb7yL%!qW& z5Y?CKMd^hmEnGC6oxI@!73d+4LCQFFu0`OF+W+Jufm}8u7Aui#MqE z1am*pQykhA3@YZoi8jMw$2Oy!i)0&4G2(FYbiykprW}*9;A9NRf4|$lkqd)jVch7S z=P(#j01T;rZ+|nD`BUKfh~Zyx{}Qmn{QNd>_%rZ&+x&arAm$4HriuPj;Ck8jyMPvE z#`JH2{}zFNhF^E*-^15PFya5~)qe_I_n+T|prpSE{hb^ADRq6h{w`%t_CKVqE#5yh nuP=b#HIbMJ(0}gp&&&H`Il!QJ_`hNaF&|0H^NFVT_3!@x11yCGY*RF@)?hXlqySoMm2{32~Fvt*Wa39=)3=o2Aa3^?zWC$AEogjk*O(3{? zfXk`>)_+e%bXB#mfv@e{!h0&s@(lN(%~VzKN6KZ(SBRw~`T=8#z$ z>o}Jw8sI0Y&Vf#VhVA6)xtV$NY+wUo(T$;4nLYB;M>6G6l_%6uztP`dkxl>QvqwfD zt`xAwF7_UO(E$pnIPL2BUSqvycZOx9Tn-E$MhkxqOom~+jWa8j{v}eW1yL(`uPOzy z;mFScT9X26jf@rSl^5{}b8&jwy+FX)Qh45|8rE1Cpq}S0o_9Z{yd9B$d z+qGa9R#f5cAmymN)f@5EKqU*|BFl%jK6!GkG5NelLOIn;2ugCIU&J(lB^b4CJXfic zxkOC%eJy`2jH)At>2ZFL)+Q*w_ITH-e z{HsA?vZIl|WVAk<-_JW7V`x24=J{XBji-_;><^S5qX7W805ZU9H>d-QkN2-53V`V0 zvOl+~q>cyTcux;*-?3ka*o(0~b@X~vCI;`tOzXCKq*5^ndkXdLkC6BAMmUK+PHH+{AIrVYrJ2@Kv`55| z+kCKsM1H>Py52lFiFIVi_QeQQR+}JqbuN=1C!Q4OE8P)OzL<&3p&GH0+RYjzb59otC{}fdnri@Ci)<$#P?m8@X-ag9M}!TjK;Q{PH4`SphloC>4>es-{ONB7 zI~JArSZ#PZL#w@+6Tb-DE2B zr(3g63&)hohh=Tqck{AEOk$u|*(DrkKimZCBl8aT%YU5L{uyMXK?1;ZeSs-ij*K(38i>*>;{w(bCtPPW}y6)r@Dmx zdReuRQR2-&Ph$eC;mgMD75kTp3iy5u5$IXRYNt5qeM7Y1J&b?@j>~S}THlCIC)q&bu(!hsXxOWfBF`$RUFyF!Vs0@8!WOS zrg^lY{!S$fllox;H+9=|mEfchmqH3?LMiK6R;V%S%&gY_Av$y5yK;yUlMyrp@oxId=PHNYwk)0EJBA>l@5yh;ofk}db@4P-_19{UE$3m2P#zt^t9)_e=_x`2#_-0raZ zNYzpx-)gmKbo*AT$pU#!yjQ`dpJH8V-xdOMxkjTdfL!1xvMvBJ8t7s!zmX&JS2 zwp1`~EBd*YZ-CZVJq;yFEg^i5qXBuTAmcv1_p7JN@xT>ISS=1xD&%G#B<#z{_YBMb zQOGKI3mw|ugUOtxr;-&>o?Tz598}B$LKjs_UtFBFGM(Oz|1dC`;GHT5gn&7kGcGUA zc6mQOI^L2Vh^YNJL5OX6PWBpyBF^yk88`2whtCPSe=MI=Jub$g;4H+`_jabaSJU^) zY+349xm1n(7jkZ%=}Ezskn%NGhd6Z zd;mbb9{?c!f2*Ohhr5f%zpsUm@1B_r6kiW?Y+MCk-#9Q9u4uOnKDJI;%?mrZzwfMk(qoc9lCCBDojbp;a`&LC&E0`I`l!&g-3<{ui^%8ZG?Z zWz>9jG>pNdO(rg9FK>`?ck54YDxe7yEUu8XoMK^B+sWGJ@HO5KR2mQqxgN6e1u~sU znpK9Luf=?+MzUY=btGkjFo{58@4;rC_MY*qRcWRdGn1QxmCVO7sw&cDL_KC?y}Kw? z^HJf&o3T6rtA+vRU)TNW*Qu5neQ6Wk(^$2MJY7p7#;mTKT!S5Ak#6prla#$7VPYM=7$MN3+7$UDz*(0nMj*OpDuA zRrMv%i+w!BG2pK(e^6^0Gamw0XGLcobF+eJXKY9M47-24afkC75>~k{aGD6(_0KlW zY_s!J-ITpL+W#z1qCPn!k*^WgGnobv@Y)-kgd7Dbj)R$<(lIgbZ$1SFo^0h(;adoL zmjzP=`1=Sm2TtJ@3M*JR(75?$0nT03XD)6Ih4;R2U2k6Ec#_iBStQ3uxvx(EX}r6= zl9)ib(i1pOTR%T72K$~5g%Df$-6sxIfUi%H@47PKDTWV&ZVGbr=qmQhlO=KnKLbtf zzF9=s!X_0Cg45`w{ZhfITS$@RKZi@(z^Stul9Q-X`%jhU=MLmau4X zF$%P1rv&ddh*j(mzn@-v|vF&*Z<$ zXmP3D_vQClHELb>MtEMk>F+bz;bj6i$P#BbuB4VnsutMej3X9WW!ui?&!wh3JB9Oe zLh~~5q;tDV4`T9wD!U1A{fg1&Kfolph|OFPK8b8Fste7#f!odYv=k=PI^YY8=RVX^ zcr6e?aQ+kVfius6JOdMq1gTQX_S`3ygL$yUK(Ap+g_Yj?%>oT^nqm~B)h{F{oFT%K zEZ=LDobI})8!f2s;zUs;Ehe-H%l$o}xJN5d4TfLQ2K^;6A=Kl|i1G{V0I{GYQ?2DbIe#+doam(Uj{AHf(^ZOXw`VZeMRb zDSd2NlxmjxjEo%h1`zBK7jJH2nK_AUR^w1HG;w>pl+}|x{JNEa0N(=ix`CC6?K@u2 zWs{DJ&TXU)cGcANsiI$!#MrR@bnIvJIErWKjTAvPw5ggt6P2QiPI<;M5c75bD zsZATmWCB-=y`Aovd}7EJjY_gW?5VtXQ93q%B5slJIX88*N|<%H&!Uu>WszMSn^JJk zU3nwTlPvZHaaKFoY8r!oj7%+htFhsyce~QYkNw8>q`5}7V6SQG#W()Bt^!g!z+3^LV>b<^ zD8>=I5}rdULe99FV=AsV*A0Og+VY0zxlHcs=(An|@fe(EXS2C;)fGSlp=Zf==L@us z6~ZSA*lJ!`8Vtw0XaYJu%7jX;EBemY1+3vZw9DNEQ!)DWrY>#A3Q~B|Y#cP>Tto^a znMQ!-Z!#MfTcdM5kugn6rtz$3^f#+9wE>O50u;$U&rc&SzQp?`Gx#O`;HPdZrT1py z9()D?N@<(xL?weaD;H!BaL_tOp*+#^7II8NeWH%;wCWSXDJZ|kYorL<@8iueXash+ z2m*2&`Zd;3E|W`>dIhL(7K7XN@0^9@1EH+Z_7H3?+`9w_CO~dUO<0hohu16T8|(2LKNh!;IP{Dr*}#IsGcic6qq;GSbED zNXo8$)-}}n*!o@hc6mSQypu(hfZ`sIhQF|(I|=Z-7uEsper7o4$|H{(FQJpafch>U zwHbed3f#@jNkF~f(bjdxEu%x(2BwUwu`C7cLQ5~xR}SEEfez&vnlG)h>T3FBXeIU= z9bPOYmC8DW=Lo?+y5eu61bY@CafyUKN3GoZNfgP?#EHGuO^(aft7+w||I$+<1Jg`F znw+yQ+Ip)LGMA z4TGZ;VLqP59^oEgNUNVlUG~WbH`Cc*pVW4=j+n$MBGKRBZ7TB{?WK`urnqiE2dml9 z@hGcKavF$XpB!1w$ZU{7YA31rz84=_snAC04htFPN|3Qy)_46f~9U4fR}3C!~#oQ6*P_h|8sCGCbs!eB~sQB|d&W z!`*)CMy8HSK_xwlV@}S;#L9-lcetM#4%ON9GH}I4&fHdUE1Wmp&tjz=k9zJ_Iq1C> zu0$TaqaUkTzbTJjzoB#Te}h?iME?PkbCbWh%cyy1jM0x4LmzusL!Uc=oyu8EXzK&Z zBC{>v;u+8F%$=q{C#?eGPaw{hSRXzl!A<~`&hZ)cd1vAUHb@6>)$)DsZT+RxK@Njw z6V@dTU3kmUH9Y+dZ8gXnVdUB4`N|>U+EU?aBo~x~tx~TQK@dqPR1c8Ge)uaR`RL{h zFwu^LFY-QNKJGGF>m;0!_!6wno;wAu!6whF?r{jw)(_L@U$RWlfn75j@m<6B&R)Nx8!t zCS41hhqyjQ_fn$Lhr23KRp?dC$S9zlk|ztFFi=m&B1J3Y!QFPNWIMOc?ZD-%f6D361x$h}^>_dU!%ge~T6zP|usXMr40Jrdlv_pyQ z%~#lz8Z;kCj#5xEzP_Nu$DioU(0r#cA4sIx=x9T}S5_c1INUoOSVoR*lCVPis!~*J z2^`Xty;wK0U0<1IEH5`kfF_1Oejzu~dxZM<sQ}dy0i}ckCnxGOnHoOy+mBa%}6IRLhl^YD{Ex-8W1#t4|-16yo z(V^#eh?^?$G6vErgSV*xPm)o^ZX9f=Tf#}acY3^c{9Dcvz13L`Mc*BXUV77R0MzejWY(lV8lw5Dz1$V{=hHS{&4(gbN?ZWe5?oNglhOyq zr)C3;((NBYZV|}pvXg1`*2*S{SA|#aVsa&y`^xz?Eq`)*h!~R=B7c`1oDf%(nnuNB zO1|!x8R7&h;_DBw*9Xz~<1esRnBj|L@f0F4><)DuEF>_M?BYbC@Ut*puM4Z%(~11% zsY7Df9n!}?H#qOp>RK0!s>)+s2HEm%7WePf^ss6qeR9nx7Kx?NcyHisc(Yj!bEg&*9I z!~H<{)9kj*p;m0_YLye-Os7UKxRU|%d&@)HdL{cS2`yt6Ki2(*e(GKPLe0_-E#p@g zif-@E*Zoj&s8grTKg2#)d9q8zfm6DE(=W(1BsOoVYwC!fBv)mnoPR${%1c4>9XAbO z6E6OdInBAtos}&f&gKp%xi#=swQ}2;R*P9ri@oaZx#jR_Z1c4ANvat4=5EI8@!7=R8TYGGH3f+4+|M>tKZVzo zJQ-zh%u{}7zCT+d{gbk-p&fMOp*gPpK$`yVlpVeP|2RX&JM2(_L>MbKvSHo_O-HZZ z*(>8pAd2C8sA}&0s_tYdMK|Y&)5Px!heG##{C4-G(#>YPyp#Q2x9!x4kuwv}AIsm4 zw$kff26JC3iyx!oTKj!3a}g6**N?@9d4R#8rP2N$MOv}6hoezcpX7~RqW1oGEVM&xbw4{b7)5Isp=X-6JobaoA_Y5<*!AVwVcJ3Q z-+wn<-Kg%LhheraKjlWH!C*E8GHKJf{$AxREa4TlPS%+&&+Jk+9pxAq=L0Uk*G z-|asbeg72r)3y4axc?EbdieR9hxO0EKb@Gr2M#^l;eYUD{weTh^Xl&cbJ+hY@c&v_ z{|x`LHvc_bg7P8!-z)V$h5jr*e;3N7`kT;yDn|d5`g6AaU8 gW(&=K(fr4B&;p@9xMqJD!dL+Dhxao_``6k30l@#O=Kufz literal 0 HcmV?d00001 diff --git a/onc/examples/OncDiscoveryDeployments.mlx b/onc/examples/OncDiscoveryDeployments.mlx new file mode 100644 index 0000000000000000000000000000000000000000..21364f799bb25d21f6e2ccb3118cc6e2a7f0493e GIT binary patch literal 8539 zcma)?1yEeumWCS$?(XjH?iSnck1Hlq3xCbXdAUGkoy9NS7=1tAq z+hty9YoA(wYpTG#zykmPNY5uVVBxcPIX?^lPz?tF;6C3ml67)) zw{mnh)%J0=ax>xZ20JvSj;r@^VTGLppp5Fh{p2i#M1K@a8I3AeF4n#7kX@btUdR>* z@DosDhR1k;?C9dTlYJ&PylrC9k04u>JHF*3k_KDtX$976@i$mz)O#fdYZT%_;MUT| zG~h2VOdy)5Rk!%rSXb`Ru%evRfvRkxcx!k%93d*vyi{zLze>|Y6`G+es$$Drm`81c zOa0NvSO%oHj8>eNr*gVFLlRYA5zpS`oC?Q_ZhI~Ip)x>h1D^R+ zYSe>yNn&rc7Iak==u!m#_tRfK1(GiDg&b$Rd3Cgng!ovy*d&2agpaQ5cj?plShS!? z4zqPQ4Y*lvru7*-WMwMNUqF}T`^H}i($I+kqz&u)FW&}FcqIC?&Uei7rl{on>r@0K zCZc!6HOsD_79GwJG@mK6|1ag1OOZ9EXUY^W002|~9>CPq%E673<9CDsU_B4}^Qcbk zc_xk~b@D5Q>4qO9$RGvwf~^n?`;3^`4|?CI^tQy|-j65vWnTdc?%>ebg&Ud8f$Ut0 zAYYRf4^&AE`hs4sC|O6{R3Ne5NVy7*xj+ZU%~wukxHamdjYH2Josr-ojz+Qow9)Nn z9``8du=}%e@nv!~54lhfAO6>FFHLHdoeO+kSp;?(8CW)Ed37~r9AyDB7I)#R9D+CR zG}})!Tj#$9oR*&zHFX)Bq%ACDzE23)zWc0RnkujVbFBDKFZxnO=1TqMsq9pm6k8wd z#bhu5v1-Z9>U8)vQlLg!)L<{w` zuqVyzDGi`as933YsKglz-a|7PQ<;8eYc`H|`_^PJ`&47}mxo;&<(xwiE?> z)ej`TOe~efkYp9VI_-a9f_ty~8hNA$;e)%#4^L5l@$DL4r}44{l^jF&Bc7R8EOdOy^eoET*YgLnv<<@p)AH*^etf~CnDn8 zLEh>ifHxt2iz~Is@8|UAS_V2nqMuMFpaGi)`?u+G`S`SMy+IGju^aPtbDT)q!f6z$ zCmEFbCka6V6E>G^gm~PV=E)SUtq7sf@(w1vkz6mb_aTcq(!487`)RS91BRVi>6;-~ z!})Vz+;tejVsJ_)R5f}+TR0bUhOQk3qT;a=l$+Lk)P$Vtl2L1n=`D7n`TV88vl0Sc zOzEb==epK#LgPg8edxZP7`5RD=#lxVHmR*-Wh`5uNhA8k8XuP>d;o-=zM{FK ztB_nh#%WH2a~9Z8)MjK)?;ezO2^Mx0YYj1)8PnR{B98W|p1H1&=7c?o??G?zV zub-WOxZ1*<6yeWkMuS;UUm@-=QCi8!X!-4KYO}rZwa}}g^#;-p-a$34BBr$@eyJ7~ zRne5QV)6zxNg5Zb--9p2TW#O)^D1yk1gVciHMSse{a7;!nTOnRz($&Hii9h4Me@{$ z5W5e3kX3+)xrLY^1Mtj_hpcq{ENfQSU)Rnjb&}UC$+mw;SjHT!;COfCDaj?whNbH}zvaHEFejKf}7+L0{$^4%xycU`7r0GDmZE1G5JUGbm>i1P;==+=w$#o`m^k8{E z&v|T5B%=yy5!qoh(RucL1{rzyL86(Ggz#Ca{N551>Mp&$t8t?}j|)~r1)zfI(M zK$B{ynT@4iKun!oGs*eh%4S5rO4&+xfSDHAX|Nci)uxwXR}}X0)ET%qhDMjo1h-8N zWcz9vzuQPo)K*S@`mM-jpusGY8^ljECmP>EhVj? z2#hf@Ws9++2-k#AupV&Z8m)m84Ud8^LJ^Z*x>j1Vta@-d&rhoo4J^9o zO_@rn;BGo&svXS$shJxHOJ911V$c;jVkRiW!IeZ+j5Mn!6Ab^HlrkwJDIHp zv?tds*Sn3p2hX<;4^I4Ynf)169|p5dt3yhKz?H+t&WmTu+lL!%LMjaob5mUg%R};! zTt?_X>27!r2lZ~bEp@laA69MDls!?!(32|$%Nb)7m18(YuKB#3$7V6YKvovZ49#;s z`Bj3>z_hVSt+t!0R+TE>_LtekCk3Pp3)J3dN+|f%Fr(&8tS67z(t2Cmq^j+#No%bu zE2;f!UljWH^2>6b5dYjH`9x4>g`VFyBF+E+?El*&ojlx~J^p!%G&yoz{6zBj{r%~w z#XS@v!M5aW;>o0x?U0&;zPfVVkedMK*f#@{;IeqMcj%FWDkA7fM~p=GF<#2WL^pQ~ zZz-i(FY$8!mp7YV*MkQ+aekk-KvrD-H#4}IIA^g;G=+^s4N%wpmjm^qj3&Z2rV)MS zLWe7KU$ZU0UDx!{2_dCG-uxt!6O@*Df0IguyfoKy%MjJRy>jse&p&sWZVx6vYL{Q{ zi#Ki{$kUk@G-%HCu+Kj?;ZtwNr<}r-r63>k6$mLV>|cb_|kRR&0)XG z>8xU>dLOhA@~cKmspwRMj1ioe>&W=SGrx(=b`_-d?t}J9&w*DiCX7JL*9)( zIssS<0d&M-%wm|1OCLTYbcPC$Sdka-s-3Qr7}L9!EKyQ*aW%ti8w%|;XA~xm@3Yaq z);PkH<|`I|>)}(qx@S976SdFAF*W$z$JtG%EGk{Nt&nK2K2D+sZ&Ln-PcNofZ=&|* z`wkTae1_J%22dnjPTWV_SrmJ~R@G=RHxAcuuAtaO%&itt1EihSu*TAkVI4or zNA@+gA++vv@4d3)E@X@ls&Vo0eW@cSf4GLO7nHJG!A39xl-nva zaU8#d1F~v9USU7+lGk}n)NJ&0&&d}Uladd&!Ga+vRz0O27ou{*5?8j9x;H+fNdKNV zlqpkd_^YqO=KZBXW4;7~B$R$$Eel3e;I@jlGcJX7qmL;rf_Dxyk-rlkdQe9mXY(fY z>3sKLKk*UwJi>c?Aem63b8L~lcKGQAA$51#R}3U85=7W#pcd44KsZS8b>4ib;EAIz zvG|Pk8pNgi>DwBj_6oh;g{f+rhuxrmPQPiJ_HcFH8?uNE>Zd1`O!8A!)rU*8w3tfx zM^TiN%O|DEg7n$qI}2#BWs-zIp4=4eH{dr-Cjx(rNaKulpV#--O`kQos#}~uiF;gq z9+3U+bMsO7OH4ih;K}!)>DudP*w=ihKvi@Dd^EhYXzM9r%D!vmE7EQXN7EBP;f2w< zvwNv{n>1+Cf%%Rvlz5Wsi>wuwiWv;G zV|#JXT|+A(t%?$1FBVk~Pa!w{ps0qw3AYP0s_w<9)Yd^2`Kp)1PBn%%{BCyIITH|5 zBPMZVSr}|b4lNz(1lj^35P&Eu^dy@-lT>KvO*s~Gd?vt3d0FiW0J=O#p_Qd6(_?^5 zA?;h5_Xw-uDD|xFWMqQtj)e-}re1>AOrfbrL<>x_8m!F{!tOErazul0E?u-jhMhR3b&Vn$Zb5%HSV1++Ew`N%L) zN2|h#bd?oS6N{y>kXcHwqtL@*Lo8EYu};PIetQY($oEj8xS1~?i;Y2wnTn>O5O^aP zSLA20H!kSAu`XG8yYCYCQhevTQ|$D|i~>6UOPYz&(GZq^dF%g0D81uJq{>X}iYJ6KTua%4F|ZhH+L?+7@sIr}uCu zFq-y}?vg}-RE!hsM|BNkg?h_JIeBDVLg)7~P9+yhCmpeU6MHK2lA-;4E{;-}Tli#z zw1lH~Y(TvbdEEjloBj~dS{^cjeOKH927+Z^AxBt%Vh7g}ygoCDjHD_$3ETYE47Q~f zl5MLHBZ?LZ35}kC#ObFNO``&8v=^*0aO1Lx7nU^I5fNNsdKe^0Rvrg{J4jtWzE*66 zW}RdLCWap#4mVM4!u=%)fWf)-3(~%buBT&01&c%iAPL=btA{!c3BR|Hp%#_k=bWqB zI&7Lj3YtzD>Avr`fS^@T$cZSTVjLluCviyjDM>ZhYu0 z6$Vz#x@c(d{B2LS4R1&VvoIH4Euno#7b^)$qj65Lr;c5Du9ki!L-$7-xrA*hWlaAk zW8{$@LPubGT20ZTLxfpAg>S-4$ef&BCNnTnYW$)*=Yooug>31}9 zunrIBv0aBhk*h?0Mb&NE19EAe*HsDe(UhVJTI$}U_O!!L#ir`*wxOo7FDm^>?+8Qj z91O&+uj!Asq+~g?9#B>%yfec#yFv&164{EWZZIf5=0t2ES#&Z}^x8UOQxqv1b?`WF zAdq;PWAs7&1JXhffAk^MYYTTzhh@@;$(;zMheZw`lKl8N;;z={J(QX%FhIM4(!FZN z3IU(a+l%X^cp7yQC|%(fu&7jbE}pT^l8F(V$bZz^FLjd&_l^=qgTL5N7>Bbv&to`Y z?;Z-1Nxdo2oZReSDJU5Bo9&iPz2WmYp+GtR!K5}bDTn^w!KAJ|B#psdN?+o&MOKqP zB@+pjT|&gRt!=_*c7;%F8w)g=W#Z7?YVL1EXGvD?&pkh_(Acu8>R!F+IHt_I@*|Y_ zUiox5*-KECSCdO#mp8Z&JnAZv0s|uD+EkNL>LdKf!+s;bhH!2b_5#lk{R9rjlJ0)Xq5#rREfm8Y}E2V#3`T><+ zpN&xr`29hOo~v7MfW{53KfI;q6RoD_Xa@~j(>W*JLc><-jpt`zVzi$dBf*D~*7Zg| zKehs}%|4UO2QV^!QB*A5FVqmyA%Xh2V{jc7OH*}Ik`laICV6;TAfgQ-d0OJY`2fj~ zgbJOF0`|NV2Hw>z#)XU;nq>>tB1bk!T2C*`JAtF=%li3WkI-NS!|gs;mEQTz3uLr{GRP*3B@&)zgGOXji-WzlUH8L zxPYO2ej1C{id0h4m_|HjB$h^UR?6OfNXrLu66MZF579BUjHLFt?>qt{fpru+PN?-1 zf(y#k`lQHig7ozMBN}0j5ieuc#!97aWK?ut`j{PpSsMIBZa*wUC=1gY%9_qOMF~#6*qaom3I|O`Fo11;hux4Z{3<>>xZp@euyMq2 z1{WFWa7MH=De=TLBq4aSnP$ozO>J=ALIk1LT4$HY?)C9B_pX83;3O%=cVCn5UO_s) zU?zhENCu&t9KL}&>mFTR->|!sKX!+uk8+e?YlRQB1koIti&$ZBiZBjxCOiaMQ}}+7 zt~03;vd@C)ojM4OUA@yfInqC|kedcEEB;6~Zgy3Xm-n!e^PdlXIR)it56}BPFWC!?N$rv&3J-PsBC^jaz=C9N0b&jbJlU6XsRp zVLPipAvl~<9>LA9@AW|WZPxyrA(rPiB4n^3!i!;^0`;dcIGJh~9SW?LCfq<%OA+wG zFC;5$`q6_RwT4MK)c+2@tHvyYp+2TY15(QDI48l#+HfEamxEgO%**yg%@WQg5Rs87wMh z$l0a2TXSYT5axZeyBgmj;)QO{Z`m)lE1MzlRD6|%3Ra7)@_D?;@9m?ryBKKd2dD8@ zACa6Mk8dk4@?-TDA!^MYlDJ&}w|-V~SRZY@jHr`1Xeh04>3T8O-CzVCFf1$hFwNut zn%KyK0{EJI9Cz@{+YDnBb+WpDhYp(8GCZ1m;peGuvWOsJ!C(=X(*2}{2D?b$(ei_VUFsraq{DZtWc!O!NTzJROhz-};dN|%Y`z=1ix@>j zQ20T>G#(3SFx^GOF&zpU9z1Lz+ukg6x0=A|g zXBDOoEekk?#}M`=M^(0Tgwb_9bW>D*vV~2? z(*V4p8bf~(Y z>TYM{_D_BK_~g;wHkAC$9m?o^|3qj;S_!JA9u+mV+`xouS%v(eeiQZ4_l*bvyxove zk1u5LJL$32`%{SejEE*b_zH=F31nG4^nUDE6PsFWip{Z~Afn^12KU)&DU@=lq7hIW znRWXjW5B0+s%D}%wF|~!F$xrXQh_a${X|i z3UfqvO!>m`UTG2qR-9>aHJMLoSnz$xcVZz?7c>o9Ox>3H)3;-r--h3j4001+M5EqA zEw7xP_yYLTeS=tGJ|$qWV0tpJIb*V;U|csYar+EAon+D1@Mht2v#+x`eax9+)m?5+ z-<*5Egg!TWww_AlQ%kEpnF)(0Q@|H0pF>AQe!lnBC_aS9>ytI=0>&DBJm8DbOr$H|JCtR^M za}JK_A+KNE#3|9=rmQx7Rnkb6Tf0olz%Uq7@w&cBAg z14(Nv4n~=>VB#jTwp5Ti>cut+A)f2J(uZTW7497ndXOh2z%PVLL z1+B=9b4|L#vBi8N<7!W_dR>cV-orFpen>Z;ugdnXsw#`sPCX2^R?7Nn`qYldm5*wy zfE4XPzLbTJ4DvywV>Xa>&9jm#Yo}^gG#JFF8r#yE2P<wd1NxI8r&osA81g;( z8)3cMF_eQ_ z$L--=t{w}m2mdF9{y?T!E$Oi{&VW)j!UH2XI#?r|#W3256g_&78wkD>6=zD=gn=xm zaPX{aCtp(q=D8aEvmO3S3h+$oe~y1+j{jZYPp9`^dH)iye*XB2@B8<}Ki$i}CXPOT z!++yt{$1eD&hB3YPLcmt;Q#u(e^39jI{!5tMDm>e&$asRLVwnuzY0y0{zd5DRinR4 z{kdHKDs@cuAEf?RynomHa{>HS^OXEQX#Qz>% literal 0 HcmV?d00001 diff --git a/onc/examples/OncDiscoveryDeviceCategories.mlx b/onc/examples/OncDiscoveryDeviceCategories.mlx new file mode 100644 index 0000000000000000000000000000000000000000..861e33acddb080e35c3e5d332de4359c8581ee70 GIT binary patch literal 9266 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 literal 0 HcmV?d00001 diff --git a/onc/examples/OncDiscoveryDevices.mlx b/onc/examples/OncDiscoveryDevices.mlx new file mode 100644 index 0000000000000000000000000000000000000000..878d9aa076062bfa02514444daa3e601ccec4eee GIT binary patch literal 5867 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 literal 0 HcmV?d00001 diff --git a/onc/examples/OncDiscoveryProperties.mlx b/onc/examples/OncDiscoveryProperties.mlx new file mode 100644 index 0000000000000000000000000000000000000000..9eeca6406ae9c7a291b22bf90f3f73647aa53f85 GIT binary patch literal 7100 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 Date: Fri, 14 Jun 2024 13:59:04 -0700 Subject: [PATCH 28/35] issue-21: update checkVersion to return nothing --- onc/+util/checkVersion.m | 5 +---- onc/Onc.m | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/onc/+util/checkVersion.m b/onc/+util/checkVersion.m index 07a156e..bf1b554 100644 --- a/onc/+util/checkVersion.m +++ b/onc/+util/checkVersion.m @@ -1,6 +1,5 @@ -function isLatestVersion = checkVersion() +function checkVersion() url = 'https://github.com/OceanNetworksCanada/api-matlab-client/releases/latest'; - isLatestVersion = 0; try % get latest version releaseInfo = webread(url); @@ -25,8 +24,6 @@ link = sprintf('How to update this library', formattedPath); warning(['You are using an outdated version(%s) of the library. Update to the latest version(%s) to avoid potential errors. ' ... 'For instructions on updating to the latest version, please visit: %s'], localVersion, latestVersion, link); - else - isLatestVersion = 1; end catch ME % do nothing diff --git a/onc/Onc.m b/onc/Onc.m index 02cf49d..63ce061 100644 --- a/onc/Onc.m +++ b/onc/Onc.m @@ -1,7 +1,6 @@ classdef Onc < onc.OncDiscovery & onc.OncDelivery & onc.OncRealTime & onc.OncArchive %% ONC Facilitates access to Ocean Networks Canada's data through the Oceans 3.0 API. - % For detailed information and usage examples, run doc command or visit MATLAB's help browser - % then find Ocean Networks Canada API Client under supplemental software + % For detailed information and usage examples, run 'doc Ocean Networks Canada API Client Toolbox' command % % ONC Properties: % token - User token, can be obtained at: https://data.oceannetworks.ca/Profile @@ -143,7 +142,7 @@ %providing the locationCodes % check if it's running the latest version. If not, throw a warning - util.checkVersion; + util.checkVersion(); end From c42e6cd2057aa48922305b21e473c0942a1f7ba6 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Fri, 14 Jun 2024 14:05:21 -0700 Subject: [PATCH 29/35] issue-20: update filename for consistency --- doc/Index.html | 158 ------------------------------------------------ doc/helptoc.xml | 32 +--------- info.xml | 3 - 3 files changed, 1 insertion(+), 192 deletions(-) delete mode 100644 doc/Index.html diff --git a/doc/Index.html b/doc/Index.html deleted file mode 100644 index 8a11bfd..0000000 --- a/doc/Index.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - Overall Info -
    -

    Ocean Networks Canada API Client Library

    -

    This library serves as a toolbox to access ONC Web Services which allows users to discover and retrieve Ocean Networks Canada's 12+ years of oceanographic data in raw, text, image, audio, video or any other format available. This codebase provides a class that wraps web service calls, complex workflows, and business logic so that users can download data with a single line of code.

    -

    Check left panel for more documentation and code examples. You can also find code examples under Examples section from here

    -

    Introduction to ONC Web Services/API

    -

    What are ONC Web Services?

    -

    A group of public web services that can be used to explore and download ONC data.

    -

    Documentation pages

    -

    https://wiki.oceannetworks.ca/display/O2A/Oceans+3.0+API+Home

    -

    https://data.oceannetworks.ca/OpenAPI

    -

    Tutorial Page

    -

    Web API Tutorial

    -

    Oceans 3.0 API overview

    -

    Check here for more information.

    -

    Glossary of terms

    -

    Check here for more information.

    -

    Main documentation

    -

    Check left panel to select and view documentation of each service and function.

    -
    - diff --git a/doc/helptoc.xml b/doc/helptoc.xml index 6c8b939..6317795 100644 --- a/doc/helptoc.xml +++ b/doc/helptoc.xml @@ -1,37 +1,7 @@ - - - Ocean Networks Canada API Client Library - - - - - - - - - - - - - - - - + Ocean Networks Canada API Client Toolbox How to use Onc class diff --git a/info.xml b/info.xml index 6c66113..f96c0f0 100644 --- a/info.xml +++ b/info.xml @@ -2,9 +2,6 @@ - - - From de57a23064b701365cbb72fd622c6e0656756fd0 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Mon, 17 Jun 2024 09:52:58 -0700 Subject: [PATCH 30/35] issue-20: modify documentation --- doc/ExampleLinks.html | 84 ++++++++++++ doc/GettingStarted.html | 5 +- doc/HowToUse.html | 81 ++++++++++++ doc/Info.html | 158 +++++++++++++++++++++++ doc/OncArchive.html | 24 ++-- doc/OncDelivery.html | 35 ++--- doc/OncDiscovery.html | 1 + doc/OncRealTime.html | 1 + doc/helptoc.xml | 5 +- onc/examples/OncDiscoveryDocumentation.m | 48 ------- 10 files changed, 362 insertions(+), 80 deletions(-) create mode 100644 doc/ExampleLinks.html create mode 100644 doc/HowToUse.html create mode 100644 doc/Info.html delete mode 100644 onc/examples/OncDiscoveryDocumentation.m diff --git a/doc/ExampleLinks.html b/doc/ExampleLinks.html new file mode 100644 index 0000000..df2fa66 --- /dev/null +++ b/doc/ExampleLinks.html @@ -0,0 +1,84 @@ + + + + Ocean Networks Canada API Client Library + + \ No newline at end of file diff --git a/doc/GettingStarted.html b/doc/GettingStarted.html index 8e5cca3..4545544 100644 --- a/doc/GettingStarted.html +++ b/doc/GettingStarted.html @@ -140,6 +140,7 @@

    Getting Started

    Contents

    +

    To navigate directly to a specific part of the documentation (use the internal links), right-click on the section you're interested and select "Open" or "Open in New Tab".

    +

    Before using the library

    You'll need a token to access all the web services.

    diff --git a/doc/HowToUse.html b/doc/HowToUse.html new file mode 100644 index 0000000..954f11a --- /dev/null +++ b/doc/HowToUse.html @@ -0,0 +1,81 @@ + + + + Ocean Networks Canada API Client Library +
    +

    How to use this library

    +

    Contents

    + +
    + \ No newline at end of file diff --git a/doc/Info.html b/doc/Info.html new file mode 100644 index 0000000..24d3200 --- /dev/null +++ b/doc/Info.html @@ -0,0 +1,158 @@ + + + + Ocean Networks Canada API Client Library +
    +

    Ocean Networks Canada API Client Library

    +

    This library serves as a toolbox to access ONC Web Services which allows users to discover and retrieve Ocean Networks Canada's 12+ years of oceanographic data in raw, text, image, audio, video or any other format available. This codebase provides a class that wraps web service calls, complex workflows, and business logic so that users can download data with a single line of code.

    +

    Check left panel for more documentation and code examples. You can also find code examples under Examples section from here

    +

    Introduction to ONC Web Services/API

    +

    What are ONC Web Services?

    +

    A group of public web services that can be used to explore and download ONC data.

    +

    Documentation pages

    +

    https://wiki.oceannetworks.ca/display/O2A/Oceans+3.0+API+Home

    +

    https://data.oceannetworks.ca/OpenAPI

    +

    Tutorial Page

    +

    Web API Tutorial

    +

    Oceans 3.0 API overview

    +

    Check here for more information.

    +

    Glossary of terms

    +

    Check here for more information.

    +

    Main documentation

    +

    Check left panel to select and view documentation of each service and function.

    +
    + diff --git a/doc/OncArchive.html b/doc/OncArchive.html index e1edfb1..755db51 100644 --- a/doc/OncArchive.html +++ b/doc/OncArchive.html @@ -101,16 +101,16 @@

    ONC Archive Files methods

    Contents

    - -

    ONC Archive File Service

    + +

    ONC Archive File Service

    Contains the functionality that wraps API archivefile services To be inherited by the Onc class These methods allow users to directly download previously generated data product files from our archive.

    ONC systems auto-generate and archive files of different types at set time intervals. These archived files can be downloaded without waiting for a generation process to finish (potentially faster than Data product download methods).

    @@ -122,7 +122,7 @@

    ONC Archive File Service

    Caution

    Due to security regulations, some very recent files (e.g. hydrophone.wav files in the last hour) might not be made immediately available.

    -

    GetListByLocation(filters, allPages)

    +

    GetListByLocation(filters, allPages)

    Get a list of files for a given location and device category filtered by other optional parameters.

    Input:

      @@ -171,7 +171,7 @@

      GetListByLocation(filters, allPages)

      fileList = this.getList(filters, 'location', allPages); end
    -

    GetListByDevice(filters, allPages)

    +

    GetListByDevice(filters, allPages)

    Get a list of files for a given device filtered by other optional parameters.

    Input:

      @@ -217,7 +217,7 @@

      GetListByDevice(filters, allPages)

      r = this.getList(filters, 'device', allPages); end
    -

    GetFile(filename, overwrite)

    +

    GetFile(filename, overwrite)

    Download the archive file identified by filename

    Input:

      @@ -291,7 +291,7 @@

      GetFile(filename, overwrite)

      'file' , ""); end
    -

    GetDirectFiles(filters, allPages, overwrite)

    +

    GetDirectFiles(filters, allPages, overwrite)

    Downloads all archive files that match the filters Uses geListByDevice or getListByLocation to get a file list, then getFile's everything.

    Input:

    ONC Delivery Service

    +

    ONC Delivery Service

    Functionality that wraps the API data product delivery services. To be inherited by the Onc class Data product download methods allow you to request and download more than 120 different types of ONC data products, with granular control over what data to obtain, from where, and in what time frame. They are comparable to the download functionality from ONC’s Data Search tool. Examples of usage include:

      @@ -114,7 +115,7 @@

      Note

      If the data product requested doesn’t exist in our archive, it will be generated by our servers before your download starts.

    -

    OrderDataProduct(filters, maxRetries, downloadResultsOnly, ...)

    +

    OrderDataProduct(filters, maxRetries, downloadResultsOnly, ...)

    Request, run and download a data product as described by the filters

    Input:

      @@ -185,7 +186,7 @@

      OrderDataProduct(filters, maxRetries, downloadResultsOnly, ...)

      r = this.formatResult(fileList, runData); end
    -

    RequestDataProducts(filters, maxRetries, ...)

    +

    RequestDataProducts(filters, maxRetries, ...)

    Request a data product generation described by the filters

    Input:

      @@ -242,7 +243,7 @@

      RequestDataProducts(filters, maxRetries, ...)

      this.printProductRequest(r); end
    -

    RunDataProduct(dpRequestId, waitComplete)

    +

    RunDataProduct(dpRequestId, waitComplete)

    Run a data product generation request

    Input:

      @@ -317,7 +318,7 @@

      RunDataProduct(dpRequestId, waitComplete)

      end end -

      CheckDataProduct(dpRequestId)

      +

      CheckDataProduct(dpRequestId)

      Check the status of a data product

      Input:

        @@ -345,7 +346,7 @@

        CheckDataProduct(dpRequestId)

        filters = struct('method', 'status', 'token', this.token, 'dpRequestId', dpRequestId); response = this.doRequest(url, filters); end -

        CancelDataProduct(dpRequestId)

        +

        CancelDataProduct(dpRequestId)

        Cancel a running data product

        Input:

          @@ -379,7 +380,7 @@

          CheckDataProduct(dpRequestId)

          end end -

          DownloadDataProduct(runId, maxRetries, downloadResultsOnly, ...)

          +

          DownloadDataProduct(runId, maxRetries, downloadResultsOnly, ...)

          Download a data product manually with a runId. Can optionally return just the download links

          Input:

            @@ -421,7 +422,7 @@

            DownloadDataProduct(runId, maxRetries, downloadResultsOnly, ...)

            fileData = this.downloadProductFiles(runId, metadata, maxRetries, overwrite); end end -

            RestartDataProduct(dpRequestId, waitComplete)

            +

            RestartDataProduct(dpRequestId, waitComplete)

            Restart a cancelled data product

            Input:

              diff --git a/doc/OncDiscovery.html b/doc/OncDiscovery.html index 96d596e..a3234ba 100644 --- a/doc/OncDiscovery.html +++ b/doc/OncDiscovery.html @@ -87,6 +87,7 @@

              ONC Discovery methods

              Contents

              +

              To navigate directly to a specific part of the documentation (use the internal links), right-click on the section you're interested and select "Open" or "Open in New Tab".

              • ONC Discovery methods
              • diff --git a/doc/OncRealTime.html b/doc/OncRealTime.html index 878b607..57dc933 100644 --- a/doc/OncRealTime.html +++ b/doc/OncRealTime.html @@ -90,6 +90,7 @@

                ONC Real-time data methods

                Contents

                +

                To navigate directly to a specific part of the documentation (use the internal links), right-click on the section you're interested and select "Open" or "Open in New Tab".

                • Near Real-Time data service
                • diff --git a/doc/helptoc.xml b/doc/helptoc.xml index 6317795..1d86fc9 100644 --- a/doc/helptoc.xml +++ b/doc/helptoc.xml @@ -2,7 +2,9 @@ Ocean Networks Canada API Client Toolbox - How to use + + How to use + Getting Started with this library Onc class @@ -18,6 +20,7 @@ Near Real Time Service + Examples/Live Scripts How to update to latest version diff --git a/onc/examples/OncDiscoveryDocumentation.m b/onc/examples/OncDiscoveryDocumentation.m deleted file mode 100644 index 42a4eaa..0000000 --- a/onc/examples/OncDiscoveryDocumentation.m +++ /dev/null @@ -1,48 +0,0 @@ -%% ONC Discovery Services - % Contains the functionality that wraps the API discovery services - % To be inherited by the Onc class - % Discovery methods can be used to search for available locations, deployments, device categories, devices, properties, - % and data products. They support numerous filters and might resemble an "advanced search" function for ONC data sources. - % - % Use discovery methods to: - % - % Obtain the identification codes required to use other API services. - % - % * Obtain the identification codes required to use other API services. - % * Explore what's available in a certain location or device. - % * Obtain the deployment dates for a device. - % * List available data products for download in a particular device or location. - % - % Note - % - % * Locations can contain other locations. - % * "Cambridge bay" may contain separate children locations for its underwater network and shore station. - % * Locations can contain device categories, which contain devices, which contain properties. - % * Searches can be performed without considering the hierarchy mentioned above. - % * You can search for locations with data on a specific property or search for all properties in a specific location. - -%% getLocations - % Obtain a filtered list of locations - % - % Input: filters(struct) - Describes the data origin - % - % Returns: ([struct]) List of locations found - % - % See https://data.oceannetworks.ca/OpenAPI#get-/locations for usage and available query string parameters. - % - % Parameters: - % Query string parameters in the API request. Return all locations available if None. - % Supported parameters are: - % - % * locationCode - % * deviceCategoryCode - % * propertyCode - % - % Returns: - % API response. Each location returned in the list is a dict with the following structure. - % - % * deployments: int - % * locationName: str - % * depth: float - % * bbox: dict - % ...... From a94ed71bddc395795a6fde740d9473778fd6fc80 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Tue, 18 Jun 2024 10:57:54 -0700 Subject: [PATCH 31/35] issue-20: update name to ONC for convenience --- doc/helptoc.xml | 4 ++-- info.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/helptoc.xml b/doc/helptoc.xml index 1d86fc9..9ef51e8 100644 --- a/doc/helptoc.xml +++ b/doc/helptoc.xml @@ -1,9 +1,9 @@ - Ocean Networks Canada API Client Toolbox + ONC Toolbox - How to use + How to use1 Getting Started with this library Onc class diff --git a/info.xml b/info.xml index f96c0f0..3442751 100644 --- a/info.xml +++ b/info.xml @@ -8,7 +8,7 @@ 2022b - Ocean Networks Canada API Client + ONC toolbox From 01ad33c45d46a2a094bc747075d58d3397a7e328 Mon Sep 17 00:00:00 2001 From: Isla Li Date: Tue, 18 Jun 2024 10:59:41 -0700 Subject: [PATCH 32/35] issue-21: fix typos and add links to documentation --- onc/Contents.m | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/onc/Contents.m b/onc/Contents.m index e22a6ae..1028a63 100644 --- a/onc/Contents.m +++ b/onc/Contents.m @@ -1,6 +1,8 @@ % Ocean Networks Canada API Client Library % Version 2.2.0 10-Jun-2024 -% +% +% For documentation click or type directly in the command window: doc ONC Toolbox. +% % Functions % +onc/OncDiscovery - Contains the functionality that wraps the API discovery services % +onc/OncDelivery - Contains the functionality that wraps the API data product delivery services. To be inherited by the Onc class @@ -8,14 +10,14 @@ % +onc/OncArchive - Contains the functionality that wraps API archivefile services % % Live Scripts -% examples/OncDiscoveryLocations.mat - Example Usage of OncDiscovery Location Service -% examples/OncDiscoveryProperties.mat - Example Usage of OncDiscovery Properties Service -% examples/OncDiscoveryDataProducts.mat - Example Usage of OncDiscovery DataProducts Service -% examples/OncDiscoveryDeployments.mat - Example Usage of OncDiscovery Deployments Service -% examples/OncDiscoveryDeviceCategories.mat - Example Usage of OncDiscovery Device Categories Service -% examples/OncDiscoveryDevices.mat - Example Usage of OncDiscovery Devices Service -% examples/OncRealTime.mat - Example Usage of OncRealTime Service -% examples/OncDeliveryDataProducts.mat - Example Usage of OncDelivery Service -% examples/OncArchive.mat - Example Usage of OncArchive Service +% examples/OncDiscoveryLocations.mlx - Example Usage of OncDiscovery Location Service +% examples/OncDiscoveryProperties.mlx - Example Usage of OncDiscovery Properties Service +% examples/OncDiscoveryDataProducts.mlx - Example Usage of OncDiscovery DataProducts Service +% examples/OncDiscoveryDeployments.mlx - Example Usage of OncDiscovery Deployments Service +% examples/OncDiscoveryDeviceCategories.mlx - Example Usage of OncDiscovery Device Categories Service +% examples/OncDiscoveryDevices.mlx - Example Usage of OncDiscovery Devices Service +% examples/OncRealTime.mlx - Example Usage of OncRealTime Service +% examples/OncDeliveryDataProducts.mlx - Example Usage of OncDelivery Service +% examples/OncArchive.mlx - Example Usage of OncArchive Service % % Copyright 2024, ONC Data Team \ No newline at end of file From 1268ee7264d8b326cb6df8e2ae692616d2575d97 Mon Sep 17 00:00:00 2001 From: Ben Biffard <75852191+bbiffard@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:27:52 -0700 Subject: [PATCH 33/35] issue-20: code review changes --- doc/ExampleLinks.html | 2 +- doc/helptoc.xml | 2 +- onc/examples/OncArchive.mlx | Bin 6732 -> 6741 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ExampleLinks.html b/doc/ExampleLinks.html index df2fa66..7f13fa9 100644 --- a/doc/ExampleLinks.html +++ b/doc/ExampleLinks.html @@ -76,7 +76,7 @@

                  Contents

                • Discovery service examples - Data Products
                • Discovery service examples - Deployments
                • Delivery service examples
                • -
                • Archive service examples
                • +
                • Archive File service examples
                • Near Real-time service examples
                diff --git a/doc/helptoc.xml b/doc/helptoc.xml index 9ef51e8..4b52eb6 100644 --- a/doc/helptoc.xml +++ b/doc/helptoc.xml @@ -3,7 +3,7 @@ ONC Toolbox - How to use1 + How to use Getting Started with this library Onc class diff --git a/onc/examples/OncArchive.mlx b/onc/examples/OncArchive.mlx index 091ba102ac8ae4798f49773b678d864a5d3e6883..9153fbad8e6024ae03b3b4ed3a499bba7cfff645 100644 GIT binary patch delta 4379 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 K*bh|yq5lj05_Q!8 From e2c6dabf594c8439511b98a4005add7334afd097 Mon Sep 17 00:00:00 2001 From: Ben Biffard <75852191+bbiffard@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:46:53 -0700 Subject: [PATCH 34/35] issue-21: minor review changes --- onc/+util/checkVersion.m | 52 ++++++++++++++++++++-------------------- onc/Contents.m | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/onc/+util/checkVersion.m b/onc/+util/checkVersion.m index bf1b554..5fdc65d 100644 --- a/onc/+util/checkVersion.m +++ b/onc/+util/checkVersion.m @@ -1,30 +1,30 @@ function checkVersion() - url = 'https://github.com/OceanNetworksCanada/api-matlab-client/releases/latest'; - try - % get latest version - releaseInfo = webread(url); - versionPattern = 'Release (\d+\.\d+\.\d+)'; - version = regexp(releaseInfo, versionPattern, 'tokens', 'once'); - latestVersion = version{1}; - % get local version - librariesVersion = ver; - localVersion ='0.0.0'; - for i = librariesVersion - if strcmp(i.Name,'Ocean Networks Canada API Client Library') - localVersion = i.Version; - break; - end +url = 'https://github.com/OceanNetworksCanada/api-matlab-client/releases/latest'; +try + % get latest version + releaseInfo = webread(url); + versionPattern = '<title>Release (\d+\.\d+\.\d+)'; + version = regexp(releaseInfo, versionPattern, 'tokens', 'once'); + latestVersion = version{1}; + % get local version + librariesVersion = ver; + localVersion = '0.0.0'; + for i = librariesVersion + if strcmp(i.Name, 'Ocean Networks Canada API Client Library') + localVersion = i.Version; + break; end + end - % compare - if ~strcmp(localVersion, latestVersion) - [oncFolderPath, ~, ~] = fileparts(which('Onc')); - localFilePath = [oncFolderPath '\..\doc\UpdateInstruction.html']; - formattedPath = ['file:///', strrep(localFilePath, '\', '/')]; - link = sprintf('<a href="%s">How to update this library</a>', formattedPath); - warning(['You are using an outdated version(%s) of the library. Update to the latest version(%s) to avoid potential errors. ' ... - 'For instructions on updating to the latest version, please visit: %s'], localVersion, latestVersion, link); - end - catch ME - % do nothing + % compare + if ~strcmp(localVersion, latestVersion) + [oncFolderPath, ~, ~] = fileparts(which('Onc')); + localFilePath = [oncFolderPath '\..\doc\UpdateInstruction.html']; + formattedPath = ['file:///', strrep(localFilePath, '\', '/')]; + link = sprintf('<a href="%s">How to update this library</a>', formattedPath); + warning(['You are using an outdated version(%s) of the library. Update to the latest version(%s) to avoid potential errors. ' ... + 'For instructions on updating to the latest version, please visit: %s'], localVersion, latestVersion, link); end +catch ME %#ok<NASGU> + % do nothing +end diff --git a/onc/Contents.m b/onc/Contents.m index 1028a63..4af7611 100644 --- a/onc/Contents.m +++ b/onc/Contents.m @@ -20,4 +20,4 @@ % examples/OncDeliveryDataProducts.mlx - Example Usage of OncDelivery Service % examples/OncArchive.mlx - Example Usage of OncArchive Service % -% Copyright 2024, ONC Data Team \ No newline at end of file +% Copyright 2024 Ocean Networks Canada \ No newline at end of file From dd3b1edf128832564de025c41b8537f647b02bea Mon Sep 17 00:00:00 2001 From: IslaLi <148501293+IslaLi@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:59:41 -0700 Subject: [PATCH 35/35] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ee6af7a..b8a69a4 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ [![View Ocean Networks Canada API Client Library on File Exchange](https://www.mathworks.com/matlabcentral/images/matlab-file-exchange.svg)](https://www.mathworks.com/matlabcentral/fileexchange/74065-ocean-networks-canada-api-client-library) This library facilitates access to scientific data hosted by [Ocean Networks Canada](https://oceannetworks.ca) through the -[Oceans 2.0 API](https://wiki.oceannetworks.ca/display/O2A/Oceans+2.0+API+Home) public web services. +[Oceans 3.0 API](https://wiki.oceannetworks.ca/display/O2A/Oceans+3.0+API+Home) public web services. This repository is synchronized to the [MATLAB ONC API Client Add-On](https://www.mathworks.com/matlabcentral/fileexchange/74065-ocean-networks-canada-api-client-library) which can be installed from the MATLAB Add-on explorer (please search for the "onc" Add-on). ## Documentation -For complete documentation and examples, visit https://wiki.oceannetworks.ca/display/O2A/Client+Libraries +For complete documentation and examples, visit [ONC File Exchange](https://www.mathworks.com/matlabcentral/fileexchange/74065-ocean-networks-canada-api-client-library) ## Maintainers