iotagent-node-lib 4.9.0 → 4.11.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 (49) hide show
  1. package/.github/workflows/ci.yml +6 -8
  2. package/CHANGES_NEXT_RELEASE +0 -1
  3. package/Changelog +14 -0
  4. package/config.js +2 -1
  5. package/doc/admin.md +17 -20
  6. package/doc/api.md +87 -50
  7. package/doc/deprecated.md +18 -0
  8. package/doc/devel/northboundinteractions.md +213 -113
  9. package/lib/commonConfig.js +12 -1
  10. package/lib/jexlTranformsMap.js +15 -0
  11. package/lib/model/Device.js +3 -1
  12. package/lib/model/Group.js +2 -1
  13. package/lib/model/dbConn.js +57 -58
  14. package/lib/services/common/iotManagerService.js +2 -1
  15. package/lib/services/devices/deviceRegistryMongoDB.js +5 -1
  16. package/lib/services/devices/deviceService.js +17 -1
  17. package/lib/services/devices/devices-NGSI-LD.js +3 -2
  18. package/lib/services/devices/devices-NGSI-mixed.js +16 -0
  19. package/lib/services/devices/devices-NGSI-v2.js +122 -8
  20. package/lib/services/devices/registrationUtils.js +97 -30
  21. package/lib/services/groups/groupRegistryMongoDB.js +2 -1
  22. package/lib/services/ngsi/subscription-NGSI-LD.js +2 -2
  23. package/lib/services/ngsi/subscription-NGSI-mixed.js +3 -3
  24. package/lib/services/ngsi/subscription-NGSI-v2.js +20 -6
  25. package/lib/services/ngsi/subscriptionService.js +2 -2
  26. package/lib/services/northBound/contextServer-NGSI-v2.js +4 -2
  27. package/lib/services/northBound/deviceProvisioningServer.js +6 -3
  28. package/lib/templates/updateDevice.json +12 -0
  29. package/lib/templates/updateDeviceLax.json +4 -0
  30. package/package.json +2 -2
  31. package/test/unit/expressions/jexlExpression-test.js +30 -0
  32. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +2 -2
  33. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +1 -1
  34. package/test/unit/ngsi-ld/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  35. package/test/unit/ngsi-ld/general/https-support-test.js +1 -1
  36. package/test/unit/ngsi-ld/ngsiService/subscriptions-test.js +6 -6
  37. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json +24 -0
  38. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json +24 -0
  39. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json +24 -0
  40. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json +24 -0
  41. package/test/unit/ngsiv2/examples/contextRequests/updateEntity.json +5 -0
  42. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2.json +5 -0
  43. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json +7 -0
  44. package/test/unit/ngsiv2/examples/contextRequests/updateEntity3.json +5 -0
  45. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest.json +4 -2
  46. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest2.json +4 -2
  47. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  48. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  49. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +245 -2
@@ -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
+ });