iotagent-node-lib 4.9.0 → 4.10.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 (43) hide show
  1. package/.github/workflows/ci.yml +6 -8
  2. package/Changelog +6 -0
  3. package/config.js +2 -1
  4. package/doc/admin.md +12 -0
  5. package/doc/api.md +33 -3
  6. package/doc/devel/northboundinteractions.md +200 -112
  7. package/lib/commonConfig.js +5 -1
  8. package/lib/model/Device.js +3 -1
  9. package/lib/model/Group.js +2 -1
  10. package/lib/services/common/iotManagerService.js +2 -1
  11. package/lib/services/devices/deviceRegistryMongoDB.js +5 -1
  12. package/lib/services/devices/deviceService.js +17 -1
  13. package/lib/services/devices/devices-NGSI-LD.js +3 -2
  14. package/lib/services/devices/devices-NGSI-mixed.js +16 -0
  15. package/lib/services/devices/devices-NGSI-v2.js +122 -8
  16. package/lib/services/devices/registrationUtils.js +97 -30
  17. package/lib/services/groups/groupRegistryMongoDB.js +2 -1
  18. package/lib/services/ngsi/subscription-NGSI-LD.js +2 -2
  19. package/lib/services/ngsi/subscription-NGSI-mixed.js +3 -3
  20. package/lib/services/ngsi/subscription-NGSI-v2.js +20 -6
  21. package/lib/services/ngsi/subscriptionService.js +2 -2
  22. package/lib/services/northBound/deviceProvisioningServer.js +6 -3
  23. package/lib/templates/updateDevice.json +12 -0
  24. package/lib/templates/updateDeviceLax.json +4 -0
  25. package/package.json +2 -2
  26. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +2 -2
  27. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +1 -1
  28. package/test/unit/ngsi-ld/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  29. package/test/unit/ngsi-ld/general/https-support-test.js +1 -1
  30. package/test/unit/ngsi-ld/ngsiService/subscriptions-test.js +6 -6
  31. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json +24 -0
  32. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json +24 -0
  33. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json +24 -0
  34. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json +24 -0
  35. package/test/unit/ngsiv2/examples/contextRequests/updateEntity.json +5 -0
  36. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2.json +5 -0
  37. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json +7 -0
  38. package/test/unit/ngsiv2/examples/contextRequests/updateEntity3.json +5 -0
  39. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest.json +4 -2
  40. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest2.json +4 -2
  41. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  42. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  43. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +245 -2
@@ -157,6 +157,10 @@
157
157
  "description": "use CB flowControl option",
158
158
  "type": "boolean"
159
159
  },
160
+ "cmdMode": {
161
+ "description": "CB commands mode",
162
+ "type": "string"
163
+ },
160
164
  "contentType": {
161
165
  "description": "Content type",
162
166
  "type": "string"
@@ -203,6 +207,10 @@
203
207
  "description": "Payload type allowed for measures for this device",
204
208
  "type": "string"
205
209
  },
210
+ "useCBflowControl": {
211
+ "description": "use CB flowControl option",
212
+ "type": "boolean"
213
+ },
206
214
  "storeLastMeasure": {
207
215
  "description": "Store last measure",
208
216
  "type": "boolean"
@@ -210,6 +218,10 @@
210
218
  "lastMeasure": {
211
219
  "description": "last measure",
212
220
  "type": "object"
221
+ },
222
+ "cmdMode": {
223
+ "description": "CB commands mode",
224
+ "type": "string"
213
225
  }
214
226
  }
215
227
  }
@@ -158,6 +158,10 @@
158
158
  "lastMeasure": {
159
159
  "description": "last measure",
160
160
  "type": "object"
161
+ },
162
+ "cmdMode": {
163
+ "description": "CB commands mode",
164
+ "type": "string"
161
165
  }
162
166
  }
163
167
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "iotagent-node-lib",
3
3
  "license": "AGPL-3.0-only",
4
4
  "description": "IoT Agent library to interface with NGSI Context Broker",
5
- "version": "4.9.0",
5
+ "version": "4.10.0",
6
6
  "homepage": "https://github.com/telefonicaid/iotagent-node-lib",
7
7
  "keywords": [
8
8
  "fiware",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "main": "lib/fiware-iotagent-lib",
25
25
  "engines": {
26
- "node": ">=16"
26
+ "node": ">=20"
27
27
  },
28
28
  "scripts": {
29
29
  "clean": "rm -rf package-lock.json && rm -rf node_modules && rm -rf coverage",
@@ -295,7 +295,7 @@ describe('NGSI-v2 - Secured access to the Context Broker with Keystone', functio
295
295
 
296
296
  it('subscribe requests use auth header', function (done) {
297
297
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
298
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
298
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
299
299
  should.not.exist(error);
300
300
 
301
301
  contextBrokerMock.done();
@@ -316,7 +316,7 @@ describe('NGSI-v2 - Secured access to the Context Broker with Keystone', functio
316
316
  });
317
317
 
318
318
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
319
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
319
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
320
320
  iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function (error) {
321
321
  contextBrokerMock.done();
322
322
  done();
@@ -243,7 +243,7 @@ describe('NGSI-v2 - In memory device registry', function () {
243
243
  should.exist(device.type);
244
244
  device.name.should.equal('name5');
245
245
  device.type.should.equal('Light5');
246
- Object.keys(device).length.should.equal(12);
246
+ Object.keys(device).length.should.equal(13);
247
247
  done();
248
248
  });
249
249
  });
@@ -309,7 +309,7 @@ describe('NGSI-LD - Secured access to the Context Broker with OAuth2 provider',
309
309
 
310
310
  it('subscribe requests use auth header', function (done) {
311
311
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
312
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
312
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
313
313
  should.not.exist(error);
314
314
 
315
315
  contextBrokerMock.done();
@@ -330,7 +330,7 @@ describe('NGSI-LD - Secured access to the Context Broker with OAuth2 provider',
330
330
  contextBrokerMock.delete('/ngsi-ld/v1/subscriptions/51c0ac9ed714fb3b37d7d5a8', '').reply(204);
331
331
 
332
332
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
333
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
333
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
334
334
  iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function (error) {
335
335
  contextBrokerMock.done();
336
336
  done();
@@ -214,7 +214,7 @@ describe('NGSI-LD - HTTPS support tests', function () {
214
214
 
215
215
  it('should send the appropriate request to the Context Broker', function (done) {
216
216
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
217
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
217
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
218
218
  should.not.exist(error);
219
219
 
220
220
  contextBrokerMock.done();
@@ -94,7 +94,7 @@ describe('NGSI-LD - Subscription tests', function () {
94
94
  describe('When a client invokes the subscribe() function for device', function () {
95
95
  it('should send the appropriate request to the Context Broker', function (done) {
96
96
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
97
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
97
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
98
98
  should.not.exist(error);
99
99
 
100
100
  contextBrokerMock.done();
@@ -105,7 +105,7 @@ describe('NGSI-LD - Subscription tests', function () {
105
105
  });
106
106
  it('should store the subscription ID in the Device Registry', function (done) {
107
107
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
108
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
108
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
109
109
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
110
110
  should.not.exist(error);
111
111
  should.exist(device);
@@ -131,7 +131,7 @@ describe('NGSI-LD - Subscription tests', function () {
131
131
 
132
132
  it('should delete the subscription from the CB', function (done) {
133
133
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
134
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
134
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
135
135
  iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function (error) {
136
136
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
137
137
  contextBrokerMock.done();
@@ -143,7 +143,7 @@ describe('NGSI-LD - Subscription tests', function () {
143
143
  });
144
144
  it('should remove the id from the subscriptions array', function (done) {
145
145
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
146
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
146
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
147
147
  iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function (error) {
148
148
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
149
149
  should.not.exist(error);
@@ -169,7 +169,7 @@ describe('NGSI-LD - Subscription tests', function () {
169
169
 
170
170
  it('should delete the subscription from the CB', function (done) {
171
171
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
172
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
172
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
173
173
  iotAgentLib.unregister(device.id, null, 'smartgondor', '/gardens', function (error) {
174
174
  contextBrokerMock.done();
175
175
  done();
@@ -181,7 +181,7 @@ describe('NGSI-LD - Subscription tests', function () {
181
181
  describe('When a new notification comes to the IoTAgent', function () {
182
182
  beforeEach(function (done) {
183
183
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
184
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
184
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
185
185
  done();
186
186
  });
187
187
  });
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: Robot:r2d2 Robot position",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"Robot:r2d2","type":"Robot"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["position"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["position"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: RobotT:r2d3 RobotT position",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"RobotT:r2d3","type":"RobotT"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["position"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["position"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: RobotT:r2d4 RobotT position",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"RobotT:r2d4","type":"RobotT"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["position"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["position"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: RobotT:r2d3 RobotT reset",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"RobotT:r2d3","type":"RobotT"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["reset"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["reset"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":"Robot:r2d2",
3
+ "type":"Robot",
4
+ "position":{"type":"command","value":null}
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":"RobotT:r2d3",
3
+ "type":"RobotT",
4
+ "position":{"type":"command","value":null}
5
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "pressure":{"type":"Hgmm","value":null},
3
+ "reset": {
4
+ "type": "command",
5
+ "value": null
6
+ }
7
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":"RobotT:r2d4",
3
+ "type":"RobotT",
4
+ "position":{"type":"command","value":null}
5
+ }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "description": "Managed by IOTA: FirstMicroLight MicroLights attr_name",
2
3
  "subject": {
3
4
  "entities": [
4
5
  {
@@ -17,6 +18,7 @@
17
18
  "url": "http://smartgondor.com/notify"
18
19
  },
19
20
  "attrs": [],
20
- "attrsFormat": "normalized"
21
+ "attrsFormat": "normalized",
22
+ "onlyChangedAttrs": true
21
23
  }
22
- }
24
+ }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "description": "Managed by IOTA: light1 Light dimming",
2
3
  "subject": {
3
4
  "entities": [
4
5
  {
@@ -17,6 +18,7 @@
17
18
  "url": "http://smartgondor.com/notify"
18
19
  },
19
20
  "attrs": [],
20
- "attrsFormat": "normalized"
21
+ "attrsFormat": "normalized",
22
+ "onlyChangedAttrs": true
21
23
  }
22
- }
24
+ }
@@ -312,7 +312,7 @@ describe('NGSI-v2 - Secured access to the Context Broker with OAuth2 provider',
312
312
 
313
313
  it('subscribe requests use auth header', function (done) {
314
314
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
315
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
315
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
316
316
  should.not.exist(error);
317
317
 
318
318
  contextBrokerMock.done();
@@ -333,7 +333,7 @@ describe('NGSI-v2 - Secured access to the Context Broker with OAuth2 provider',
333
333
  contextBrokerMock.delete('/v2/subscriptions/51c0ac9ed714fb3b37d7d5a8', '').reply(204);
334
334
 
335
335
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
336
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
336
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
337
337
  iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function (error) {
338
338
  contextBrokerMock.done();
339
339
  done();
@@ -211,7 +211,7 @@ describe('NGSI-v2 - HTTPS support tests', function () {
211
211
 
212
212
  it('should send the appropriate request to the Context Broker', function (done) {
213
213
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
214
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
214
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
215
215
  should.not.exist(error);
216
216
 
217
217
  contextBrokerMock.done();
@@ -31,6 +31,7 @@ const request = utils.request;
31
31
  const should = require('should');
32
32
  const logger = require('logops');
33
33
  const nock = require('nock');
34
+ const async = require('async');
34
35
  const mongoUtils = require('../../mongodb/mongoDBUtils');
35
36
 
36
37
  const timekeeper = require('timekeeper');
@@ -99,18 +100,98 @@ const iotAgentConfig = {
99
100
  lazy: [],
100
101
  staticAttributes: [],
101
102
  active: []
103
+ },
104
+ RobotT: {
105
+ commands: [
106
+ {
107
+ name: 'position',
108
+ type: 'Array'
109
+ }
110
+ ],
111
+ lazy: [],
112
+ staticAttributes: [],
113
+ active: [],
114
+ cmdMode: 'notification'
102
115
  }
103
116
  },
104
117
  service: 'smartgondor',
105
118
  subservice: 'gardens',
106
119
  providerUrl: 'http://smartgondor.com',
107
- useCBflowControl: true
120
+ useCBflowControl: true,
121
+ cmdMode: 'legacy'
108
122
  };
109
123
  const device3 = {
110
124
  id: 'r2d2',
111
125
  type: 'Robot',
112
126
  service: 'smartgondor',
113
- subservice: 'gardens'
127
+ subservice: 'gardens',
128
+ cmdMode: 'legacy'
129
+ };
130
+
131
+ const device4 = {
132
+ id: 'r2d2',
133
+ type: 'Robot',
134
+ service: 'smartgondor',
135
+ subservice: 'gardens',
136
+ cmdMode: 'notification',
137
+ apikey: null
138
+ };
139
+
140
+ const device5 = {
141
+ id: 'r2d3',
142
+ type: 'RobotT',
143
+ service: 'smartgondor',
144
+ subservice: 'gardens',
145
+ apikey: null,
146
+ cmdMode: 'notification'
147
+ };
148
+
149
+ const device5old = {
150
+ id: 'r2d3',
151
+ name: 'RobotT:r2d3',
152
+ type: 'RobotT',
153
+ service: 'smartgondor',
154
+ subservice: 'gardens',
155
+ apikey: null,
156
+ cmdMode: 'notification',
157
+ commands: [
158
+ {
159
+ name: 'position',
160
+ type: 'Array'
161
+ }
162
+ ],
163
+ subscriptions: [{ id: '6319a7f5254b05844116584d', triggers: ['position'] }],
164
+ subscriptionId: '6319a7f5254b05844116584d'
165
+ };
166
+
167
+ const device5updated = {
168
+ id: 'r2d3',
169
+ name: 'RobotT:r2d3',
170
+ type: 'RobotT',
171
+ service: 'smartgondor',
172
+ subservice: 'gardens',
173
+ apikey: null,
174
+ active: [
175
+ {
176
+ name: 'pressure',
177
+ type: 'Hgmm'
178
+ }
179
+ ],
180
+ commands: [
181
+ {
182
+ name: 'reset',
183
+ type: 'Array'
184
+ }
185
+ ],
186
+ cmdMode: 'notification'
187
+ };
188
+
189
+ const device6 = {
190
+ id: 'r2d4',
191
+ type: 'RobotT',
192
+ service: 'smartgondor',
193
+ subservice: 'gardens',
194
+ apikey: null
114
195
  };
115
196
 
116
197
  describe('NGSI-v2 - Command functionalities', function () {
@@ -414,3 +495,165 @@ describe('NGSI-v2 - Command functionalities', function () {
414
495
  });
415
496
  });
416
497
  });
498
+
499
+ describe('NGSI-v2 - Command notification functionalities', function () {
500
+ beforeEach(function (done) {
501
+ logger.setLevel('FATAL');
502
+ nock.cleanAll();
503
+
504
+ contextBrokerMock = nock('http://192.168.1.1:1026')
505
+ .matchHeader('fiware-service', 'smartgondor')
506
+ .matchHeader('fiware-servicepath', 'gardens')
507
+ .post(
508
+ '/v2/subscriptions',
509
+ utils.readExampleFile(
510
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json'
511
+ )
512
+ )
513
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
514
+
515
+ contextBrokerMock
516
+ .matchHeader('fiware-service', 'smartgondor')
517
+ .matchHeader('fiware-servicepath', 'gardens')
518
+ .post(
519
+ '/v2/entities?options=upsert',
520
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity.json')
521
+ )
522
+ .reply(204);
523
+ iotAgentConfig.cmdMode = 'notification';
524
+ iotAgentLib.activate(iotAgentConfig, done);
525
+ });
526
+
527
+ afterEach(function (done) {
528
+ iotAgentLib.clearAll(function () {
529
+ iotAgentLib.deactivate(function () {
530
+ mongoUtils.cleanDbs(function () {
531
+ nock.cleanAll();
532
+ iotAgentLib.setDataUpdateHandler();
533
+ iotAgentLib.setCommandHandler();
534
+ done();
535
+ });
536
+ });
537
+ });
538
+ });
539
+
540
+ describe('When a device with commands by notifications is registered with with commands', function () {
541
+ it('should subscribe a Context Provider of the commands', function (done) {
542
+ iotAgentLib.register(device4, function (error) {
543
+ should.not.exist(error);
544
+ contextBrokerMock.done();
545
+ done();
546
+ });
547
+ });
548
+ });
549
+ });
550
+
551
+ describe('NGSI-v2 - Command update subscription and notification functionalities', function () {
552
+ afterEach(function (done) {
553
+ iotAgentLib.clearAll(function () {
554
+ iotAgentLib.deactivate(done);
555
+ });
556
+ });
557
+
558
+ describe('When a device with commands by notifications is registered with with commands and its updated', function () {
559
+ beforeEach(function (done) {
560
+ logger.setLevel('FATAL');
561
+ nock.cleanAll();
562
+ contextBrokerMock = nock('http://192.168.1.1:1026')
563
+ .post(
564
+ '/v2/subscriptions',
565
+ utils.readExampleFile(
566
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json'
567
+ )
568
+ )
569
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
570
+ contextBrokerMock
571
+ .matchHeader('fiware-service', 'smartgondor')
572
+ .matchHeader('fiware-servicepath', 'gardens')
573
+ .post(
574
+ '/v2/entities?options=upsert',
575
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity2.json')
576
+ )
577
+ .reply(204);
578
+
579
+ contextBrokerMock
580
+ .post(
581
+ '/v2/subscriptions',
582
+ utils.readExampleFile(
583
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json'
584
+ )
585
+ )
586
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
587
+ contextBrokerMock
588
+ .matchHeader('fiware-service', 'smartgondor')
589
+ .matchHeader('fiware-servicepath', 'gardens')
590
+ .post(
591
+ '/v2/entities/RobotT:r2d3/attrs?type=RobotT',
592
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json')
593
+ )
594
+ .reply(204);
595
+ contextBrokerMock
596
+ .matchHeader('fiware-service', 'smartgondor')
597
+ .matchHeader('fiware-servicepath', 'gardens')
598
+ .delete('/v2/subscriptions/6319a7f5254b05844116584d')
599
+ .reply(204, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
600
+
601
+ iotAgentLib.activate(iotAgentConfig, function (error) {
602
+ async.series([async.apply(iotAgentLib.clearAll), async.apply(iotAgentLib.register, device5)], done);
603
+ });
604
+ });
605
+
606
+ it('should update subscription in a Context Provider of the commands', function (done) {
607
+ iotAgentLib.updateRegister(device5updated, device5old, false, function (error) {
608
+ should.not.exist(error);
609
+ contextBrokerMock.done();
610
+ done();
611
+ });
612
+ });
613
+ });
614
+ });
615
+
616
+ describe('NGSI-v2 - Command unsubscribe notification functionalities', function () {
617
+ afterEach(function (done) {
618
+ iotAgentLib.clearAll(function () {
619
+ iotAgentLib.deactivate(done);
620
+ });
621
+ });
622
+
623
+ describe('When a device with commands by notifications is registered with with commands', function () {
624
+ beforeEach(function (done) {
625
+ logger.setLevel('FATAL');
626
+ nock.cleanAll();
627
+ contextBrokerMock = nock('http://192.168.1.1:1026')
628
+ .post(
629
+ '/v2/subscriptions',
630
+ utils.readExampleFile(
631
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json'
632
+ )
633
+ )
634
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
635
+ contextBrokerMock
636
+ .matchHeader('fiware-service', 'smartgondor')
637
+ .matchHeader('fiware-servicepath', 'gardens')
638
+ .post(
639
+ '/v2/entities?options=upsert',
640
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity3.json')
641
+ )
642
+ .reply(204);
643
+ contextBrokerMock
644
+ .delete('/v2/subscriptions/6319a7f5254b05844116584d')
645
+ .reply(204, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
646
+ iotAgentLib.activate(iotAgentConfig, function (error) {
647
+ async.series([async.apply(iotAgentLib.clearAll), async.apply(iotAgentLib.register, device6)], done);
648
+ });
649
+ });
650
+
651
+ it('should unsubscribe a Context Provider of the commands', function (done) {
652
+ iotAgentLib.unregister(device6.id, null, 'smartgondor', 'gardens', function (error) {
653
+ should.not.exist(error);
654
+ contextBrokerMock.done();
655
+ done();
656
+ });
657
+ });
658
+ });
659
+ });