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
|
@@ -365,6 +365,522 @@ describe('NGSI-LD - Command functionalities', function () {
|
|
|
365
365
|
});
|
|
366
366
|
});
|
|
367
367
|
|
|
368
|
+
describe('When a sequential command with datasetId updates via PATCH /attrs/attr-name arrives to the IoT Agent', function () {
|
|
369
|
+
const options = {
|
|
370
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs',
|
|
371
|
+
method: 'PUT',
|
|
372
|
+
json: {
|
|
373
|
+
position: [
|
|
374
|
+
{
|
|
375
|
+
type: 'Property',
|
|
376
|
+
value: [1, 2, 3],
|
|
377
|
+
datasetId: 'urn:ngsi-ld:this'
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
type: 'Property',
|
|
381
|
+
value: [28, -104, 23],
|
|
382
|
+
datasetId: 'urn:ngsi-ld:that'
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
},
|
|
386
|
+
headers: {
|
|
387
|
+
'fiware-service': 'smartgondor',
|
|
388
|
+
'content-type': 'application/ld+json'
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
beforeEach(function (done) {
|
|
393
|
+
logger.setLevel('ERROR');
|
|
394
|
+
iotAgentLib.register(device3, function (error) {
|
|
395
|
+
done();
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it('should call the client handler once including datasetId', function (done) {
|
|
400
|
+
let handlerCalled = 0;
|
|
401
|
+
|
|
402
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
403
|
+
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
404
|
+
type.should.equal(device3.type);
|
|
405
|
+
attributes[0].name.should.equal('position');
|
|
406
|
+
attributes[0].datasetId.should.equal('urn:ngsi-ld:this');
|
|
407
|
+
attributes[1].name.should.equal('position');
|
|
408
|
+
attributes[1].datasetId.should.equal('urn:ngsi-ld:that');
|
|
409
|
+
JSON.stringify(attributes[0].value).should.equal('[1,2,3]');
|
|
410
|
+
JSON.stringify(attributes[1].value).should.equal('[28,-104,23]');
|
|
411
|
+
handlerCalled++;
|
|
412
|
+
callback(null, {
|
|
413
|
+
id,
|
|
414
|
+
type,
|
|
415
|
+
attributes: [
|
|
416
|
+
{
|
|
417
|
+
name: 'position',
|
|
418
|
+
type: 'Array',
|
|
419
|
+
value: '[28, -104, 23]'
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: 'orientation',
|
|
423
|
+
type: 'Array',
|
|
424
|
+
value: '[1, 2, 3]'
|
|
425
|
+
}
|
|
426
|
+
]
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
request(options, function (error, response, body) {
|
|
431
|
+
should.not.exist(error);
|
|
432
|
+
handlerCalled.should.equal(1);
|
|
433
|
+
done();
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
437
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
438
|
+
callback(null, {
|
|
439
|
+
id,
|
|
440
|
+
type,
|
|
441
|
+
attributes: [
|
|
442
|
+
{
|
|
443
|
+
name: 'position',
|
|
444
|
+
type: 'Array',
|
|
445
|
+
value: '[28, -104, 23]'
|
|
446
|
+
}
|
|
447
|
+
]
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
request(options, function (error, response, body) {
|
|
452
|
+
should.not.exist(error);
|
|
453
|
+
done();
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
457
|
+
let serviceReceived = false;
|
|
458
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
459
|
+
serviceReceived = service === 'smartgondor';
|
|
460
|
+
callback(null, {
|
|
461
|
+
id,
|
|
462
|
+
type,
|
|
463
|
+
attributes: [
|
|
464
|
+
{
|
|
465
|
+
name: 'position',
|
|
466
|
+
type: 'Array',
|
|
467
|
+
value: '[28, -104, 23]'
|
|
468
|
+
}
|
|
469
|
+
]
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
request(options, function (error, response, body) {
|
|
474
|
+
serviceReceived.should.equal(true);
|
|
475
|
+
done();
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
describe('When a command update PATCH attrs/attr-name with datasetId arrives to the IoT Agent as Context Provider', function () {
|
|
481
|
+
const options = {
|
|
482
|
+
url:
|
|
483
|
+
'http://localhost:' +
|
|
484
|
+
iotAgentConfig.server.port +
|
|
485
|
+
'/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/position',
|
|
486
|
+
method: 'PATCH',
|
|
487
|
+
json: {
|
|
488
|
+
type: 'Property',
|
|
489
|
+
value: [28, -104, 23],
|
|
490
|
+
datasetId: 'urn:ngsi-ld:this'
|
|
491
|
+
},
|
|
492
|
+
headers: {
|
|
493
|
+
'fiware-service': 'smartgondor',
|
|
494
|
+
'content-type': 'application/ld+json'
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
beforeEach(function (done) {
|
|
499
|
+
logger.setLevel('ERROR');
|
|
500
|
+
iotAgentLib.register(device3, function (error) {
|
|
501
|
+
done();
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
it('should call the client handler once including datasetId', function (done) {
|
|
506
|
+
let handlerCalled = 0;
|
|
507
|
+
|
|
508
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
509
|
+
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
510
|
+
type.should.equal(device3.type);
|
|
511
|
+
attributes[0].name.should.equal('position');
|
|
512
|
+
attributes[0].datasetId.should.equal('urn:ngsi-ld:this');
|
|
513
|
+
JSON.stringify(attributes[0].value).should.equal('[28,-104,23]');
|
|
514
|
+
handlerCalled++;
|
|
515
|
+
callback(null, {
|
|
516
|
+
id,
|
|
517
|
+
type,
|
|
518
|
+
attributes: [
|
|
519
|
+
{
|
|
520
|
+
name: 'position',
|
|
521
|
+
type: 'Array',
|
|
522
|
+
value: '[28, -104, 23]'
|
|
523
|
+
}
|
|
524
|
+
]
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
request(options, function (error, response, body) {
|
|
529
|
+
should.not.exist(error);
|
|
530
|
+
handlerCalled.should.equal(1);
|
|
531
|
+
done();
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
535
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
536
|
+
callback(null, {
|
|
537
|
+
id,
|
|
538
|
+
type,
|
|
539
|
+
attributes: [
|
|
540
|
+
{
|
|
541
|
+
name: 'position',
|
|
542
|
+
type: 'Array',
|
|
543
|
+
value: '[28, -104, 23]'
|
|
544
|
+
}
|
|
545
|
+
]
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
request(options, function (error, response, body) {
|
|
550
|
+
should.not.exist(error);
|
|
551
|
+
done();
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
555
|
+
let serviceReceived = false;
|
|
556
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
557
|
+
serviceReceived = service === 'smartgondor';
|
|
558
|
+
callback(null, {
|
|
559
|
+
id,
|
|
560
|
+
type,
|
|
561
|
+
attributes: [
|
|
562
|
+
{
|
|
563
|
+
name: 'position',
|
|
564
|
+
type: 'Array',
|
|
565
|
+
value: '[28, -104, 23]'
|
|
566
|
+
}
|
|
567
|
+
]
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
request(options, function (error, response, body) {
|
|
572
|
+
serviceReceived.should.equal(true);
|
|
573
|
+
done();
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
describe('When a command update PATCH attrs/attr-name with metadata arrives to the IoT Agent as Context Provider', function () {
|
|
579
|
+
const options = {
|
|
580
|
+
url:
|
|
581
|
+
'http://localhost:' +
|
|
582
|
+
iotAgentConfig.server.port +
|
|
583
|
+
'/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/position',
|
|
584
|
+
method: 'PATCH',
|
|
585
|
+
json: {
|
|
586
|
+
type: 'Property',
|
|
587
|
+
value: [28, -104, 23],
|
|
588
|
+
qos: 1
|
|
589
|
+
},
|
|
590
|
+
headers: {
|
|
591
|
+
'fiware-service': 'smartgondor',
|
|
592
|
+
'content-type': 'application/ld+json'
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
beforeEach(function (done) {
|
|
597
|
+
logger.setLevel('ERROR');
|
|
598
|
+
iotAgentLib.register(device3, function (error) {
|
|
599
|
+
done();
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
it('should call the client handler once including metadata', function (done) {
|
|
604
|
+
let handlerCalled = 0;
|
|
605
|
+
|
|
606
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
607
|
+
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
608
|
+
type.should.equal(device3.type);
|
|
609
|
+
attributes[0].name.should.equal('position');
|
|
610
|
+
attributes[0].metadata.qos.should.equal(1);
|
|
611
|
+
JSON.stringify(attributes[0].value).should.equal('[28,-104,23]');
|
|
612
|
+
handlerCalled++;
|
|
613
|
+
callback(null, {
|
|
614
|
+
id,
|
|
615
|
+
type,
|
|
616
|
+
attributes: [
|
|
617
|
+
{
|
|
618
|
+
name: 'position',
|
|
619
|
+
type: 'Array',
|
|
620
|
+
value: '[28, -104, 23]'
|
|
621
|
+
}
|
|
622
|
+
]
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
request(options, function (error, response, body) {
|
|
627
|
+
should.not.exist(error);
|
|
628
|
+
handlerCalled.should.equal(1);
|
|
629
|
+
done();
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
633
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
634
|
+
callback(null, {
|
|
635
|
+
id,
|
|
636
|
+
type,
|
|
637
|
+
attributes: [
|
|
638
|
+
{
|
|
639
|
+
name: 'position',
|
|
640
|
+
type: 'Array',
|
|
641
|
+
value: '[28, -104, 23]'
|
|
642
|
+
}
|
|
643
|
+
]
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
request(options, function (error, response, body) {
|
|
648
|
+
should.not.exist(error);
|
|
649
|
+
done();
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
653
|
+
let serviceReceived = false;
|
|
654
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
655
|
+
serviceReceived = service === 'smartgondor';
|
|
656
|
+
callback(null, {
|
|
657
|
+
id,
|
|
658
|
+
type,
|
|
659
|
+
attributes: [
|
|
660
|
+
{
|
|
661
|
+
name: 'position',
|
|
662
|
+
type: 'Array',
|
|
663
|
+
value: '[28, -104, 23]'
|
|
664
|
+
}
|
|
665
|
+
]
|
|
666
|
+
});
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
request(options, function (error, response, body) {
|
|
670
|
+
serviceReceived.should.equal(true);
|
|
671
|
+
done();
|
|
672
|
+
});
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
describe('When a command overwrite PUT attrs/attr-name arrives to the IoT Agent as Context Provider', function () {
|
|
677
|
+
const options = {
|
|
678
|
+
url:
|
|
679
|
+
'http://localhost:' +
|
|
680
|
+
iotAgentConfig.server.port +
|
|
681
|
+
'/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/position',
|
|
682
|
+
method: 'PUT',
|
|
683
|
+
json: {
|
|
684
|
+
type: 'Property',
|
|
685
|
+
value: [28, -104, 23]
|
|
686
|
+
},
|
|
687
|
+
headers: {
|
|
688
|
+
'fiware-service': 'smartgondor',
|
|
689
|
+
'content-type': 'application/ld+json'
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
beforeEach(function (done) {
|
|
694
|
+
logger.setLevel('ERROR');
|
|
695
|
+
iotAgentLib.register(device3, function (error) {
|
|
696
|
+
done();
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
it('should call the client handler once', function (done) {
|
|
701
|
+
let handlerCalled = 0;
|
|
702
|
+
|
|
703
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
704
|
+
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
705
|
+
type.should.equal(device3.type);
|
|
706
|
+
attributes[0].name.should.equal('position');
|
|
707
|
+
JSON.stringify(attributes[0].value).should.equal('[28,-104,23]');
|
|
708
|
+
handlerCalled++;
|
|
709
|
+
callback(null, {
|
|
710
|
+
id,
|
|
711
|
+
type,
|
|
712
|
+
attributes: [
|
|
713
|
+
{
|
|
714
|
+
name: 'position',
|
|
715
|
+
type: 'Array',
|
|
716
|
+
value: '[28, -104, 23]'
|
|
717
|
+
}
|
|
718
|
+
]
|
|
719
|
+
});
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
request(options, function (error, response, body) {
|
|
723
|
+
should.not.exist(error);
|
|
724
|
+
handlerCalled.should.equal(1);
|
|
725
|
+
done();
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
729
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
730
|
+
callback(null, {
|
|
731
|
+
id,
|
|
732
|
+
type,
|
|
733
|
+
attributes: [
|
|
734
|
+
{
|
|
735
|
+
name: 'position',
|
|
736
|
+
type: 'Array',
|
|
737
|
+
value: '[28, -104, 23]'
|
|
738
|
+
}
|
|
739
|
+
]
|
|
740
|
+
});
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
request(options, function (error, response, body) {
|
|
744
|
+
should.not.exist(error);
|
|
745
|
+
done();
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
749
|
+
let serviceReceived = false;
|
|
750
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
751
|
+
serviceReceived = service === 'smartgondor';
|
|
752
|
+
callback(null, {
|
|
753
|
+
id,
|
|
754
|
+
type,
|
|
755
|
+
attributes: [
|
|
756
|
+
{
|
|
757
|
+
name: 'position',
|
|
758
|
+
type: 'Array',
|
|
759
|
+
value: '[28, -104, 23]'
|
|
760
|
+
}
|
|
761
|
+
]
|
|
762
|
+
});
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
request(options, function (error, response, body) {
|
|
766
|
+
serviceReceived.should.equal(true);
|
|
767
|
+
done();
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
describe('When a sequential command with datasetId overwrites via PUT /attrs/attr-name arrives to the IoT Agent', function () {
|
|
773
|
+
const options = {
|
|
774
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs',
|
|
775
|
+
method: 'PUT',
|
|
776
|
+
json: {
|
|
777
|
+
position: [
|
|
778
|
+
{
|
|
779
|
+
type: 'Property',
|
|
780
|
+
value: [1, 2, 3],
|
|
781
|
+
datasetId: 'urn:ngsi-ld:this'
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
type: 'Property',
|
|
785
|
+
value: [28, -104, 23],
|
|
786
|
+
datasetId: 'urn:ngsi-ld:that'
|
|
787
|
+
}
|
|
788
|
+
]
|
|
789
|
+
},
|
|
790
|
+
headers: {
|
|
791
|
+
'fiware-service': 'smartgondor',
|
|
792
|
+
'content-type': 'application/ld+json'
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
beforeEach(function (done) {
|
|
797
|
+
logger.setLevel('ERROR');
|
|
798
|
+
iotAgentLib.register(device3, function (error) {
|
|
799
|
+
done();
|
|
800
|
+
});
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
it('should call the client handler once', function (done) {
|
|
804
|
+
let handlerCalled = 0;
|
|
805
|
+
|
|
806
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
807
|
+
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
808
|
+
type.should.equal(device3.type);
|
|
809
|
+
attributes[0].name.should.equal('position');
|
|
810
|
+
attributes[0].datasetId.should.equal('urn:ngsi-ld:this');
|
|
811
|
+
attributes[1].name.should.equal('position');
|
|
812
|
+
attributes[1].datasetId.should.equal('urn:ngsi-ld:that');
|
|
813
|
+
JSON.stringify(attributes[0].value).should.equal('[1,2,3]');
|
|
814
|
+
JSON.stringify(attributes[1].value).should.equal('[28,-104,23]');
|
|
815
|
+
handlerCalled++;
|
|
816
|
+
callback(null, {
|
|
817
|
+
id,
|
|
818
|
+
type,
|
|
819
|
+
attributes: [
|
|
820
|
+
{
|
|
821
|
+
name: 'position',
|
|
822
|
+
type: 'Array',
|
|
823
|
+
value: '[28, -104, 23]'
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
name: 'orientation',
|
|
827
|
+
type: 'Array',
|
|
828
|
+
value: '[1, 2, 3]'
|
|
829
|
+
}
|
|
830
|
+
]
|
|
831
|
+
});
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
request(options, function (error, response, body) {
|
|
835
|
+
should.not.exist(error);
|
|
836
|
+
handlerCalled.should.equal(1);
|
|
837
|
+
done();
|
|
838
|
+
});
|
|
839
|
+
});
|
|
840
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
841
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
842
|
+
callback(null, {
|
|
843
|
+
id,
|
|
844
|
+
type,
|
|
845
|
+
attributes: [
|
|
846
|
+
{
|
|
847
|
+
name: 'position',
|
|
848
|
+
type: 'Array',
|
|
849
|
+
value: '[28, -104, 23]'
|
|
850
|
+
}
|
|
851
|
+
]
|
|
852
|
+
});
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
request(options, function (error, response, body) {
|
|
856
|
+
should.not.exist(error);
|
|
857
|
+
done();
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
861
|
+
let serviceReceived = false;
|
|
862
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
863
|
+
serviceReceived = service === 'smartgondor';
|
|
864
|
+
callback(null, {
|
|
865
|
+
id,
|
|
866
|
+
type,
|
|
867
|
+
attributes: [
|
|
868
|
+
{
|
|
869
|
+
name: 'position',
|
|
870
|
+
type: 'Array',
|
|
871
|
+
value: '[28, -104, 23]'
|
|
872
|
+
}
|
|
873
|
+
]
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
request(options, function (error, response, body) {
|
|
878
|
+
serviceReceived.should.equal(true);
|
|
879
|
+
done();
|
|
880
|
+
});
|
|
881
|
+
});
|
|
882
|
+
});
|
|
883
|
+
|
|
368
884
|
describe('When multiple command overwrites via PUT /attrs arrive to the IoT Agent as Context Provider', function () {
|
|
369
885
|
const options = {
|
|
370
886
|
url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs',
|
|
@@ -471,7 +987,7 @@ describe('NGSI-LD - Command functionalities', function () {
|
|
|
471
987
|
});
|
|
472
988
|
});
|
|
473
989
|
|
|
474
|
-
describe('When a command overwrite PUT attrs/attr-name arrives to the IoT Agent as Context Provider', function () {
|
|
990
|
+
describe('When a command overwrite PUT attrs/attr-name with datasetId arrives to the IoT Agent as Context Provider', function () {
|
|
475
991
|
const options = {
|
|
476
992
|
url:
|
|
477
993
|
'http://localhost:' +
|
|
@@ -480,7 +996,8 @@ describe('NGSI-LD - Command functionalities', function () {
|
|
|
480
996
|
method: 'PUT',
|
|
481
997
|
json: {
|
|
482
998
|
type: 'Property',
|
|
483
|
-
value: [28, -104, 23]
|
|
999
|
+
value: [28, -104, 23],
|
|
1000
|
+
datasetId: 'urn:ngsi-ld:this'
|
|
484
1001
|
},
|
|
485
1002
|
headers: {
|
|
486
1003
|
'fiware-service': 'smartgondor',
|
|
@@ -502,6 +1019,105 @@ describe('NGSI-LD - Command functionalities', function () {
|
|
|
502
1019
|
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
503
1020
|
type.should.equal(device3.type);
|
|
504
1021
|
attributes[0].name.should.equal('position');
|
|
1022
|
+
attributes[0].datasetId.should.equal('urn:ngsi-ld:this');
|
|
1023
|
+
JSON.stringify(attributes[0].value).should.equal('[28,-104,23]');
|
|
1024
|
+
handlerCalled++;
|
|
1025
|
+
callback(null, {
|
|
1026
|
+
id,
|
|
1027
|
+
type,
|
|
1028
|
+
attributes: [
|
|
1029
|
+
{
|
|
1030
|
+
name: 'position',
|
|
1031
|
+
type: 'Array',
|
|
1032
|
+
value: '[28, -104, 23]'
|
|
1033
|
+
}
|
|
1034
|
+
]
|
|
1035
|
+
});
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
request(options, function (error, response, body) {
|
|
1039
|
+
should.not.exist(error);
|
|
1040
|
+
handlerCalled.should.equal(1);
|
|
1041
|
+
done();
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
1045
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
1046
|
+
callback(null, {
|
|
1047
|
+
id,
|
|
1048
|
+
type,
|
|
1049
|
+
attributes: [
|
|
1050
|
+
{
|
|
1051
|
+
name: 'position',
|
|
1052
|
+
type: 'Array',
|
|
1053
|
+
value: '[28, -104, 23]'
|
|
1054
|
+
}
|
|
1055
|
+
]
|
|
1056
|
+
});
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
request(options, function (error, response, body) {
|
|
1060
|
+
should.not.exist(error);
|
|
1061
|
+
done();
|
|
1062
|
+
});
|
|
1063
|
+
});
|
|
1064
|
+
it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
|
|
1065
|
+
let serviceReceived = false;
|
|
1066
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
1067
|
+
serviceReceived = service === 'smartgondor';
|
|
1068
|
+
callback(null, {
|
|
1069
|
+
id,
|
|
1070
|
+
type,
|
|
1071
|
+
attributes: [
|
|
1072
|
+
{
|
|
1073
|
+
name: 'position',
|
|
1074
|
+
type: 'Array',
|
|
1075
|
+
value: '[28, -104, 23]'
|
|
1076
|
+
}
|
|
1077
|
+
]
|
|
1078
|
+
});
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
request(options, function (error, response, body) {
|
|
1082
|
+
serviceReceived.should.equal(true);
|
|
1083
|
+
done();
|
|
1084
|
+
});
|
|
1085
|
+
});
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
describe('When a command update PUT attrs/attr-name with metadata arrives to the IoT Agent as Context Provider', function () {
|
|
1089
|
+
const options = {
|
|
1090
|
+
url:
|
|
1091
|
+
'http://localhost:' +
|
|
1092
|
+
iotAgentConfig.server.port +
|
|
1093
|
+
'/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/position',
|
|
1094
|
+
method: 'PUT',
|
|
1095
|
+
json: {
|
|
1096
|
+
type: 'Property',
|
|
1097
|
+
value: [28, -104, 23],
|
|
1098
|
+
qos: 1
|
|
1099
|
+
},
|
|
1100
|
+
headers: {
|
|
1101
|
+
'fiware-service': 'smartgondor',
|
|
1102
|
+
'content-type': 'application/ld+json'
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
beforeEach(function (done) {
|
|
1107
|
+
logger.setLevel('ERROR');
|
|
1108
|
+
iotAgentLib.register(device3, function (error) {
|
|
1109
|
+
done();
|
|
1110
|
+
});
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
it('should call the client handler once including metadata', function (done) {
|
|
1114
|
+
let handlerCalled = 0;
|
|
1115
|
+
|
|
1116
|
+
iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
|
|
1117
|
+
id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
|
|
1118
|
+
type.should.equal(device3.type);
|
|
1119
|
+
attributes[0].name.should.equal('position');
|
|
1120
|
+
attributes[0].metadata.qos.should.equal(1);
|
|
505
1121
|
JSON.stringify(attributes[0].value).should.equal('[28,-104,23]');
|
|
506
1122
|
handlerCalled++;
|
|
507
1123
|
callback(null, {
|
|
@@ -615,4 +1231,42 @@ describe('NGSI-LD - Command functionalities', function () {
|
|
|
615
1231
|
});
|
|
616
1232
|
});
|
|
617
1233
|
});
|
|
1234
|
+
|
|
1235
|
+
describe('When a query arrives to the IoT Agent with registered commands but no lazy attributes', function () {
|
|
1236
|
+
const options = {
|
|
1237
|
+
url:
|
|
1238
|
+
'http://localhost:' +
|
|
1239
|
+
iotAgentConfig.server.port +
|
|
1240
|
+
'/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2',
|
|
1241
|
+
method: 'GET',
|
|
1242
|
+
headers: {
|
|
1243
|
+
'fiware-service': 'smartgondor',
|
|
1244
|
+
'content-type': 'application/ld+json'
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
beforeEach(function (done) {
|
|
1249
|
+
logger.setLevel('ERROR');
|
|
1250
|
+
iotAgentLib.register(device3, function (error) {
|
|
1251
|
+
done();
|
|
1252
|
+
});
|
|
1253
|
+
});
|
|
1254
|
+
|
|
1255
|
+
it('should return the a valid empty response', function (done) {
|
|
1256
|
+
iotAgentLib.setDataQueryHandler(function (id, type, service, subservice, attributes, callback) {
|
|
1257
|
+
should.exist(attributes);
|
|
1258
|
+
attributes.length.should.equal(0);
|
|
1259
|
+
callback(null, {
|
|
1260
|
+
id: 'urn:ngsi-ld:Robot:r2d2',
|
|
1261
|
+
type: 'Robot'
|
|
1262
|
+
});
|
|
1263
|
+
});
|
|
1264
|
+
|
|
1265
|
+
request(options, function (error, response, body) {
|
|
1266
|
+
should.not.exist(error);
|
|
1267
|
+
response.statusCode.should.equal(200);
|
|
1268
|
+
done();
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
1271
|
+
});
|
|
618
1272
|
});
|