iotagent-node-lib 4.5.0 → 4.7.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 (124) hide show
  1. package/.github/workflows/ci.yml +0 -1
  2. package/Changelog +12 -0
  3. package/README.md +67 -272
  4. package/config.js +3 -1
  5. package/doc/README.md +1 -1
  6. package/doc/admin.md +40 -18
  7. package/doc/api.md +532 -136
  8. package/doc/deprecated.md +4 -0
  9. package/doc/devel/architecture.md +5 -135
  10. package/doc/devel/development.md +224 -12
  11. package/doc/getting-started.md +114 -53
  12. package/doc/requirements.txt +1 -1
  13. package/doc/roadmap.md +5 -5
  14. package/docker/Mosquitto/Dockerfile +2 -2
  15. package/docker/Mosquitto/README.md +14 -11
  16. package/lib/commonConfig.js +21 -2
  17. package/lib/constants.js +3 -0
  18. package/lib/fiware-iotagent-lib.js +12 -15
  19. package/lib/jexlTranformsMap.js +3 -1
  20. package/lib/model/Command.js +2 -2
  21. package/lib/model/Device.js +7 -3
  22. package/lib/model/Group.js +5 -3
  23. package/lib/model/dbConn.js +53 -115
  24. package/lib/services/commands/commandRegistryMongoDB.js +115 -75
  25. package/lib/services/common/alarmManagement.js +3 -0
  26. package/lib/services/common/iotManagerService.js +3 -1
  27. package/lib/services/devices/deviceRegistryMemory.js +36 -0
  28. package/lib/services/devices/deviceRegistryMongoDB.js +160 -87
  29. package/lib/services/devices/deviceService.js +33 -3
  30. package/lib/services/devices/devices-NGSI-v2.js +6 -1
  31. package/lib/services/groups/groupRegistryMongoDB.js +120 -83
  32. package/lib/services/groups/groupService.js +1 -1
  33. package/lib/services/ngsi/entities-NGSI-LD.js +320 -570
  34. package/lib/services/ngsi/entities-NGSI-v2.js +51 -3
  35. package/lib/services/ngsi/ngsiService.js +34 -1
  36. package/lib/services/northBound/deviceGroupAdministrationServer.js +42 -6
  37. package/lib/services/northBound/deviceProvisioningServer.js +12 -4
  38. package/lib/services/northBound/northboundServer.js +2 -0
  39. package/lib/services/stats/statsRegistry.js +128 -101
  40. package/lib/templates/createDevice.json +0 -24
  41. package/lib/templates/createDeviceLax.json +0 -23
  42. package/lib/templates/deviceGroup.json +1 -25
  43. package/lib/templates/updateDevice.json +12 -24
  44. package/lib/templates/updateDeviceLax.json +12 -23
  45. package/package.json +5 -5
  46. package/scripts/legacy_expression_tool/README.md +0 -1
  47. package/test/functional/README.md +22 -17
  48. package/test/functional/config-test.js +3 -2
  49. package/test/functional/functional-tests-runner.js +9 -4
  50. package/test/functional/functional-tests.js +4 -4
  51. package/test/functional/testCases.js +245 -4
  52. package/test/functional/testUtils.js +2 -2
  53. package/test/unit/examples/deviceProvisioningRequests/provisionFullDevice.json +1 -13
  54. package/test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json +44 -0
  55. package/test/unit/examples/groupProvisioningRequests/provisionDuplicateConfigGroup.json +35 -0
  56. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroup.json +36 -0
  57. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroupAlternate.json +36 -0
  58. package/test/unit/examples/groupProvisioningRequests/provisionFullGroup.json +1 -0
  59. package/test/unit/general/config-multi-core-test.js +1 -2
  60. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +5 -4
  61. package/test/unit/general/deviceService-test.js +106 -3
  62. package/test/unit/general/statistics-service_test.js +1 -74
  63. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +6 -5
  64. package/test/unit/mongodb/mongodb-configGroup-registry-test.js +452 -0
  65. package/test/unit/mongodb/mongodb-connectionoptions-test.js +9 -42
  66. package/test/unit/mongodb/mongodb-group-registry-test.js +34 -33
  67. package/test/unit/mongodb/mongodb-service-registry-test.js +477 -0
  68. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +4 -4
  69. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +22 -22
  70. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +4 -4
  71. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +14 -15
  72. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +23 -23
  73. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin15.json +0 -5
  74. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +11 -16
  75. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +23 -28
  76. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +8 -13
  77. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
  78. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +24 -29
  79. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +12 -17
  80. package/test/unit/ngsi-ld/examples/contextRequests/updateContextStaticLinkedAttributes.json +12 -10
  81. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +1 -104
  82. package/test/unit/ngsi-ld/general/config-jsonld-contexts-test.js +1 -2
  83. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +4 -5
  84. package/test/unit/ngsi-ld/provisioning/listProvisionedDevices-test.js +0 -4
  85. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +8 -5
  86. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +42 -41
  87. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +11 -10
  88. package/test/unit/ngsiv2/general/deviceService-test.js +98 -4
  89. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  90. package/test/unit/ngsiv2/general/iotam-autoregistration-test.js +195 -0
  91. package/test/unit/ngsiv2/lazyAndCommands/active-devices-attribute-update-test.js +4 -3
  92. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +6 -5
  93. package/test/unit/ngsiv2/lazyAndCommands/lazy-devices-test.js +17 -16
  94. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +10 -18
  95. package/test/unit/ngsiv2/ngsiService/active-devices-test.js +21 -20
  96. package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +8 -7
  97. package/test/unit/ngsiv2/plugins/alias-plugin_test.js +12 -11
  98. package/test/unit/ngsiv2/plugins/custom-plugin_test.js +3 -2
  99. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +28 -27
  100. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +265 -4
  101. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +12 -11
  102. package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +1190 -0
  103. package/test/unit/ngsiv2/provisioning/device-registration_test.js +5 -4
  104. package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +6 -9
  105. package/test/unit/ngsiv2/provisioning/provisionDeviceMultientity-test.js +1 -1
  106. package/test/unit/ngsiv2/provisioning/removeProvisionedDevice-test.js +5 -4
  107. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +8 -7
  108. package/test/unit/statsRegistry/openmetrics-test.js +167 -0
  109. package/lib/templates/queryContext.json +0 -25
  110. package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +0 -35
  111. package/test/unit/examples/deviceProvisioningRequests/provisionDeviceBidirectionalGroup.json +0 -17
  112. package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +0 -31
  113. package/test/unit/general/statistics-persistence_test.js +0 -121
  114. package/test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json +0 -17
  115. package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +0 -12
  116. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  117. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +0 -21
  118. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -17
  119. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -23
  120. package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +0 -132
  121. package/test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json +0 -8
  122. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  123. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -19
  124. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -24
@@ -23,6 +23,7 @@
23
23
  * Modified by: Daniel Calvo - ATOS Research & Innovation
24
24
  */
25
25
 
26
+ // #FIXME1649: parallel tests in mongodb-configGroup-registry-test.js. Remove this file if at the end /iot/services API (now Deprecated) is removed
26
27
  /* eslint-disable no-unused-vars */
27
28
 
28
29
  const iotAgentLib = require('../../../lib/fiware-iotagent-lib');
@@ -60,10 +61,10 @@ const iotAgentConfig = {
60
61
  const mongo = require('mongodb').MongoClient;
61
62
  const mongoUtils = require('./mongoDBUtils');
62
63
  const optionsCreation = {
63
- url: 'http://localhost:4041/iot/services',
64
+ url: 'http://localhost:4041/iot/groups',
64
65
  method: 'POST',
65
66
  json: {
66
- services: [
67
+ groups: [
67
68
  {
68
69
  resource: '/deviceTest',
69
70
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
@@ -102,7 +103,7 @@ const optionsCreation = {
102
103
  }
103
104
  };
104
105
  const optionsDelete = {
105
- url: 'http://localhost:4041/iot/services',
106
+ url: 'http://localhost:4041/iot/groups',
106
107
  method: 'DELETE',
107
108
  json: {},
108
109
  headers: {
@@ -115,7 +116,7 @@ const optionsDelete = {
115
116
  }
116
117
  };
117
118
  const optionsList = {
118
- url: 'http://localhost:4041/iot/services',
119
+ url: 'http://localhost:4041/iot/groups',
119
120
  method: 'GET',
120
121
  json: {},
121
122
  headers: {
@@ -124,7 +125,7 @@ const optionsList = {
124
125
  }
125
126
  };
126
127
  const optionsUpdate = {
127
- url: 'http://localhost:4041/iot/services',
128
+ url: 'http://localhost:4041/iot/groups',
128
129
  method: 'PUT',
129
130
  json: {
130
131
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
@@ -166,7 +167,7 @@ const optionsUpdate = {
166
167
  }
167
168
  };
168
169
  const optionsGet = {
169
- url: 'http://localhost:4041/iot/services',
170
+ url: 'http://localhost:4041/iot/groups',
170
171
  method: 'GET',
171
172
  json: {},
172
173
  headers: {
@@ -176,7 +177,7 @@ const optionsGet = {
176
177
  };
177
178
  let iotAgentDb;
178
179
 
179
- describe('MongoDB Group Registry test', function () {
180
+ describe('MongoDB Group Registry test', function () {
180
181
  beforeEach(function (done) {
181
182
  mongoUtils.cleanDbs(function () {
182
183
  iotAgentLib.activate(iotAgentConfig, function () {
@@ -309,7 +310,7 @@ describe('MongoDB Group Registry test', function () {
309
310
 
310
311
  beforeEach(function (done) {
311
312
  optionsMultipleCreation.json = utils.readExampleFile(
312
- './test/unit/examples/groupProvisioningRequests/multipleGroupsCreation.json'
313
+ './test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json'
313
314
  );
314
315
 
315
316
  done();
@@ -337,14 +338,14 @@ describe('MongoDB Group Registry test', function () {
337
338
  const optionsCreation2 = _.clone(optionsCreation);
338
339
  const optionsCreation3 = _.clone(optionsCreation);
339
340
 
340
- optionsCreation2.json = { services: [] };
341
- optionsCreation3.json = { services: [] };
341
+ optionsCreation2.json = { groups: [] };
342
+ optionsCreation3.json = { groups: [] };
342
343
 
343
- optionsCreation2.json.services[0] = _.clone(optionsCreation.json.services[0]);
344
- optionsCreation3.json.services[0] = _.clone(optionsCreation.json.services[0]);
344
+ optionsCreation2.json.groups[0] = _.clone(optionsCreation.json.groups[0]);
345
+ optionsCreation3.json.groups[0] = _.clone(optionsCreation.json.groups[0]);
345
346
 
346
- optionsCreation2.json.services[0].apikey = 'qwertyuiop';
347
- optionsCreation3.json.services[0].apikey = 'lkjhgfds';
347
+ optionsCreation2.json.groups[0].apikey = 'qwertyuiop';
348
+ optionsCreation3.json.groups[0].apikey = 'lkjhgfds';
348
349
 
349
350
  async.series(
350
351
  [
@@ -366,7 +367,7 @@ describe('MongoDB Group Registry test', function () {
366
367
 
367
368
  describe('When a device group listing arrives with a limit', function () {
368
369
  const optionsConstrained = {
369
- url: 'http://localhost:4041/iot/services',
370
+ url: 'http://localhost:4041/iot/groups',
370
371
  method: 'GET',
371
372
  qs: {
372
373
  limit: 3,
@@ -385,9 +386,9 @@ describe('MongoDB Group Registry test', function () {
385
386
 
386
387
  for (let i = 0; i < 10; i++) {
387
388
  optionsCreationList[i] = _.clone(optionsCreation);
388
- optionsCreationList[i].json = { services: [] };
389
- optionsCreationList[i].json.services[0] = _.clone(optionsCreation.json.services[0]);
390
- optionsCreationList[i].json.services[0].apikey = 'qwertyuiop' + i;
389
+ optionsCreationList[i].json = { groups: [] };
390
+ optionsCreationList[i].json.groups[0] = _.clone(optionsCreation.json.groups[0]);
391
+ optionsCreationList[i].json.groups[0].apikey = 'qwertyuiop' + i;
391
392
  creationFns.push(async.apply(request, optionsCreationList[i]));
392
393
  }
393
394
 
@@ -412,10 +413,10 @@ describe('MongoDB Group Registry test', function () {
412
413
  should.exist(body);
413
414
  should.exist(body.count);
414
415
  body.count.should.equal(1);
415
- should.exist(body.services);
416
- should.exist(body.services.length);
417
- body.services.length.should.equal(1);
418
- body.services[0].service.should.equal('testservice');
416
+ should.exist(body.groups);
417
+ should.exist(body.groups.length);
418
+ body.groups.length.should.equal(1);
419
+ body.groups[0].service.should.equal('testservice');
419
420
  done();
420
421
  });
421
422
  });
@@ -428,9 +429,9 @@ describe('MongoDB Group Registry test', function () {
428
429
 
429
430
  for (let i = 0; i < 10; i++) {
430
431
  optionsCreationList[i] = _.clone(optionsCreation);
431
- optionsCreationList[i].json = { services: [] };
432
- optionsCreationList[i].json.services[0] = _.clone(optionsCreation.json.services[0]);
433
- optionsCreationList[i].json.services[0].apikey = 'qwertyuiop' + i;
432
+ optionsCreationList[i].json = { groups: [] };
433
+ optionsCreationList[i].json.groups[0] = _.clone(optionsCreation.json.groups[0]);
434
+ optionsCreationList[i].json.groups[0].apikey = 'qwertyuiop' + i;
434
435
  creationFns.push(async.apply(request, optionsCreationList[i]));
435
436
  }
436
437
 
@@ -442,9 +443,9 @@ describe('MongoDB Group Registry test', function () {
442
443
  should.exist(body);
443
444
  should.exist(body.count);
444
445
  body.count.should.equal(10);
445
- should.exist(body.services);
446
- should.exist(body.services.length);
447
- body.services.length.should.equal(10);
446
+ should.exist(body.groups);
447
+ should.exist(body.groups.length);
448
+ body.groups.length.should.equal(10);
448
449
  done();
449
450
  });
450
451
  });
@@ -464,11 +465,11 @@ describe('MongoDB Group Registry test', function () {
464
465
  should.exist(body);
465
466
  should.exist(body.count);
466
467
  body.count.should.equal(1);
467
- should.exist(body.services);
468
- should.exist(body.services.length);
469
- body.services.length.should.equal(1);
470
- should.exist(body.services[0].entity_type);
471
- body.services[0].entity_type.should.equal('Light');
468
+ should.exist(body.groups);
469
+ should.exist(body.groups.length);
470
+ body.groups.length.should.equal(1);
471
+ should.exist(body.groups[0].entity_type);
472
+ body.groups[0].entity_type.should.equal('Light');
472
473
  done();
473
474
  });
474
475
  });
@@ -0,0 +1,477 @@
1
+ /*
2
+ * Copyright 2024 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
+ * Modified by: Daniel Calvo - ATOS Research & Innovation
24
+ */
25
+
26
+ // #FIXME1649: parallel tests in mongodb-configGroup-registry-test.js. Remove this file if at the end /iot/services API (now Deprecated) is removed
27
+ /* eslint-disable no-unused-vars */
28
+
29
+ const iotAgentLib = require('../../../lib/fiware-iotagent-lib');
30
+ const _ = require('underscore');
31
+ const utils = require('../../tools/utils');
32
+ const request = utils.request;
33
+ const async = require('async');
34
+ const should = require('should');
35
+ const iotAgentConfig = {
36
+ logLevel: 'FATAL',
37
+ contextBroker: {
38
+ host: '192.168.1.1',
39
+ port: '1026'
40
+ },
41
+ server: {
42
+ name: 'testAgent',
43
+ port: 4041,
44
+ host: 'localhost',
45
+ baseRoot: '/'
46
+ },
47
+ types: {},
48
+ deviceRegistry: {
49
+ type: 'mongodb'
50
+ },
51
+ mongodb: {
52
+ host: 'localhost',
53
+ port: '27017',
54
+ db: 'iotagent'
55
+ },
56
+ service: 'smartgondor',
57
+ subservice: 'gardens',
58
+ providerUrl: 'http://smartgondor.com',
59
+ deviceRegistrationDuration: 'P1M'
60
+ };
61
+ const mongo = require('mongodb').MongoClient;
62
+ const mongoUtils = require('./mongoDBUtils');
63
+ const optionsCreation = {
64
+ url: 'http://localhost:4041/iot/services',
65
+ method: 'POST',
66
+ json: {
67
+ services: [
68
+ {
69
+ resource: '/deviceTest',
70
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
71
+ entity_type: 'Light',
72
+ trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
73
+ cbHost: 'http://unexistentHost:1026',
74
+ commands: [
75
+ {
76
+ name: 'wheel1',
77
+ type: 'Wheel'
78
+ }
79
+ ],
80
+ lazy: [
81
+ {
82
+ name: 'luminescence',
83
+ type: 'Lumens'
84
+ }
85
+ ],
86
+ attributes: [
87
+ {
88
+ name: 'status',
89
+ type: 'Boolean'
90
+ }
91
+ ],
92
+ internal_attributes: [
93
+ {
94
+ customField: 'customValue'
95
+ }
96
+ ]
97
+ }
98
+ ]
99
+ },
100
+ headers: {
101
+ 'fiware-service': 'testservice',
102
+ 'fiware-servicepath': '/testingPath'
103
+ }
104
+ };
105
+ const optionsDelete = {
106
+ url: 'http://localhost:4041/iot/services',
107
+ method: 'DELETE',
108
+ json: {},
109
+ headers: {
110
+ 'fiware-service': 'testservice',
111
+ 'fiware-servicepath': '/testingPath'
112
+ },
113
+ qs: {
114
+ resource: '/deviceTest',
115
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
116
+ }
117
+ };
118
+ const optionsList = {
119
+ url: 'http://localhost:4041/iot/services',
120
+ method: 'GET',
121
+ json: {},
122
+ headers: {
123
+ 'fiware-service': 'testservice',
124
+ 'fiware-servicepath': '/*'
125
+ }
126
+ };
127
+ const optionsUpdate = {
128
+ url: 'http://localhost:4041/iot/services',
129
+ method: 'PUT',
130
+ json: {
131
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
132
+ trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
133
+ cbHost: 'http://anotherUnexistentHost:1026',
134
+ commands: [
135
+ {
136
+ name: 'wheel1',
137
+ type: 'Wheel'
138
+ }
139
+ ],
140
+ lazy: [
141
+ {
142
+ name: 'luminescence',
143
+ type: 'Lumens'
144
+ }
145
+ ],
146
+ attributes: [
147
+ {
148
+ name: 'status',
149
+ type: 'Boolean'
150
+ }
151
+ ],
152
+ static_attributes: [
153
+ {
154
+ name: 'bootstrapServer',
155
+ type: 'Address',
156
+ value: '127.0.0.1'
157
+ }
158
+ ]
159
+ },
160
+ headers: {
161
+ 'fiware-service': 'testservice',
162
+ 'fiware-servicepath': '/testingPath'
163
+ },
164
+ qs: {
165
+ resource: '/deviceTest',
166
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
167
+ }
168
+ };
169
+ const optionsGet = {
170
+ url: 'http://localhost:4041/iot/services',
171
+ method: 'GET',
172
+ json: {},
173
+ headers: {
174
+ 'fiware-service': 'testservice',
175
+ 'fiware-servicepath': '/testingPath'
176
+ }
177
+ };
178
+ let iotAgentDb;
179
+
180
+ describe('MongoDB Service Registry test', function () {
181
+ beforeEach(function (done) {
182
+ mongoUtils.cleanDbs(function () {
183
+ iotAgentLib.activate(iotAgentConfig, function () {
184
+ mongo.connect('mongodb://localhost:27017/iotagent', function (err, db) {
185
+ iotAgentDb = db;
186
+ done();
187
+ });
188
+ });
189
+ });
190
+ });
191
+
192
+ afterEach(function (done) {
193
+ iotAgentLib.deactivate(function () {
194
+ iotAgentDb.close(function (error) {
195
+ mongoUtils.cleanDbs(done);
196
+ });
197
+ });
198
+ });
199
+ describe('When a new device group creation request arrives', function () {
200
+ it('should store it in the DB', function (done) {
201
+ request(optionsCreation, function (error, response, body) {
202
+ iotAgentDb
203
+ .db()
204
+ .collection('groups')
205
+ .find({})
206
+ .toArray(function (err, docs) {
207
+ should.not.exist(err);
208
+ should.exist(docs);
209
+ should.exist(docs.length);
210
+ docs.length.should.equal(1);
211
+ should.exist(docs[0].type);
212
+ should.exist(docs[0].internalAttributes);
213
+ should.exist(docs[0].attributes);
214
+ should.exist(docs[0].apikey);
215
+ docs[0].type.should.equal('Light');
216
+ docs[0].apikey.should.equal('801230BJKL23Y9090DSFL123HJK09H324HV8732');
217
+ docs[0].internalAttributes.length.should.equal(1);
218
+ docs[0].internalAttributes[0].customField.should.equal('customValue');
219
+ docs[0].attributes.length.should.equal(1);
220
+ docs[0].attributes[0].name.should.equal('status');
221
+ done();
222
+ });
223
+ });
224
+ });
225
+ it('should store the service information from the headers into the DB', function (done) {
226
+ request(optionsCreation, function (error, response, body) {
227
+ iotAgentDb
228
+ .db()
229
+ .collection('groups')
230
+ .find({})
231
+ .toArray(function (err, docs) {
232
+ should.not.exist(err);
233
+ should.exist(docs[0].service);
234
+ should.exist(docs[0].subservice);
235
+ docs[0].service.should.equal('testservice');
236
+ docs[0].subservice.should.equal('/testingPath');
237
+ done();
238
+ });
239
+ });
240
+ });
241
+ });
242
+
243
+ describe('When a new device group creation request arrives with an existant (apikey, resource) pair', function () {
244
+ it('should return a DUPLICATE_GROUP error', function (done) {
245
+ request(optionsCreation, function (error, response, body) {
246
+ request(optionsCreation, function (error, response, body) {
247
+ response.statusCode.should.equal(409);
248
+ body.name.should.equal('DUPLICATE_GROUP');
249
+ done();
250
+ });
251
+ });
252
+ });
253
+ });
254
+
255
+ describe('When a device group removal request arrives', function () {
256
+ beforeEach(function (done) {
257
+ request(optionsCreation, done);
258
+ });
259
+
260
+ it('should remove it from the database', function (done) {
261
+ request(optionsDelete, function (error, response, body) {
262
+ iotAgentDb
263
+ .db()
264
+ .collection('groups')
265
+ .find({})
266
+ .toArray(function (err, docs) {
267
+ should.not.exist(err);
268
+ should.exist(docs);
269
+ should.exist(docs.length);
270
+ docs.length.should.equal(0);
271
+ done();
272
+ });
273
+ });
274
+ });
275
+
276
+ it('should return a 204 OK statusCode', function (done) {
277
+ request(optionsDelete, function (error, response, body) {
278
+ response.statusCode.should.equal(204);
279
+ done();
280
+ });
281
+ });
282
+ });
283
+
284
+ describe('When a device group update request arrives', function () {
285
+ beforeEach(function (done) {
286
+ request(optionsCreation, done);
287
+ });
288
+
289
+ it('should update the values in the database', function (done) {
290
+ request(optionsUpdate, function (error, response, body) {
291
+ iotAgentDb
292
+ .db()
293
+ .collection('groups')
294
+ .find({})
295
+ .toArray(function (err, docs) {
296
+ should.not.exist(err);
297
+ should.exist(docs);
298
+ should.exist(docs[0].cbHost);
299
+ docs[0].cbHost.should.equal('http://anotherUnexistentHost:1026');
300
+ should.exist(docs[0].staticAttributes);
301
+ docs[0].staticAttributes.length.should.equal(1);
302
+ done();
303
+ });
304
+ });
305
+ });
306
+ });
307
+
308
+ describe('When a multiple device group creation arrives', function () {
309
+ const optionsMultipleCreation = _.clone(optionsCreation);
310
+
311
+ beforeEach(function (done) {
312
+ optionsMultipleCreation.json = utils.readExampleFile(
313
+ './test/unit/examples/groupProvisioningRequests/multipleGroupsCreation.json'
314
+ );
315
+
316
+ done();
317
+ });
318
+
319
+ it('should create the values in the database', function (done) {
320
+ request(optionsMultipleCreation, function (error, response, body) {
321
+ iotAgentDb
322
+ .db()
323
+ .collection('groups')
324
+ .find({})
325
+ .toArray(function (err, docs) {
326
+ should.not.exist(err);
327
+ should.exist(docs);
328
+ docs.length.should.equal(2);
329
+ done();
330
+ });
331
+ });
332
+ });
333
+ });
334
+
335
+ describe('When a device group listing request arrives', function () {
336
+ beforeEach(function (done) {
337
+ const optionsCreation1 = _.clone(optionsCreation);
338
+ const optionsCreation2 = _.clone(optionsCreation);
339
+ const optionsCreation3 = _.clone(optionsCreation);
340
+
341
+ optionsCreation2.json = { services: [] };
342
+ optionsCreation3.json = { services: [] };
343
+
344
+ optionsCreation2.json.services[0] = _.clone(optionsCreation.json.services[0]);
345
+ optionsCreation3.json.services[0] = _.clone(optionsCreation.json.services[0]);
346
+
347
+ optionsCreation2.json.services[0].apikey = 'qwertyuiop';
348
+ optionsCreation3.json.services[0].apikey = 'lkjhgfds';
349
+
350
+ async.series(
351
+ [
352
+ async.apply(request, optionsCreation1),
353
+ async.apply(request, optionsCreation2),
354
+ async.apply(request, optionsCreation3)
355
+ ],
356
+ done
357
+ );
358
+ });
359
+
360
+ it('should return all the configured device groups from the database', function (done) {
361
+ request(optionsList, function (error, response, body) {
362
+ body.count.should.equal(3);
363
+ done();
364
+ });
365
+ });
366
+ });
367
+
368
+ describe('When a device group listing arrives with a limit', function () {
369
+ const optionsConstrained = {
370
+ url: 'http://localhost:4041/iot/services',
371
+ method: 'GET',
372
+ qs: {
373
+ limit: 3,
374
+ offset: 2
375
+ },
376
+ json: {},
377
+ headers: {
378
+ 'fiware-service': 'testservice',
379
+ 'fiware-servicepath': '/*'
380
+ }
381
+ };
382
+
383
+ beforeEach(function (done) {
384
+ const optionsCreationList = [];
385
+ const creationFns = [];
386
+
387
+ for (let i = 0; i < 10; i++) {
388
+ optionsCreationList[i] = _.clone(optionsCreation);
389
+ optionsCreationList[i].json = { services: [] };
390
+ optionsCreationList[i].json.services[0] = _.clone(optionsCreation.json.services[0]);
391
+ optionsCreationList[i].json.services[0].apikey = 'qwertyuiop' + i;
392
+ creationFns.push(async.apply(request, optionsCreationList[i]));
393
+ }
394
+
395
+ async.series(creationFns, done);
396
+ });
397
+
398
+ it('should return the appropriate count of services', function (done) {
399
+ request(optionsConstrained, function (error, response, body) {
400
+ body.count.should.equal(10);
401
+ done();
402
+ });
403
+ });
404
+ });
405
+
406
+ describe('When a device info request arrives', function () {
407
+ beforeEach(function (done) {
408
+ async.series([async.apply(request, optionsCreation)], done);
409
+ });
410
+
411
+ it('should return all the configured device groups from the database', function (done) {
412
+ request(optionsGet, function (error, response, body) {
413
+ should.exist(body);
414
+ should.exist(body.count);
415
+ body.count.should.equal(1);
416
+ should.exist(body.services);
417
+ should.exist(body.services.length);
418
+ body.services.length.should.equal(1);
419
+ body.services[0].service.should.equal('testservice');
420
+ done();
421
+ });
422
+ });
423
+ });
424
+
425
+ describe('When a device info request arrives and multiple groups have been created', function () {
426
+ beforeEach(function (done) {
427
+ const optionsCreationList = [];
428
+ const creationFns = [];
429
+
430
+ for (let i = 0; i < 10; i++) {
431
+ optionsCreationList[i] = _.clone(optionsCreation);
432
+ optionsCreationList[i].json = { services: [] };
433
+ optionsCreationList[i].json.services[0] = _.clone(optionsCreation.json.services[0]);
434
+ optionsCreationList[i].json.services[0].apikey = 'qwertyuiop' + i;
435
+ creationFns.push(async.apply(request, optionsCreationList[i]));
436
+ }
437
+
438
+ async.series(creationFns, done);
439
+ });
440
+
441
+ it('should return all the configured device groups from the database', function (done) {
442
+ request(optionsGet, function (error, response, body) {
443
+ should.exist(body);
444
+ should.exist(body.count);
445
+ body.count.should.equal(10);
446
+ should.exist(body.services);
447
+ should.exist(body.services.length);
448
+ body.services.length.should.equal(10);
449
+ done();
450
+ });
451
+ });
452
+ });
453
+
454
+ describe('When the device info request with name and type', function () {
455
+ beforeEach(function (done) {
456
+ async.series([async.apply(request, optionsCreation)], done);
457
+ });
458
+
459
+ afterEach(function (done) {
460
+ iotAgentLib.clearRegistry(done);
461
+ });
462
+
463
+ it('should return the name and type of device', function (done) {
464
+ request(optionsGet, function (error, response, body) {
465
+ should.exist(body);
466
+ should.exist(body.count);
467
+ body.count.should.equal(1);
468
+ should.exist(body.services);
469
+ should.exist(body.services.length);
470
+ body.services.length.should.equal(1);
471
+ should.exist(body.services[0].entity_type);
472
+ body.services[0].entity_type.should.equal('Light');
473
+ done();
474
+ });
475
+ });
476
+ });
477
+ });
@@ -1,6 +1,8 @@
1
1
  [
2
2
  {
3
3
  "@context": "http://context.json-ld",
4
+ "id": "urn:ngsi-ld:WeatherStation:ws1",
5
+ "type": "WeatherStation",
4
6
  "pressure": {
5
7
  "type": "Property",
6
8
  "value": 1040
@@ -9,10 +11,8 @@
9
11
  "type": "Property",
10
12
  "value": {
11
13
  "@type": "Summary",
12
- "@value": "Humidity NaN and pressure 1040"
14
+ "@value": "Humidity NaN and pressure 20800"
13
15
  }
14
- },
15
- "id": "urn:ngsi-ld:WeatherStation:ws1",
16
- "type": "WeatherStation"
16
+ }
17
17
  }
18
18
  ]