From 3745b88dd5bd1273849e436943dcff6fab86c45c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Arranz?= Date: Mon, 2 Apr 2018 17:03:37 +0200 Subject: [PATCH 1/2] Restructure v1 endpoints --- NGSI.js | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/NGSI.js b/NGSI.js index 5eb3856..ca933ce 100644 --- a/NGSI.js +++ b/NGSI.js @@ -243,17 +243,19 @@ } NGSI.endpoints = { - REGISTER_CONTEXT: 'v1/registry/registerContext', - DISCOVER_CONTEXT_AVAILABILITY: 'v1/registry/discoverContextAvailability', - SUBSCRIBE_CONTEXT_AVAILABILITY: 'v1/registry/subscribeContextAvailability', - UPDATE_CONTEXT_AVAILABILITY_SUBSCRIPTION: 'v1/registry/updateContextAvailabilitySubscription', - UNSUBSCRIBE_CONTEXT_AVAILABILITY: 'v1/registry/unsubscribeContextAvailability', - QUERY_CONTEXT: 'v1/queryContext', - UPDATE_CONTEXT: 'v1/updateContext', - SUBSCRIBE_CONTEXT: 'v1/subscribeContext', - UPDATE_CONTEXT_SUBSCRIPTION: 'v1/updateContextSubscription', - UNSUBSCRIBE_CONTEXT: 'v1/unsubscribeContext', - CONTEXT_TYPES: 'v1/contextTypes', + v1: { + REGISTER_CONTEXT: 'v1/registry/registerContext', + DISCOVER_CONTEXT_AVAILABILITY: 'v1/registry/discoverContextAvailability', + SUBSCRIBE_CONTEXT_AVAILABILITY: 'v1/registry/subscribeContextAvailability', + UPDATE_CONTEXT_AVAILABILITY_SUBSCRIPTION: 'v1/registry/updateContextAvailabilitySubscription', + UNSUBSCRIBE_CONTEXT_AVAILABILITY: 'v1/registry/unsubscribeContextAvailability', + QUERY_CONTEXT: 'v1/queryContext', + UPDATE_CONTEXT: 'v1/updateContext', + SUBSCRIBE_CONTEXT: 'v1/subscribeContext', + UPDATE_CONTEXT_SUBSCRIPTION: 'v1/updateContextSubscription', + UNSUBSCRIBE_CONTEXT: 'v1/unsubscribeContext', + CONTEXT_TYPES: 'v1/contextTypes' + }, v2: { BATCH_QUERY_OP: 'v2/op/query', @@ -1763,7 +1765,7 @@ } var payload = ngsi_build_register_context_request(entities, attributes, duration, providingApplication); - var url = new URL(NGSI.endpoints.REGISTER_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.REGISTER_CONTEXT, this.url); makeJSONRequest.call(this, url, payload, parse_register_context_response, callbacks); }; @@ -1835,7 +1837,7 @@ } var payload = ngsi_build_register_context_request(entities, attributes, duration, providingApplication, regId); - var url = new URL(NGSI.endpoints.REGISTER_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.REGISTER_CONTEXT, this.url); return makeJSONRequest.call(this, url, payload, parse_register_context_response, callbacks); }; @@ -1927,7 +1929,7 @@ } var payload = ngsi_build_discover_context_availability_request(entities, attributeNames); - var url = new URL(NGSI.endpoints.DISCOVER_CONTEXT_AVAILABILITY, this.url); + var url = new URL(NGSI.endpoints.v1.DISCOVER_CONTEXT_AVAILABILITY, this.url); makeJSONRequest.call(this, url, payload, parse_discover_context_availability_response, callbacks); }; @@ -1986,7 +1988,7 @@ throw new TypeError('A ngsi-proxy is needed for using local onNotify callbacks'); } - var url = new URL(NGSI.endpoints.SUBSCRIBE_CONTEXT_AVAILABILITY, this.url); + var url = new URL(NGSI.endpoints.v1.SUBSCRIBE_CONTEXT_AVAILABILITY, this.url); if (typeof options.onNotify === 'function' && this.ngsi_proxy != null) { var onNotify = function onNotify(payload) { @@ -2079,7 +2081,7 @@ } var payload = ngsi_build_subscribe_update_context_availability_request(entities, attributeNames, duration, restriction, subId); - var url = new URL(NGSI.endpoints.UPDATE_CONTEXT_AVAILABILITY_SUBSCRIPTION, this.url); + var url = new URL(NGSI.endpoints.v1.UPDATE_CONTEXT_AVAILABILITY_SUBSCRIPTION, this.url); makeJSONRequest.call(this, url, payload, parse_subscribe_update_context_availability_response, callbacks); }; @@ -2112,7 +2114,7 @@ } var payload = ngsi_build_unsubscribe_context_availability_request(subId); - var url = new URL(NGSI.endpoints.UNSUBSCRIBE_CONTEXT_AVAILABILITY, this.url); + var url = new URL(NGSI.endpoints.v1.UNSUBSCRIBE_CONTEXT_AVAILABILITY, this.url); makeJSONRequest.call(this, url, payload, parse_unsubscribe_context_availability_response, callbacks); }; @@ -2181,7 +2183,7 @@ parameters = parse_pagination_options(options, 'off'); - url = new URL(NGSI.endpoints.QUERY_CONTEXT, this.url); + url = new URL(NGSI.endpoints.v1.QUERY_CONTEXT, this.url); payload = ngsi_build_query_context_request(entities, attributesName, options.restriction); makeJSONRequest.call(this, url, payload, parse_query_context_response, options, parameters); }; @@ -2232,7 +2234,7 @@ } var payload = ngsi_build_update_context_request('UPDATE', update); - var url = new URL(NGSI.endpoints.UPDATE_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.UPDATE_CONTEXT, this.url); makeJSONRequest.call(this, url, payload, parse_update_context_response, callbacks); }; @@ -2282,7 +2284,7 @@ } var payload = ngsi_build_update_context_request('APPEND', toAdd); - var url = new URL(NGSI.endpoints.UPDATE_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.UPDATE_CONTEXT, this.url); makeJSONRequest.call(this, url, payload, parse_update_context_response, callbacks); }; @@ -2345,7 +2347,7 @@ } var payload = ngsi_build_update_context_request('DELETE', toDelete); - var url = new URL(NGSI.endpoints.UPDATE_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.UPDATE_CONTEXT, this.url); makeJSONRequest.call(this, url, payload, parse_update_context_response, callbacks); }; @@ -2431,7 +2433,7 @@ throw new TypeError('A ngsi-proxy is needed for using local onNotify callbacks'); } - var url = new URL(NGSI.endpoints.SUBSCRIBE_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.SUBSCRIBE_CONTEXT, this.url); if (typeof options.onNotify === 'function' && this.ngsi_proxy != null) { var onNotify = function onNotify(payload) { @@ -2539,7 +2541,7 @@ } var payload = ngsi_build_subscribe_update_context_request(subId, null, null, duration, throttling, cond); - var url = new URL(NGSI.endpoints.UPDATE_CONTEXT_SUBSCRIPTION, this.url); + var url = new URL(NGSI.endpoints.v1.UPDATE_CONTEXT_SUBSCRIPTION, this.url); makeJSONRequest.call(this, url, payload, parse_update_context_subscription_response, options); }; @@ -2593,7 +2595,7 @@ }.bind(this); } var payload = ngsi_build_unsubscribe_context_request(subId); - var url = new URL(NGSI.endpoints.UNSUBSCRIBE_CONTEXT, this.url); + var url = new URL(NGSI.endpoints.v1.UNSUBSCRIBE_CONTEXT, this.url); makeJSONRequest.call(this, url, payload, parse_unsubscribe_context_response, options); }; @@ -2632,7 +2634,7 @@ * */ NGSI.Connection.prototype.getAvailableTypes = function getAvailableTypes(options) { - var url = new URL(NGSI.endpoints.CONTEXT_TYPES, this.url); + var url = new URL(NGSI.endpoints.v1.CONTEXT_TYPES, this.url); var parameters = parse_pagination_options(options, 'on'); makeJSONRequest.call(this, url, null, parse_available_types_response, options, parameters); }; @@ -2674,7 +2676,7 @@ throw new TypeError("Invalid type parameter"); } - var url = new URL(NGSI.endpoints.CONTEXT_TYPES + '/' + encodeURIComponent(type), this.url); + var url = new URL(NGSI.endpoints.v1.CONTEXT_TYPES + '/' + encodeURIComponent(type), this.url); makeJSONRequest.call(this, url, null, parse_type_info_response, options); }; From fc2ad72ce5d766cd7a9957a93c915be375668e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Arranz?= Date: Mon, 2 Apr 2018 17:19:52 +0200 Subject: [PATCH 2/2] Initial implementation of the getServerDetails method. Fix #16 --- .eslintrc-jasmine | 3 +- NGSI.js | 66 +++++++++++++++++++++++++ tests/ConnectionSpec.js | 107 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 174 insertions(+), 2 deletions(-) diff --git a/.eslintrc-jasmine b/.eslintrc-jasmine index d2f2026..de84358 100644 --- a/.eslintrc-jasmine +++ b/.eslintrc-jasmine @@ -1,6 +1,7 @@ { "extends": ".eslintrc", "env": { - "jasmine": true + "jasmine": true, + "es6": true } } diff --git a/NGSI.js b/NGSI.js index ca933ce..25f36ee 100644 --- a/NGSI.js +++ b/NGSI.js @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2017 CoNWeT Lab., Universidad Politécnica de Madrid + * Copyright (c) 2018 Future Internet Consulting and Development Solutions S.L. * * This file is part of ngsijs. * @@ -243,6 +244,8 @@ } NGSI.endpoints = { + SERVER_DETAILS: 'version', + v1: { REGISTER_CONTEXT: 'v1/registry/registerContext', DISCOVER_CONTEXT_AVAILABILITY: 'v1/registry/discoverContextAvailability', @@ -1695,6 +1698,69 @@ }); }; + /** + * Retrieves context broker server information. + * + * @name NGSI.Connection@getServerDetails + * @memberof NGSI.Connection + * @method "getServerDetails" + * + * @param {Object} [options] + * + * Object with extra options: + * + * - `correlator` (`String`): Transaction id + * + * @returns {Promise} + * + * @example + * + * connection.getServerDetails().then( + * (response) => { + * // Server information retrieved successfully + * // response.details contains all the details returned by the server. + * // response.correlator transaction id associated with the server response + * }, (error) => { + * // Error retrieving server information + * // If the error was reported by Orion, error.correlator will be + * // filled with the associated transaction id + * } + * ); + */ + NGSI.Connection.prototype.getServerDetails = function getServerDetails(options) { + if (options == null) { + options = {}; + } + + var url = new URL(NGSI.endpoints.SERVER_DETAILS, this.url); + return makeJSONRequest2.call(this, url, { + method: "GET", + requestHeaders: { + "FIWARE-Correlator": options.correlator, + } + }).then(function (response) { + var correlator = response.getHeader('Fiware-correlator'); + + if (response.status !== 200) { + return Promise.reject(new NGSI.InvalidResponseError('Unexpected error code: ' + response.status, correlator)); + } + + try { + var data = JSON.parse(response.responseText); + } catch (e) { + return Promise.reject(new NGSI.InvalidResponseError('Server returned invalid JSON content', correlator)); + } + + var result = { + details: data, + correlator: correlator + }; + + return Promise.resolve(result); + }); + }; + + /** * Registers context information (entities and attributes) into the NGSI * server. diff --git a/tests/ConnectionSpec.js b/tests/ConnectionSpec.js index 7b2d316..22f2190 100644 --- a/tests/ConnectionSpec.js +++ b/tests/ConnectionSpec.js @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 CoNWeT Lab., Universidad Politécnica de Madrid + * Copyright (c) 2018 Future Internet Consulting and Development Solutions S.L. * * This file is part of ngsijs. * @@ -35,7 +36,7 @@ * */ -/* globals NGSI */ +/* globals ajaxMockFactory, NGSI */ (function () { @@ -158,6 +159,110 @@ }); + describe("getServerDetails([options])", () => { + + var connection; + var ajaxMockup = ajaxMockFactory.createFunction(); + const details = { + "orion": { + "version": "1.9.0", + "uptime": "2 d, 20 h, 14 m, 17 s", + "git_hash": "f942277924867ced3682244c31a6df63bfa066e9", + "compile_time": "Wed Nov 22 08:37:00 UTC 2017", + "compiled_by": "root", + "compiled_in": "c663f9f730c9", + "release_date": "Wed Nov 22 08:37:00 UTC 2017", + "doc": "https://fiware-orion.readthedocs.org/en/master/" + } + }; + + beforeEach(function () { + var options = { + requestFunction: ajaxMockup + }; + connection = new NGSI.Connection('http://ngsi.server.com', options); + ajaxMockup.clear(); + }); + + it("provides server details", function (done) { + ajaxMockup.addStaticURL("http://ngsi.server.com/version", { + method: "GET", + headers: { + 'Fiware-correlator': 'correlatortoken', + }, + responseText: JSON.stringify(details), + status: 200 + }); + + connection.getServerDetails().then(function (result) { + expect(result).toEqual({ + details: details, + correlator: 'correlatortoken' + }); + done(); + }, function (e) { + fail("Failure callback called"); + }); + }); + + it("supports the correlator option", function (done) { + ajaxMockup.addStaticURL("http://ngsi.server.com/version", { + method: "GET", + checkRequestContent: function (url, options) { + expect(options.requestHeaders).toEqual(jasmine.objectContaining({ + 'FIWARE-Correlator': 'customcorrelator' + })); + }, + headers: { + 'Fiware-correlator': 'customcorrelator', + }, + responseText: JSON.stringify(details), + status: 200 + }); + + connection.getServerDetails({correlator: "customcorrelator"}).then(function (result) { + expect(result).toEqual({ + details: details, + correlator: 'customcorrelator' + }); + done(); + }, function (e) { + fail("Failure callback called"); + }); + }); + + it("unexpected error code", function (done) { + ajaxMockup.addStaticURL("http://ngsi.server.com/version", { + method: "GET", + status: 404 + }); + + connection.getServerDetails().then(function (value) { + fail("Success callback called"); + }, function (e) { + expect(e).toEqual(jasmine.any(NGSI.InvalidResponseError)); + expect(e.correlator).toBeNull(); + done(); + }); + }); + + it("handles responses with invalid payloads", function (done) { + ajaxMockup.addStaticURL("http://ngsi.server.com/version", { + method: "GET", + status: 200, + responseText: "invalid json content" + }); + + connection.getServerDetails().then(function (value) { + fail("Success callback called"); + }, function (e) { + expect(e).toEqual(jasmine.any(NGSI.InvalidResponseError)); + expect(e.correlator).toBeNull(); + done(); + }); + }); + }); + }); })();