iotagent-node-lib 2.19.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  2. package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  3. package/.nyc_output/processinfo/index.json +1 -0
  4. package/.readthedocs.yml +3 -1
  5. package/CHANGES_NEXT_RELEASE +1 -0
  6. package/README.md +5 -56
  7. package/doc/Contribution.md +3 -3
  8. package/doc/advanced-topics.md +8 -41
  9. package/doc/api.md +14 -3
  10. package/doc/expressionLanguage.md +17 -0
  11. package/doc/northboundinteractions.md +40 -33
  12. package/doc/operations.md +8 -5
  13. package/doc/requirements.txt +4 -0
  14. package/{docs → doc}/roadmap.md +21 -6
  15. package/doc/usermanual.md +4 -4
  16. package/docker/Mosquitto/Dockerfile +28 -12
  17. package/docker/Mosquitto/README.md +8 -7
  18. package/docker/Mosquitto/startMosquitto.sh +8 -0
  19. package/lib/fiware-iotagent-lib.js +1 -2
  20. package/lib/jexlTranformsMap.js +3 -1
  21. package/lib/model/Group.js +2 -1
  22. package/lib/model/dbConn.js +4 -0
  23. package/lib/plugins/expressionPlugin.js +56 -21
  24. package/lib/plugins/multiEntity.js +43 -49
  25. package/lib/plugins/pluginUtils.js +16 -0
  26. package/lib/services/commands/commandService.js +29 -2
  27. package/lib/services/common/domain.js +6 -2
  28. package/lib/services/common/iotManagerService.js +2 -1
  29. package/lib/services/devices/deviceRegistryMemory.js +13 -2
  30. package/lib/services/devices/deviceRegistryMongoDB.js +15 -7
  31. package/lib/services/devices/deviceService.js +52 -16
  32. package/lib/services/groups/groupRegistryMongoDB.js +13 -12
  33. package/lib/services/ngsi/entities-NGSI-LD.js +13 -4
  34. package/lib/services/ngsi/entities-NGSI-v2.js +8 -6
  35. package/lib/services/ngsi/ngsiService.js +3 -3
  36. package/lib/services/northBound/contextServer-NGSI-LD.js +20 -1
  37. package/lib/services/northBound/contextServer-NGSI-v2.js +39 -30
  38. package/lib/services/northBound/contextServerUtils.js +10 -10
  39. package/lib/services/northBound/deviceProvisioningServer.js +4 -1
  40. package/lib/templates/createDevice.json +13 -2
  41. package/lib/templates/createDeviceLax.json +2 -3
  42. package/lib/templates/updateDevice.json +13 -2
  43. package/package.json +27 -33
  44. package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +14 -0
  45. package/test/unit/mongodb/mongoDBUtils.js +2 -2
  46. package/test/unit/mongodb/mongodb-group-registry-test.js +1 -1
  47. package/test/unit/mongodb/mongodb-registry-test.js +2 -3
  48. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +2 -1
  49. package/test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json +15 -0
  50. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +315 -1
  51. package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +112 -0
  52. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +1 -1
  53. package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +8 -0
  54. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +6 -0
  55. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin35.json +2 -0
  56. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +1 -0
  57. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +27 -0
  58. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +63 -2
  59. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +151 -0
  60. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +63 -0
  61. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +60 -0
  62. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +2 -1
  63. package/bin/agentConsole.js +0 -257
  64. package/bin/iotAgentTester.js +0 -44
  65. package/lib/command/commandLine.js +0 -918
  66. package/lib/command/migration.js +0 -176
  67. package/test/unit/general/migration-test.js +0 -257
@@ -1,176 +0,0 @@
1
- /*
2
- * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
3
- *
4
- * This file is part of fiware-iotagent-lib
5
- *
6
- * fiware-iotagent-lib is free software: you can redistribute it and/or
7
- * modify it under the terms of the GNU Affero General Public License as
8
- * published by the Free Software Foundation, either version 3 of the License,
9
- * or (at your option) any later version.
10
- *
11
- * fiware-iotagent-lib is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
- * See the GNU Affero General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Affero General Public
17
- * License along with fiware-iotagent-lib.
18
- * If not, see http://www.gnu.org/licenses/.
19
- *
20
- * For those usages not covered by the GNU Affero General Public License
21
- * please contact with::[contacto@tid.es]
22
- */
23
-
24
- /* eslint-disable no-prototype-builtins */
25
-
26
- const async = require('async');
27
- const logger = require('logops');
28
- const apply = async.apply;
29
- const MongoClient = require('mongodb').MongoClient;
30
- const serviceTranslation = {
31
- apikey: 'apikey',
32
- token: 'trust',
33
- cbroker: 'cbHost',
34
- entity_type: 'type',
35
- resource: 'resource',
36
- service: 'service',
37
- service_path: 'subservice',
38
- attributes: 'attributes',
39
- static_attributes: 'staticAttributes'
40
- };
41
- const deviceTranslation = {
42
- device_id: 'id',
43
- entity_name: 'name',
44
- entity_type: 'type',
45
- endpoint: 'endpoint',
46
- timezone: 'timezone',
47
- service: 'service',
48
- service_path: 'subservice',
49
- protocol: 'protocol',
50
- attributes: 'active',
51
- static_attributes: 'staticAttributes',
52
- commands: 'commands',
53
- registration_id: 'registrationId'
54
- };
55
- const context = {
56
- op: 'IoTAgentNGSI.MigrationTool'
57
- };
58
-
59
- function connectToDb(dbConfig, dbName, callback) {
60
- const url = 'mongodb://' + dbConfig.host + ':' + (dbConfig.port || 27017) + '/' + dbName;
61
-
62
- MongoClient.connect(url, { useNewUrlParser: true }, callback);
63
- }
64
-
65
- function generateCollectionTranslator(translationKey) {
66
- function translateItem(item, innerCb) {
67
- const translatedItem = {};
68
-
69
- for (const i in item) {
70
- if (item.hasOwnProperty(i) && translationKey[i]) {
71
- translatedItem[translationKey[i]] = item[i];
72
- } else if (i !== '_id') {
73
- logger.warn(context, 'Attribute [%s] was not found for item translation', i);
74
- }
75
- }
76
-
77
- innerCb(null, translatedItem);
78
- }
79
-
80
- return function translateCollection(docs, innerCb) {
81
- async.map(docs, translateItem, innerCb);
82
- };
83
- }
84
-
85
- function migrate(dbConfig, originDb, targetDb, service, subservice, callback) {
86
- function saveToTargetDb(db, collection, docs, innerCb) {
87
- if (docs.length > 0) {
88
- db.db()
89
- .collection(collection)
90
- /* eslint-disable-next-line no-unused-vars */
91
- .insertMany(docs, function (error, inserts) {
92
- innerCb(error);
93
- });
94
- } else {
95
- innerCb();
96
- }
97
- }
98
-
99
- function setDefaultName(item, innerCb) {
100
- if (!item.name || item.name === '') {
101
- item.name = item.type + ':' + item.id;
102
- }
103
-
104
- innerCb(null, item);
105
- }
106
-
107
- function applyDefaultName(docs, innerCb) {
108
- async.map(docs, setDefaultName, innerCb);
109
- }
110
-
111
- function translateProtocol(item, innerCb) {
112
- if (item.protocol && dbConfig.protocols && dbConfig.protocols[item.protocol]) {
113
- item.protocol = dbConfig.protocols[item.protocol];
114
- }
115
-
116
- innerCb(null, item);
117
- }
118
-
119
- function applyProtocolTranslations(docs, innerCb) {
120
- async.map(docs, translateProtocol, innerCb);
121
- }
122
-
123
- function getCollection(db, name, service, subservice, innerCb) {
124
- const query = {};
125
-
126
- if (service) {
127
- query.service = service;
128
- }
129
-
130
- if (subservice) {
131
- query.service_path = subservice;
132
- }
133
-
134
- db.db().collection(name).find(query).toArray(innerCb);
135
- }
136
-
137
- function closeDb(db, innerCb) {
138
- /* eslint-disable-next-line no-unused-vars */
139
- db.close(function (error) {
140
- innerCb();
141
- });
142
- }
143
-
144
- function startMigration(dbResults, innerCb) {
145
- const originDb = dbResults[0];
146
- const targetDb = dbResults[1];
147
-
148
- async.waterfall(
149
- [
150
- apply(getCollection, originDb, 'SERVICE', service, subservice),
151
- generateCollectionTranslator(serviceTranslation),
152
- apply(saveToTargetDb, targetDb, 'groups'),
153
- apply(getCollection, originDb, 'DEVICE', service, subservice),
154
- generateCollectionTranslator(deviceTranslation),
155
- applyDefaultName,
156
- applyProtocolTranslations,
157
- apply(saveToTargetDb, targetDb, 'devices'),
158
- apply(closeDb, originDb),
159
- apply(closeDb, targetDb)
160
- ],
161
- function (error) {
162
- innerCb(error);
163
- }
164
- );
165
- }
166
-
167
- async.waterfall(
168
- [
169
- apply(async.series, [apply(connectToDb, dbConfig, originDb), apply(connectToDb, dbConfig, targetDb)]),
170
- startMigration
171
- ],
172
- callback
173
- );
174
- }
175
-
176
- exports.migrate = migrate;
@@ -1,257 +0,0 @@
1
- /*
2
- * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
3
- *
4
- * This file is part of fiware-iotagent-lib
5
- *
6
- * fiware-iotagent-lib is free software: you can redistribute it and/or
7
- * modify it under the terms of the GNU Affero General Public License as
8
- * published by the Free Software Foundation, either version 3 of the License,
9
- * or (at your option) any later version.
10
- *
11
- * fiware-iotagent-lib is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
- * See the GNU Affero General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Affero General Public
17
- * License along with fiware-iotagent-lib.
18
- * If not, see http://www.gnu.org/licenses/.
19
- *
20
- * For those usages not covered by the GNU Affero General Public License
21
- * please contact with::[contacto@tid.es]
22
- */
23
-
24
- /* eslint-disable no-unused-vars */
25
-
26
- const migration = require('../../../lib/command/migration');
27
- const mongo = require('mongodb').MongoClient;
28
- const mongoUtils = require('../mongodb/mongoDBUtils');
29
- const utils = require('../../tools/utils');
30
- const request = utils.request;
31
- const logger = require('logops');
32
- const async = require('async');
33
- const apply = async.apply;
34
- const should = require('should');
35
- const deviceCollection = utils.readExampleFile('./test/unit/examples/mongoCollections/devices.json');
36
- const configurationCollection = utils.readExampleFile('./test/unit/examples/mongoCollections/configurations.json');
37
- let originDb;
38
- let targetDb;
39
-
40
- describe('MongoDB migration', function () {
41
- beforeEach(function (done) {
42
- logger.setLevel('FATAL');
43
-
44
- mongo.connect('mongodb://localhost:27017/iotOrigin', { useNewUrlParser: true }, function (err, client) {
45
- originDb = client;
46
- mongo.connect('mongodb://localhost:27017/iotTarget', { useNewUrlParser: true }, function (err, client) {
47
- targetDb = client;
48
- async.series(
49
- [
50
- apply(mongoUtils.populate, 'localhost', 'iotOrigin', deviceCollection, 'DEVICE'),
51
- apply(mongoUtils.populate, 'localhost', 'iotOrigin', configurationCollection, 'SERVICE')
52
- ],
53
- done
54
- );
55
- });
56
- });
57
- });
58
-
59
- afterEach(function (done) {
60
- mongoUtils.cleanDb('localhost', 'iotTarget', function (error) {
61
- mongoUtils.cleanDb('localhost', 'iotOrigin', function (error) {
62
- originDb.close(function (error) {
63
- targetDb.close(function (error) {
64
- done();
65
- });
66
- });
67
- });
68
- });
69
- });
70
-
71
- describe('When the full migration command is executed for two databases', function () {
72
- const config = {
73
- host: 'localhost',
74
- port: '27017'
75
- };
76
-
77
- it('should migrate all the services', function (done) {
78
- migration.migrate(config, 'iotOrigin', 'iotTarget', null, null, function () {
79
- targetDb
80
- .db()
81
- .collection('groups')
82
- .find({})
83
- .toArray(function (err, docs) {
84
- should.not.exist(err);
85
- docs.length.should.equal(3);
86
- done();
87
- });
88
- });
89
- });
90
- it('should migrate all the devices', function (done) {
91
- migration.migrate(config, 'iotOrigin', 'iotTarget', null, null, function () {
92
- targetDb
93
- .db()
94
- .collection('devices')
95
- .find({})
96
- .toArray(function (err, docs) {
97
- should.not.exist(err);
98
- docs.length.should.equal(4);
99
- done();
100
- });
101
- });
102
- });
103
- it('should migrate all the fields for each device', function (done) {
104
- migration.migrate(config, 'iotOrigin', 'iotTarget', null, null, function () {
105
- targetDb
106
- .db()
107
- .collection('groups')
108
- .find({
109
- service: 'dumb_mordor'
110
- })
111
- .toArray(function (err, docs) {
112
- should.not.exist(err);
113
- docs.length.should.equal(1);
114
- should.exist(docs[0].apikey);
115
- should.exist(docs[0].cbHost);
116
- should.exist(docs[0].resource);
117
- should.exist(docs[0].service);
118
- should.exist(docs[0].subservice);
119
- should.exist(docs[0].type);
120
- should.exist(docs[0].staticAttributes);
121
- done();
122
- });
123
- });
124
- });
125
- it('should migrate all the fields for each service', function (done) {
126
- migration.migrate(config, 'iotOrigin', 'iotTarget', null, null, function () {
127
- targetDb
128
- .db()
129
- .collection('devices')
130
- .find({
131
- id: 'gk20'
132
- })
133
- .toArray(function (err, docs) {
134
- should.not.exist(err);
135
- docs.length.should.equal(1);
136
- should.exist(docs[0].id);
137
- should.exist(docs[0].name);
138
- should.exist(docs[0].protocol);
139
- should.exist(docs[0].service);
140
- should.exist(docs[0].subservice);
141
- should.exist(docs[0].type);
142
- should.exist(docs[0].active);
143
- should.exist(docs[0].staticAttributes);
144
- docs[0].id = 'gk20';
145
- docs[0].name = 'The GK20 Entity';
146
- docs[0].protocol = 'PDI-IoTA-UltraLight';
147
- docs[0].service = 'smart_gondor';
148
- docs[0].subservice = '/gardens';
149
- docs[0].type = 'acme.lights.sensor';
150
- done();
151
- });
152
- });
153
- });
154
- });
155
-
156
- describe('When a service migration command is executed', function () {
157
- const config = {
158
- host: 'localhost',
159
- port: '27017'
160
- };
161
-
162
- it("should migrate just the service's configurations", function (done) {
163
- migration.migrate(config, 'iotOrigin', 'iotTarget', 'smart_gondor', null, function () {
164
- targetDb
165
- .db()
166
- .collection('groups')
167
- .find({})
168
- .toArray(function (err, docs) {
169
- should.not.exist(err);
170
- docs.length.should.equal(1);
171
- done();
172
- });
173
- });
174
- });
175
- it("should migrate just the service's devices", function (done) {
176
- migration.migrate(config, 'iotOrigin', 'iotTarget', 'smart_gondor', null, function () {
177
- targetDb
178
- .db()
179
- .collection('devices')
180
- .find({})
181
- .toArray(function (err, docs) {
182
- should.not.exist(err);
183
- docs.length.should.equal(3);
184
- done();
185
- });
186
- });
187
- });
188
- });
189
-
190
- describe('When a device has an empty string in its name', function () {
191
- const config = {
192
- host: 'localhost',
193
- port: '27017'
194
- };
195
-
196
- it('should set the name as undefined', function (done) {
197
- migration.migrate(config, 'iotOrigin', 'iotTarget', 'dumb_mordor', null, function () {
198
- targetDb
199
- .db()
200
- .collection('devices')
201
- .find({})
202
- .toArray(function (err, docs) {
203
- docs.length.should.equal(1);
204
- should.exist(docs[0].name);
205
- docs[0].name.should.equal(docs[0].type + ':' + docs[0].id);
206
- done();
207
- });
208
- });
209
- });
210
- });
211
-
212
- describe('When a subservice migration command is executed', function () {
213
- const config = {
214
- host: 'localhost',
215
- port: '27017'
216
- };
217
-
218
- it("should migrate just the subservice's devices", function (done) {
219
- migration.migrate(config, 'iotOrigin', 'iotTarget', 'smart_gondor', '/gardens', function () {
220
- targetDb
221
- .db()
222
- .collection('devices')
223
- .find({})
224
- .toArray(function (err, docs) {
225
- should.not.exist(err);
226
- docs.length.should.equal(1);
227
- done();
228
- });
229
- });
230
- });
231
- });
232
-
233
- describe('When a subservice migration configuration has a protocol translation table', function () {
234
- const config = {
235
- host: 'localhost',
236
- port: '27017',
237
- protocols: {
238
- 'PDI-IoTA-UltraLight': 'NODE-Ultralight'
239
- }
240
- };
241
-
242
- it('should change the protocol to the translated one', function (done) {
243
- migration.migrate(config, 'iotOrigin', 'iotTarget', 'smart_gondor', '/gardens', function () {
244
- targetDb
245
- .db()
246
- .collection('devices')
247
- .find({})
248
- .toArray(function (err, docs) {
249
- should.not.exist(err);
250
- docs.length.should.equal(1);
251
- docs[0].protocol.should.equal('NODE-Ultralight');
252
- done();
253
- });
254
- });
255
- });
256
- });
257
- });