iotagent-node-lib 2.23.0 → 2.25.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 (60) hide show
  1. package/.github/workflows/ci.yml +6 -7
  2. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  3. package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  4. package/.nyc_output/processinfo/index.json +1 -1
  5. package/CHANGES_NEXT_RELEASE +1 -2
  6. package/doc/advanced-topics.md +78 -3
  7. package/doc/apiary/iotagent.apib +5 -5
  8. package/doc/architecture.md +52 -5
  9. package/doc/deprecated.md +10 -7
  10. package/doc/expressionLanguage.md +46 -35
  11. package/doc/getting-started.md +1 -1
  12. package/doc/usermanual.md +18 -16
  13. package/examples/TTOpen-service.json +1 -1
  14. package/lib/errors.js +9 -1
  15. package/lib/fiware-iotagent-lib.js +2 -1
  16. package/lib/jexlTranformsMap.js +12 -1
  17. package/lib/plugins/bidirectionalData.js +104 -6
  18. package/lib/plugins/expressionPlugin.js +10 -0
  19. package/lib/plugins/jexlParser.js +2 -2
  20. package/lib/plugins/pluginUtils.js +2 -1
  21. package/lib/request-shim.js +2 -1
  22. package/lib/services/devices/deviceService.js +53 -21
  23. package/lib/services/devices/devices-NGSI-v2.js +3 -1
  24. package/lib/services/ngsi/entities-NGSI-v2.js +14 -4
  25. package/lib/services/northBound/contextServer-NGSI-LD.js +96 -20
  26. package/lib/services/northBound/contextServer-NGSI-v2.js +1 -0
  27. package/lib/services/northBound/restUtils.js +3 -5
  28. package/lib/templates/deviceGroup.json +1 -1
  29. package/package.json +2 -2
  30. package/test/unit/examples/deviceProvisioningRequests/provisionNewDeviceEmpty.json +43 -0
  31. package/test/unit/examples/mongoCollections/configurations.json +3 -3
  32. package/test/unit/expressions/jexlExpression-test.js +29 -8
  33. package/test/unit/general/deviceService-test.js +31 -29
  34. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +62 -10
  35. package/test/unit/mongodb/mongodb-group-registry-test.js +24 -0
  36. package/test/unit/mongodb/mongodb-registry-test.js +68 -10
  37. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin30.json +11 -0
  38. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +21 -0
  39. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +17 -0
  40. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +18 -4
  41. package/test/unit/ngsi-ld/general/deviceService-test.js +31 -29
  42. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +656 -2
  43. package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +111 -0
  44. package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +221 -0
  45. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +0 -3
  46. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityJexlExpressionPlugin1.json +22 -0
  47. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
  48. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +21 -6
  49. package/test/unit/ngsiv2/general/deviceService-test.js +25 -23
  50. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
  51. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
  52. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +58 -0
  53. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +25 -6
  54. package/.nyc_output/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
  55. package/.nyc_output/processinfo/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
  56. package/config +0 -0
  57. package/docker/Mosquitto/Dockerfile.debian +0 -38
  58. package/docker/Mosquitto/Dockerfile.debian~ +0 -23
  59. package/lib/plugins/multiEntity.js_avg2 +0 -343
  60. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js_avg2 +0 -1224
@@ -237,6 +237,120 @@ describe('NGSI-v2 - Bidirectional data plugin', function () {
237
237
  });
238
238
  });
239
239
 
240
+ it('should return the transformed values', function (done) {
241
+ let transformedHandler = false;
242
+
243
+ function mockedHandler(device, values, callback) {
244
+
245
+ let latitudeFound = false;
246
+ let longitudeFound = false;
247
+
248
+ for (let i = 0; i < values.length; i++) {
249
+ if (values[i].name === 'latitude' && values[i].type === 'string' && values[i].value === '-9.6') {
250
+ latitudeFound = true;
251
+ }
252
+
253
+ if (values[i].name === 'longitude' && values[i].type === 'string' && values[i].value === '12.4') {
254
+ longitudeFound = true;
255
+ }
256
+ }
257
+
258
+ transformedHandler = values.length >= 2 && longitudeFound && latitudeFound;
259
+ callback();
260
+ }
261
+
262
+ iotAgentLib.setNotificationHandler(mockedHandler);
263
+
264
+ request(options, function (error, response, body) {
265
+ request(notificationOptions, function (error, response, body) {
266
+ contextBrokerMock.done();
267
+ transformedHandler.should.equal(true);
268
+ done();
269
+ });
270
+ });
271
+ });
272
+ });
273
+
274
+
275
+ describe('When a notification with metadata arrives for a bidirectional attribute', function () {
276
+ const notificationOptions = {
277
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/notify',
278
+ method: 'POST',
279
+ json: utils.readExampleFile(
280
+ './test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json'
281
+ ),
282
+ headers: {
283
+ 'fiware-service': 'smartgondor',
284
+ 'fiware-servicepath': '/gardens'
285
+ }
286
+ };
287
+ let executedHandler = false;
288
+
289
+ beforeEach(function () {
290
+ contextBrokerMock
291
+ .matchHeader('fiware-service', 'smartgondor')
292
+ .matchHeader('fiware-servicepath', '/gardens')
293
+ .post(
294
+ '/v2/subscriptions',
295
+ utils.readExampleFile(
296
+ './test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json'
297
+ )
298
+ )
299
+ .reply(201, null, { Location: '/v2/subscriptions/51c0ac9ed714fb3b37d7d5a8' });
300
+
301
+ contextBrokerMock
302
+ .matchHeader('fiware-service', 'smartgondor')
303
+ .matchHeader('fiware-servicepath', '/gardens')
304
+ .post(
305
+ '/v2/entities?options=upsert',
306
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json')
307
+ )
308
+ .reply(204);
309
+ });
310
+
311
+ afterEach(function () {
312
+ iotAgentLib.setNotificationHandler();
313
+ });
314
+
315
+ it('should execute the original handler', function (done) {
316
+ function mockedHandler(device, notification, callback) {
317
+
318
+ notification[0].name.should.equal('location');
319
+ notification[0].value.should.equal('12.4, -9.6');
320
+ notification[0].metadata.qos.value.should.equal(1);
321
+
322
+ executedHandler = true;
323
+ callback();
324
+ }
325
+
326
+ iotAgentLib.setNotificationHandler(mockedHandler);
327
+
328
+ request(options, function (error, response, body) {
329
+ request(notificationOptions, function (error, response, body) {
330
+ executedHandler.should.equal(true);
331
+ contextBrokerMock.done();
332
+ done();
333
+ });
334
+ });
335
+ });
336
+
337
+ it('should return a 200 OK', function (done) {
338
+ function mockedHandler(device, notification, callback) {
339
+ executedHandler = true;
340
+ callback();
341
+ }
342
+
343
+ iotAgentLib.setNotificationHandler(mockedHandler);
344
+
345
+ request(options, function (error, response, body) {
346
+ request(notificationOptions, function (error, response, body) {
347
+ response.statusCode.should.equal(200);
348
+ contextBrokerMock.done();
349
+ done();
350
+ });
351
+ });
352
+ });
353
+
240
354
  it('should return the transformed values', function (done) {
241
355
  let transformedHandler = false;
242
356
 
@@ -270,6 +384,7 @@ describe('NGSI-v2 - Bidirectional data plugin', function () {
270
384
  });
271
385
  });
272
386
 
387
+
273
388
  describe('When a new Group provisioning request arrives with bidirectional attributes', function () {
274
389
  const provisionGroup = {
275
390
  url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/services',
@@ -540,6 +540,26 @@ const iotAgentConfig = {
540
540
  }
541
541
  ],
542
542
  explicitAttrs: '[ "attr1", "attr2" ]'
543
+ },
544
+ LightMultiDefault: {
545
+ commands: [],
546
+ type: 'Light',
547
+ lazy: [],
548
+ active: [
549
+ {
550
+ object_id: 'p',
551
+ name: 'pressure',
552
+ type: 'Number',
553
+ entity_type: 'myType',
554
+ entity_name: 'Ligth:mymulti'
555
+ },
556
+ {
557
+ object_id: 'q',
558
+ name: 'pressure',
559
+ type: 'Number'
560
+ }
561
+ ],
562
+ expressionLanguage: 'jexl'
543
563
  }
544
564
  },
545
565
  service: 'smartgondor',
@@ -1356,6 +1376,44 @@ describe('NGSI-v2 - Multi-entity plugin', function () {
1356
1376
  });
1357
1377
  }
1358
1378
  );
1379
+
1380
+ describe('When pseudo-multientity device is provisioned (entity_type and default entity_id)', function () {
1381
+ // Case: Expression which results is sent as a new attribute
1382
+ const values = [
1383
+ {
1384
+ name: 'p',
1385
+ type: 'Number',
1386
+ value: 90
1387
+ },
1388
+ {
1389
+ name: 'q',
1390
+ type: 'Number',
1391
+ value: 60
1392
+ }
1393
+ ];
1394
+
1395
+ beforeEach(function () {
1396
+ nock.cleanAll();
1397
+ contextBrokerMock = nock('http://192.168.1.1:1026')
1398
+ .matchHeader('fiware-service', 'smartgondor')
1399
+ .matchHeader('fiware-servicepath', 'gardens')
1400
+ .post(
1401
+ '/v2/op/update',
1402
+ utils.readExampleFile(
1403
+ './test/unit/ngsiv2/examples/contextRequests/updateContextMultientityJexlExpressionPlugin1.json'
1404
+ )
1405
+ )
1406
+ .reply(204);
1407
+ });
1408
+
1409
+ it('should work without invalid expression error', function (done) {
1410
+ iotAgentLib.update('lightPseudo:id', 'LightMultiDefault', '', values, function (error) {
1411
+ should.not.exist(error);
1412
+ contextBrokerMock.done();
1413
+ done();
1414
+ });
1415
+ });
1416
+ });
1359
1417
  });
1360
1418
 
1361
1419
  describe('NGSI-v2 - Multi-entity plugin is executed before timestamp process plugin', function () {
@@ -450,7 +450,7 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
450
450
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
451
451
  /*jshint camelcase: false */
452
452
  entity_type: 'MicroLights',
453
- cbroker: 'http://192.168.1.1:1026',
453
+ cbHost: 'http://192.168.1.1:1026',
454
454
  explicitAttrs: true
455
455
  }
456
456
  ]
@@ -516,7 +516,7 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
516
516
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
517
517
  /*jshint camelcase: false */
518
518
  entity_type: 'MicroLights',
519
- cbroker: 'http://192.168.1.1:1026',
519
+ cbHost: 'http://192.168.1.1:1026',
520
520
  explicitAttrs: true,
521
521
  static_attributes: [
522
522
  {
@@ -589,7 +589,7 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
589
589
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
590
590
  /*jshint camelcase: false */
591
591
  entity_type: 'MicroLights',
592
- cbroker: 'http://192.168.1.1:1026',
592
+ cbHost: 'http://192.168.1.1:1026',
593
593
  explicitAttrs: true
594
594
  }
595
595
  ]
@@ -656,7 +656,7 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
656
656
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
657
657
  /*jshint camelcase: false */
658
658
  entity_type: 'MicroLights',
659
- cbroker: 'http://192.168.1.1:1026',
659
+ cbHost: 'http://192.168.1.1:1026',
660
660
  explicitAttrs: true,
661
661
  static_attributes: [
662
662
  {
@@ -726,7 +726,7 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
726
726
  /*jshint camelcase: false */
727
727
  entity_type: 'MicroLights',
728
728
  entityNameExp: 'EntityNameByExp',
729
- cbroker: 'http://192.168.1.1:1026'
729
+ cbHost: 'http://192.168.1.1:1026'
730
730
  }
731
731
  ]
732
732
  },
@@ -790,7 +790,7 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
790
790
  apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
791
791
  /*jshint camelcase: false */
792
792
  entity_type: 'MicroLights',
793
- cbroker: 'http://192.168.1.1:1026',
793
+ cbHost: 'http://192.168.1.1:1026',
794
794
  explicitAttrs: true,
795
795
  static_attributes: [
796
796
  {
@@ -1385,4 +1385,23 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
1385
1385
  });
1386
1386
  });
1387
1387
  });
1388
+ describe('When a device provisioning request arrives to the Agent without device_id', function () {
1389
+ const options = {
1390
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
1391
+ headers: {
1392
+ 'fiware-service': 'smartgondor',
1393
+ 'fiware-servicepath': '/gardens'
1394
+ },
1395
+ method: 'POST',
1396
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionNewDeviceEmpty.json')
1397
+ };
1398
+
1399
+ it('should return a 400 error', function (done) {
1400
+ request(options, function (error, response, body) {
1401
+ should.not.exist(error);
1402
+ response.statusCode.should.equal(400);
1403
+ done();
1404
+ });
1405
+ });
1406
+ });
1388
1407
  });