iotagent-node-lib 2.25.0 → 3.0.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 (91) hide show
  1. package/CHANGES_NEXT_RELEASE +0 -1
  2. package/config.js +6 -1
  3. package/doc/deprecated.md +4 -1
  4. package/doc/howto.md +8 -0
  5. package/doc/installationguide.md +18 -0
  6. package/doc/usermanual.md +77 -0
  7. package/lib/commonConfig.js +15 -1
  8. package/lib/constants.js +1 -0
  9. package/lib/fiware-iotagent-lib.js +1 -5
  10. package/lib/plugins/compressTimestamp.js +2 -7
  11. package/lib/plugins/expressionParser.js +0 -47
  12. package/lib/plugins/expressionPlugin.js +6 -78
  13. package/lib/plugins/jexlParser.js +0 -36
  14. package/lib/plugins/pluginUtils.js +0 -119
  15. package/lib/services/devices/deviceService.js +1 -0
  16. package/lib/services/devices/registrationUtils.js +21 -1
  17. package/lib/services/ngsi/entities-NGSI-LD.js +600 -199
  18. package/lib/services/ngsi/entities-NGSI-v2.js +620 -298
  19. package/lib/services/ngsi/ngsiUtils.js +15 -22
  20. package/lib/services/northBound/contextServer-NGSI-LD.js +221 -38
  21. package/lib/services/northBound/contextServer.js +14 -1
  22. package/lib/services/northBound/northboundServer.js +1 -0
  23. package/package.json +1 -1
  24. package/test/unit/general/loglevel-api_test.js +0 -2
  25. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +1 -1
  26. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgent1.json +24 -14
  27. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgent2.json +25 -15
  28. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgent4.json +15 -5
  29. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +9 -1
  30. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommandsAndLazy.json +32 -0
  31. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerProvisionedDevice.json +12 -1
  32. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerProvisionedDevice2.json +9 -1
  33. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerProvisionedDeviceWithGroup.json +12 -1
  34. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerProvisionedDeviceWithGroup2.json +12 -1
  35. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerProvisionedDeviceWithGroup3.json +9 -1
  36. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/updateCommands1.json +10 -2
  37. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/updateIoTAgent1.json +11 -1
  38. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/updateIoTAgent2.json +12 -1
  39. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin1.json +0 -5
  40. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast10.json +1 -1
  41. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast8.json +1 -1
  42. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast9.json +1 -1
  43. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +16 -15
  44. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin4.json +8 -8
  45. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin4a.json +34 -34
  46. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +8 -8
  47. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +0 -20
  48. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
  49. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +10 -10
  50. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin1.json +8 -7
  51. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +5 -4
  52. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin3.json +1 -1
  53. package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +4 -4
  54. package/test/unit/ngsi-ld/examples/contextRequests/updateContextTimestampOverride.json +4 -3
  55. package/test/unit/ngsi-ld/examples/contextRequests/updateContextTimestampOverrideWithoutMilis.json +4 -3
  56. package/test/unit/ngsi-ld/expressions/expressionBasedTransformations-test.js +2 -5
  57. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +1 -7
  58. package/test/unit/ngsi-ld/general/startup-test.js +17 -2
  59. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +1 -12
  60. package/test/unit/ngsi-ld/lazyAndCommands/merge-patch-test.js +249 -0
  61. package/test/unit/ngsi-ld/ngsiService/autocast-test.js +15 -3
  62. package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +171 -0
  63. package/test/unit/ngsi-ld/plugins/alias-plugin_test.js +0 -2
  64. package/test/unit/ngsi-ld/plugins/compress-timestamp-plugin_test.js +0 -31
  65. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +18 -18
  66. package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +19 -6
  67. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin1.json +2 -2
  68. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin11.json +5 -1
  69. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin5.json +4 -4
  70. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin6.json +0 -16
  71. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin7.json +0 -4
  72. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin8.json +8 -8
  73. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin1.json +42 -42
  74. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +7 -7
  75. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin4.json +0 -5
  76. package/test/unit/ngsiv2/examples/contextRequests/updateContextProcessTimestamp.json +1 -7
  77. package/test/unit/ngsiv2/expressions/expressionBasedTransformations-test.js +0 -3
  78. package/test/unit/ngsiv2/expressions/expressionCombinedTransformations-test.js +0 -6
  79. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +1 -7
  80. package/test/unit/ngsiv2/plugins/alias-plugin_test.js +0 -2
  81. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +0 -4
  82. package/test/unit/ngsiv2/plugins/compress-timestamp-plugin_test.js +0 -32
  83. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +5 -15
  84. package/test/unit/ngsiv2/plugins/timestamp-processing-plugin_test.js +1 -1
  85. package/lib/plugins/addEvent.js +0 -32
  86. package/lib/plugins/attributeAlias.js +0 -107
  87. package/lib/plugins/multiEntity.js +0 -255
  88. package/lib/plugins/timestampProcessPlugin.js +0 -95
  89. package/test/unit/ngsi-ld/plugins/event-plugin_test.js +0 -116
  90. package/test/unit/ngsiv2/plugins/event-plugin_test.js +0 -118
  91. package/test/unit/ngsiv2/plugins/translation-inPlugins_test.js +0 -262
@@ -293,13 +293,10 @@ const iotAgentConfigTS = {
293
293
 
294
294
  describe('NGSI-LD: JEXL', function () {
295
295
  beforeEach(function (done) {
296
- logger.setLevel('FATAL');
296
+ //logger.setLevel('FATAL');
297
297
 
298
298
  iotAgentLib.activate(iotAgentConfig, function () {
299
299
  iotAgentLib.clearAll(function () {
300
- iotAgentLib.addUpdateMiddleware(iotAgentLib.dataPlugins.attributeAlias.update);
301
- iotAgentLib.addQueryMiddleware(iotAgentLib.dataPlugins.attributeAlias.query);
302
- iotAgentLib.addUpdateMiddleware(iotAgentLib.dataPlugins.expressionTransformation.update);
303
300
  done();
304
301
  });
305
302
  });
@@ -964,9 +961,6 @@ describe('NGSI-LD: JEXL - Timestamps', function () {
964
961
 
965
962
  iotAgentLib.activate(iotAgentConfigTS, function () {
966
963
  iotAgentLib.clearAll(function () {
967
- iotAgentLib.addUpdateMiddleware(iotAgentLib.dataPlugins.attributeAlias.update);
968
- iotAgentLib.addQueryMiddleware(iotAgentLib.dataPlugins.attributeAlias.query);
969
- iotAgentLib.addUpdateMiddleware(iotAgentLib.dataPlugins.expressionTransformation.update);
970
964
  done();
971
965
  });
972
966
  });
@@ -66,7 +66,7 @@ describe('NGSI-LD - Startup tests', function () {
66
66
  beforeEach(function () {
67
67
  process.env.IOTA_CB_HOST = 'cbhost';
68
68
  process.env.IOTA_CB_PORT = '1111';
69
- process.env.IOTA_CB_NGSI_VERSION = 'v2';
69
+ process.env.IOTA_CB_NGSI_VERSION = 'ld';
70
70
  process.env.IOTA_NORTH_HOST = 'localhost';
71
71
  process.env.IOTA_NORTH_PORT = '2222';
72
72
  process.env.IOTA_PROVIDER_URL = 'provider:3333';
@@ -83,6 +83,11 @@ describe('NGSI-LD - Startup tests', function () {
83
83
  process.env.IOTA_MONGO_DB = 'themongodb';
84
84
  process.env.IOTA_MONGO_REPLICASET = 'customReplica';
85
85
  process.env.IOTA_DEFAULT_RESOURCE = '/iot/custom';
86
+ process.env.IOTA_JSON_LD_CONTEXT = 'http://context.jsonld';
87
+ process.env.IOTA_FALLBACK_TENANT = 'openiot';
88
+ process.env.IOTA_FALLBACK_PATH = 'smartgondor';
89
+ process.env.IOTA_LD_SUPPORT_NULL = 'false';
90
+ process.env.IOTA_LD_SUPPORT_DATASET_ID = 'false';
86
91
 
87
92
  nock.cleanAll();
88
93
 
@@ -114,6 +119,11 @@ describe('NGSI-LD - Startup tests', function () {
114
119
  delete process.env.IOTA_MONGO_DB;
115
120
  delete process.env.IOTA_MONGO_REPLICASET;
116
121
  delete process.env.IOTA_DEFAULT_RESOURCE;
122
+ delete process.env.IOTA_JSON_LD_CONTEXT;
123
+ delete process.env.IOTA_FALLBACK_TENANT;
124
+ delete process.env.IOTA_FALLBACK_PATH;
125
+ delete process.env.IOTA_LD_SUPPORT_NULL;
126
+ delete process.env.IOTA_LD_SUPPORT_DATASET_ID;
117
127
  });
118
128
 
119
129
  afterEach(function (done) {
@@ -123,7 +133,12 @@ describe('NGSI-LD - Startup tests', function () {
123
133
  it('should load the correct configuration parameters', function (done) {
124
134
  iotAgentLib.activate(iotAgentConfig, function (error) {
125
135
  config.getConfig().contextBroker.url.should.equal('http://cbhost:1111');
126
- config.getConfig().contextBroker.ngsiVersion.should.equal('v2');
136
+ config.getConfig().contextBroker.ngsiVersion.should.equal('ld');
137
+ config.getConfig().contextBroker.jsonLdContext.should.equal('http://context.jsonld');
138
+ config.getConfig().contextBroker.fallbackTenant.should.equal( 'openiot');
139
+ config.getConfig().contextBroker.fallbackPath.should.equal('smartgondor');
140
+ config.getConfig().server.ldSupport.null.should.equal(false);
141
+ config.getConfig().server.ldSupport.datasetId.should.equal(false);
127
142
  config.getConfig().server.host.should.equal('localhost');
128
143
  config.getConfig().server.port.should.equal('2222');
129
144
  config.getConfig().providerUrl.should.equal('provider:3333');
@@ -184,7 +184,6 @@ describe('NGSI-LD - Command functionalities', function () {
184
184
  };
185
185
 
186
186
  beforeEach(function (done) {
187
- logger.setLevel('ERROR');
188
187
  iotAgentLib.register(device3, function (error) {
189
188
  done();
190
189
  });
@@ -287,7 +286,6 @@ describe('NGSI-LD - Command functionalities', function () {
287
286
  };
288
287
 
289
288
  beforeEach(function (done) {
290
- logger.setLevel('ERROR');
291
289
  iotAgentLib.register(device3, function (error) {
292
290
  done();
293
291
  });
@@ -368,7 +366,7 @@ describe('NGSI-LD - Command functionalities', function () {
368
366
  describe('When a sequential command with datasetId updates via PATCH /attrs/attr-name arrives to the IoT Agent', function () {
369
367
  const options = {
370
368
  url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs',
371
- method: 'PUT',
369
+ method: 'PATCH',
372
370
  json: {
373
371
  position: [
374
372
  {
@@ -390,7 +388,6 @@ describe('NGSI-LD - Command functionalities', function () {
390
388
  };
391
389
 
392
390
  beforeEach(function (done) {
393
- logger.setLevel('ERROR');
394
391
  iotAgentLib.register(device3, function (error) {
395
392
  done();
396
393
  });
@@ -496,7 +493,6 @@ describe('NGSI-LD - Command functionalities', function () {
496
493
  };
497
494
 
498
495
  beforeEach(function (done) {
499
- logger.setLevel('ERROR');
500
496
  iotAgentLib.register(device3, function (error) {
501
497
  done();
502
498
  });
@@ -594,7 +590,6 @@ describe('NGSI-LD - Command functionalities', function () {
594
590
  };
595
591
 
596
592
  beforeEach(function (done) {
597
- logger.setLevel('ERROR');
598
593
  iotAgentLib.register(device3, function (error) {
599
594
  done();
600
595
  });
@@ -691,7 +686,6 @@ describe('NGSI-LD - Command functionalities', function () {
691
686
  };
692
687
 
693
688
  beforeEach(function (done) {
694
- logger.setLevel('ERROR');
695
689
  iotAgentLib.register(device3, function (error) {
696
690
  done();
697
691
  });
@@ -794,7 +788,6 @@ describe('NGSI-LD - Command functionalities', function () {
794
788
  };
795
789
 
796
790
  beforeEach(function (done) {
797
- logger.setLevel('ERROR');
798
791
  iotAgentLib.register(device3, function (error) {
799
792
  done();
800
793
  });
@@ -902,7 +895,6 @@ describe('NGSI-LD - Command functionalities', function () {
902
895
  };
903
896
 
904
897
  beforeEach(function (done) {
905
- logger.setLevel('ERROR');
906
898
  iotAgentLib.register(device3, function (error) {
907
899
  done();
908
900
  });
@@ -1006,7 +998,6 @@ describe('NGSI-LD - Command functionalities', function () {
1006
998
  };
1007
999
 
1008
1000
  beforeEach(function (done) {
1009
- logger.setLevel('ERROR');
1010
1001
  iotAgentLib.register(device3, function (error) {
1011
1002
  done();
1012
1003
  });
@@ -1104,7 +1095,6 @@ describe('NGSI-LD - Command functionalities', function () {
1104
1095
  };
1105
1096
 
1106
1097
  beforeEach(function (done) {
1107
- logger.setLevel('ERROR');
1108
1098
  iotAgentLib.register(device3, function (error) {
1109
1099
  done();
1110
1100
  });
@@ -1246,7 +1236,6 @@ describe('NGSI-LD - Command functionalities', function () {
1246
1236
  };
1247
1237
 
1248
1238
  beforeEach(function (done) {
1249
- logger.setLevel('ERROR');
1250
1239
  iotAgentLib.register(device3, function (error) {
1251
1240
  done();
1252
1241
  });
@@ -0,0 +1,249 @@
1
+ /*
2
+ * Copyright 2020 Telefonica Investigación y Desarrollo, S.A.U
3
+ *
4
+ * This file is part of fiware-iotagent-lib
5
+ *
6
+ * fiware-iotagent-lib is free software: you can redistribute it and/or
7
+ * modify it under the terms of the GNU Affero General Public License as
8
+ * published by the Free Software Foundation, either version 3 of the License,
9
+ * or (at your option) any later version.
10
+ *
11
+ * fiware-iotagent-lib is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+ * See the GNU Affero General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public
17
+ * License along with fiware-iotagent-lib.
18
+ * If not, seehttp://www.gnu.org/licenses/.
19
+ *
20
+ * For those usages not covered by the GNU Affero General Public License
21
+ * please contact with::[contacto@tid.es]
22
+ *
23
+ * Modified by: Jason Fox - FIWARE Foundation
24
+ */
25
+
26
+ /* eslint-disable no-unused-vars */
27
+
28
+ const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
29
+ const utils = require('../../../tools/utils');
30
+ const request = utils.request;
31
+ const should = require('should');
32
+ const logger = require('logops');
33
+ const nock = require('nock');
34
+ const mongoUtils = require('../../mongodb/mongoDBUtils');
35
+
36
+ const timekeeper = require('timekeeper');
37
+ let contextBrokerMock;
38
+ let statusAttributeMock;
39
+ const iotAgentConfig = {
40
+ contextBroker: {
41
+ host: '192.168.1.1',
42
+ port: '1026',
43
+ ngsiVersion: 'ld',
44
+ jsonLdContext: 'http://context.json-ld'
45
+ },
46
+ server: {
47
+ port: 4041,
48
+ ldSupport: {
49
+ null: true,
50
+ datasetId: false,
51
+ merge: true
52
+ }
53
+ },
54
+ types: {
55
+ Robot: {
56
+ internalAttributes:[],
57
+ commands:[
58
+ {
59
+ name: 'position',
60
+ object_id: 'pos',
61
+ type: 'Object'
62
+ },
63
+ {
64
+ name: 'orientation',
65
+ type: 'Object'
66
+ }
67
+ ],
68
+ lazy: [
69
+ {
70
+ name: 'batteryLevel',
71
+ type: 'Object'
72
+ }
73
+ ],
74
+ staticAttributes: [],
75
+ active: []
76
+ }
77
+ },
78
+ service: 'smartgondor',
79
+ providerUrl: 'http://smartgondor.com'
80
+ };
81
+ const device3 = {
82
+ id: 'r2d2',
83
+ type: 'Robot',
84
+ service: 'smartgondor'
85
+ };
86
+
87
+ describe('NGSI-LD - Merge-Patch functionalities', function () {
88
+ beforeEach(function (done) {
89
+ const time = new Date(1438760101468); // 2015-08-05T07:35:01.468+00:00
90
+ timekeeper.freeze(time);
91
+ nock.cleanAll();
92
+
93
+ contextBrokerMock = nock('http://192.168.1.1:1026')
94
+ .matchHeader('fiware-service', 'smartgondor')
95
+ .post(
96
+ '/ngsi-ld/v1/csourceRegistrations/',
97
+ utils.readExampleFile(
98
+ './test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommandsAndLazy.json'
99
+ )
100
+ )
101
+ .reply(201, null, { Location: '/ngsi-ld/v1/csourceRegistrations/6319a7f5254b05844116584d' });
102
+
103
+ contextBrokerMock
104
+ .matchHeader('fiware-service', 'smartgondor')
105
+ .post('/ngsi-ld/v1/entityOperations/upsert/')
106
+ .reply(204);
107
+
108
+ iotAgentLib.activate(iotAgentConfig, done);
109
+ });
110
+
111
+ afterEach(function (done) {
112
+ timekeeper.reset();
113
+ delete device3.registrationId;
114
+ iotAgentLib.clearAll(function () {
115
+ iotAgentLib.deactivate(function () {
116
+ mongoUtils.cleanDbs(function () {
117
+ nock.cleanAll();
118
+ iotAgentLib.setDataUpdateHandler();
119
+ iotAgentLib.setCommandHandler();
120
+ done();
121
+ });
122
+ });
123
+ });
124
+ });
125
+
126
+ describe('When a merge-patch PATCH arrives to the IoT Agent as Context Provider', function () {
127
+ const options = {
128
+ url:
129
+ 'http://localhost:' +
130
+ iotAgentConfig.server.port +
131
+ '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2',
132
+ method: 'PATCH',
133
+ json: {
134
+ "position": {
135
+ "type": "Property",
136
+ "value": {
137
+ "moveTo" : [12,34],
138
+ "observedAt": "urn:ngsi-ld:null",
139
+ "precision": {
140
+ "value": 0.95,
141
+ "unitCode": "C62"
142
+ }
143
+ }
144
+ },
145
+ "orientation" : "urn:ngsi-ld:null"
146
+ },
147
+ headers: {
148
+ 'fiware-service': 'smartgondor',
149
+ 'content-type': 'application/ld+json'
150
+ }
151
+ };
152
+
153
+ beforeEach(function (done) {
154
+ iotAgentLib.register(device3, function (error) {
155
+ done();
156
+ });
157
+ });
158
+
159
+ it('should call the client handler once', function (done) {
160
+ let handlerCalled = 0;
161
+
162
+ iotAgentLib.setMergePatchHandler(function (id, type, service, subservice, attributes, callback) {
163
+ id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
164
+ type.should.equal(device3.type);
165
+ attributes[0].name.should.equal('position');
166
+ attributes[1].name.should.equal('orientation');
167
+ should.equal(attributes[1].value, null);
168
+ handlerCalled++;
169
+ callback(null, {
170
+ id,
171
+ type,
172
+ attributes: [
173
+ {
174
+ name: 'position',
175
+ type: 'Array',
176
+ value: '[28, -104, 23]'
177
+ }
178
+ ]
179
+ });
180
+ });
181
+
182
+ request(options, function (error, response, body) {
183
+ should.not.exist(error);
184
+ response.statusCode.should.equal(200);
185
+ handlerCalled.should.equal(1);
186
+ done();
187
+ });
188
+ });
189
+ });
190
+
191
+
192
+ xdescribe('When a partial update PATCH with an NGSI-LD Null arrives to the IoT Agent as Context Provider', function () {
193
+ const options = {
194
+ url:
195
+ 'http://localhost:' +
196
+ iotAgentConfig.server.port +
197
+ '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/position',
198
+ method: 'PATCH',
199
+ json: {
200
+ "type": "Property",
201
+ "value": "urn:ngsi-ld:null"
202
+ },
203
+ headers: {
204
+ 'fiware-service': 'smartgondor',
205
+ 'content-type': 'application/ld+json'
206
+ }
207
+ };
208
+
209
+ beforeEach(function (done) {
210
+ logger.setLevel('FATAL');
211
+ iotAgentLib.register(device3, function (error) {
212
+ done();
213
+ });
214
+ });
215
+
216
+ it('should call the client handler once', function (done) {
217
+ let handlerCalled = 0;
218
+
219
+ iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
220
+ id.should.equal('urn:ngsi-ld:' + device3.type + ':' + device3.id);
221
+ type.should.equal(device3.type);
222
+ attributes[0].name.should.equal('position');
223
+ should.equal(attributes[0].value, null);
224
+ handlerCalled++;
225
+ callback(null, {
226
+ id,
227
+ type,
228
+ attributes: [
229
+ {
230
+ name: 'position',
231
+ type: 'Array',
232
+ value: null
233
+ }
234
+ ]
235
+ });
236
+ });
237
+
238
+ request(options, function (error, response, body) {
239
+ console.error(error)
240
+ should.not.exist(error);
241
+
242
+
243
+ response.statusCode.should.equal(204);
244
+ handlerCalled.should.equal(1);
245
+ done();
246
+ });
247
+ });
248
+ });
249
+ });
@@ -75,6 +75,18 @@ const iotAgentConfig = {
75
75
  {
76
76
  name: 'configuration',
77
77
  type: 'Object'
78
+ },
79
+ {
80
+ name: 'date',
81
+ type: 'Date'
82
+ },
83
+ {
84
+ name: 'time',
85
+ type: 'Time'
86
+ },
87
+ {
88
+ name: 'dateTime',
89
+ type: 'DateTime'
78
90
  }
79
91
  ]
80
92
  }
@@ -327,7 +339,7 @@ describe('NGSI-LD - JSON native types autocast test', function () {
327
339
  describe('When the IoT Agent receives new information from a device. Observation with Time type', function () {
328
340
  const values = [
329
341
  {
330
- name: 'configuration',
342
+ name: 'time',
331
343
  type: 'Time',
332
344
  value: '2016-04-30T14:59:46.000Z'
333
345
  }
@@ -360,7 +372,7 @@ describe('NGSI-LD - JSON native types autocast test', function () {
360
372
  describe('When the IoT Agent receives new information from a device. Observation with DateTime type', function () {
361
373
  const values = [
362
374
  {
363
- name: 'configuration',
375
+ name: 'dateTime',
364
376
  type: 'DateTime',
365
377
  value: '2016-04-30Z'
366
378
  }
@@ -393,7 +405,7 @@ describe('NGSI-LD - JSON native types autocast test', function () {
393
405
  describe('When the IoT Agent receives new information from a device. Observation with Date type', function () {
394
406
  const values = [
395
407
  {
396
- name: 'configuration',
408
+ name: 'date',
397
409
  type: 'Date',
398
410
  value: '2016-04-30T14:59:46.000Z'
399
411
  }
@@ -29,6 +29,7 @@ const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
29
29
  const utils = require('../../../tools/utils');
30
30
  const request = utils.request;
31
31
  const should = require('should');
32
+ const nock = require('nock');
32
33
 
33
34
  let contextBrokerMock;
34
35
  const iotAgentConfig = {
@@ -47,6 +48,50 @@ const iotAgentConfig = {
47
48
  providerUrl: 'http://smartgondor.com'
48
49
  };
49
50
 
51
+
52
+ const iotAgentConfigWithLimitedSupport = {
53
+ contextBroker: {
54
+ host: '192.168.1.1',
55
+ port: '1026',
56
+ ngsiVersion: 'ld',
57
+ jsonLdContext: 'http://context.json-ld'
58
+ },
59
+ server: {
60
+ port: 4041,
61
+ ldSupport : {
62
+ null: false,
63
+ datasetId: false
64
+ }
65
+ },
66
+ types: {
67
+ Robot: {
68
+ commands: [
69
+ {
70
+ name: 'position',
71
+ type: 'Array'
72
+ },
73
+ {
74
+ name: 'orientation',
75
+ type: 'Array'
76
+ }
77
+ ],
78
+ lazy: [],
79
+ staticAttributes: [],
80
+ active: []
81
+ }
82
+ },
83
+ service: 'smartgondor',
84
+ subservice: 'gardens',
85
+ providerUrl: 'http://smartgondor.com'
86
+ };
87
+
88
+ const device = {
89
+ id: 'r2d2',
90
+ type: 'Robot',
91
+ service: 'smartgondor'
92
+ };
93
+
94
+
50
95
  describe('NGSI-LD - Unsupported Endpoints', function () {
51
96
  beforeEach(function (done) {
52
97
  iotAgentLib.activate(iotAgentConfig, function () {
@@ -107,5 +152,131 @@ describe('NGSI-LD - Unsupported Endpoints', function () {
107
152
  done();
108
153
  });
109
154
  });
155
+
156
+
157
+ it('PUT /entities/<entity-id> includes an NGSI-LD Null should return a valid NSGI-LD error message', function (done) {
158
+ const options = {
159
+ url:
160
+ 'http://localhost:' +
161
+ iotAgentConfig.server.port +
162
+ '/ngsi-ld/v1/entities/urn:ngsi-ld:entity/attrs/att',
163
+ method: 'PUT',
164
+ json: {
165
+ "value": "urn:ngsi-ld:null"
166
+ },
167
+ headers: {
168
+ 'fiware-service': 'smartgondor',
169
+ 'content-type': 'application/ld+json'
170
+ }
171
+ };
172
+ request(options, function (error, response, body) {
173
+ response.statusCode.should.equal(400);
174
+ done();
175
+ });
176
+ });
177
+ });
178
+ });
179
+
180
+ describe('NGSI-LD - Limiting Support', function () {
181
+ beforeEach(function (done) {
182
+ contextBrokerMock = nock('http://192.168.1.1:1026')
183
+ .matchHeader('fiware-service', 'smartgondor')
184
+ .post(
185
+ '/ngsi-ld/v1/csourceRegistrations/',
186
+ utils.readExampleFile(
187
+ './test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json'
188
+ )
189
+ )
190
+ .reply(201, null, { Location: '/ngsi-ld/v1/csourceRegistrations/6319a7f5254b05844116584d' });
191
+
192
+ contextBrokerMock
193
+ .matchHeader('fiware-service', 'smartgondor')
194
+ .post('/ngsi-ld/v1/entityOperations/upsert/')
195
+ .reply(204);
196
+
197
+
198
+ iotAgentLib.activate(iotAgentConfigWithLimitedSupport, function () {
199
+ iotAgentLib.clearAll(function () {
200
+ done();
201
+ });
202
+ });
203
+ });
204
+
205
+ afterEach(function (done) {
206
+ iotAgentLib.clearAll(function () {
207
+ iotAgentLib.deactivate(done);
208
+ });
110
209
  });
210
+
211
+ describe('When sending sending an NGSI-LD Null when nulls are unsupported', function () {
212
+ it('should return a valid NSGI-LD error message', function (done) {
213
+ const options = {
214
+ url:
215
+ 'http://localhost:' +
216
+ iotAgentConfig.server.port +
217
+ '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/position',
218
+ method: 'PATCH',
219
+ json: {
220
+ "value": "urn:ngsi-ld:null"
221
+ },
222
+ headers: {
223
+ 'fiware-service': 'smartgondor',
224
+ 'content-type': 'application/ld+json'
225
+ }
226
+ };
227
+
228
+ iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
229
+ callback(null, {});
230
+ });
231
+
232
+ iotAgentLib.register(device, function (error) {
233
+ request(options, function (error, response, body) {
234
+ response.statusCode.should.equal(400);
235
+ done();
236
+ });
237
+ });
238
+
239
+ });
240
+ });
241
+ describe('When sending a payload including a datasetId when datasetIds are unsupported ', function () {
242
+ it('should return a valid NSGI-LD error message', function (done) {
243
+ const options = {
244
+ url:
245
+ 'http://localhost:' +
246
+ iotAgentConfig.server.port +
247
+ '/ngsi-ld/v1/entities/urn:ngsi-ld:Robot:r2d2/attrs/',
248
+ method: 'PATCH',
249
+ json: {
250
+ position: [
251
+ {
252
+ type: 'Property',
253
+ value: [1, 2, 3],
254
+ datasetId: 'urn:ngsi-ld:this'
255
+ },
256
+ {
257
+ type: 'Property',
258
+ value: [28, -104, 23],
259
+ datasetId: 'urn:ngsi-ld:that'
260
+ }
261
+ ]
262
+ },
263
+ headers: {
264
+ 'fiware-service': 'smartgondor',
265
+ 'content-type': 'application/ld+json'
266
+ }
267
+ };
268
+
269
+ iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
270
+ callback(null, {});
271
+ });
272
+
273
+ iotAgentLib.register(device, function (error) {
274
+ request(options, function (error, response, body) {
275
+ response.statusCode.should.equal(400);
276
+ done();
277
+ });
278
+ });
279
+
280
+ });
281
+ });
111
282
  });
@@ -117,8 +117,6 @@ describe('NGSI-LD - Attribute alias plugin', function () {
117
117
 
118
118
  iotAgentLib.activate(iotAgentConfig, function () {
119
119
  iotAgentLib.clearAll(function () {
120
- iotAgentLib.addUpdateMiddleware(iotAgentLib.dataPlugins.attributeAlias.update);
121
- iotAgentLib.addQueryMiddleware(iotAgentLib.dataPlugins.attributeAlias.query);
122
120
  done();
123
121
  });
124
122
  });