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.
- package/.github/workflows/ci.yml +6 -7
- package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
- package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/CHANGES_NEXT_RELEASE +1 -2
- package/doc/advanced-topics.md +78 -3
- package/doc/apiary/iotagent.apib +5 -5
- package/doc/architecture.md +52 -5
- package/doc/deprecated.md +10 -7
- package/doc/expressionLanguage.md +46 -35
- package/doc/getting-started.md +1 -1
- package/doc/usermanual.md +18 -16
- package/examples/TTOpen-service.json +1 -1
- package/lib/errors.js +9 -1
- package/lib/fiware-iotagent-lib.js +2 -1
- package/lib/jexlTranformsMap.js +12 -1
- package/lib/plugins/bidirectionalData.js +104 -6
- package/lib/plugins/expressionPlugin.js +10 -0
- package/lib/plugins/jexlParser.js +2 -2
- package/lib/plugins/pluginUtils.js +2 -1
- package/lib/request-shim.js +2 -1
- package/lib/services/devices/deviceService.js +53 -21
- package/lib/services/devices/devices-NGSI-v2.js +3 -1
- package/lib/services/ngsi/entities-NGSI-v2.js +14 -4
- package/lib/services/northBound/contextServer-NGSI-LD.js +96 -20
- package/lib/services/northBound/contextServer-NGSI-v2.js +1 -0
- package/lib/services/northBound/restUtils.js +3 -5
- package/lib/templates/deviceGroup.json +1 -1
- package/package.json +2 -2
- package/test/unit/examples/deviceProvisioningRequests/provisionNewDeviceEmpty.json +43 -0
- package/test/unit/examples/mongoCollections/configurations.json +3 -3
- package/test/unit/expressions/jexlExpression-test.js +29 -8
- package/test/unit/general/deviceService-test.js +31 -29
- package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +62 -10
- package/test/unit/mongodb/mongodb-group-registry-test.js +24 -0
- package/test/unit/mongodb/mongodb-registry-test.js +68 -10
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin30.json +11 -0
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +21 -0
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +17 -0
- package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +18 -4
- package/test/unit/ngsi-ld/general/deviceService-test.js +31 -29
- package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +656 -2
- package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +111 -0
- package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +221 -0
- package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +0 -3
- package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityJexlExpressionPlugin1.json +22 -0
- package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
- package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +21 -6
- package/test/unit/ngsiv2/general/deviceService-test.js +25 -23
- package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
- package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
- package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +58 -0
- package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +25 -6
- package/.nyc_output/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
- package/.nyc_output/processinfo/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
- package/config +0 -0
- package/docker/Mosquitto/Dockerfile.debian +0 -38
- package/docker/Mosquitto/Dockerfile.debian~ +0 -23
- package/lib/plugins/multiEntity.js_avg2 +0 -343
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
});
|