iotagent-node-lib 4.5.0 → 4.6.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/README.md +67 -272
- package/doc/README.md +1 -1
- package/doc/admin.md +3 -15
- package/doc/api.md +469 -134
- package/doc/deprecated.md +4 -0
- package/doc/devel/architecture.md +5 -135
- package/doc/devel/development.md +224 -12
- package/doc/getting-started.md +114 -53
- package/doc/roadmap.md +5 -5
- package/docker/Mosquitto/Dockerfile +2 -2
- package/docker/Mosquitto/README.md +14 -11
- package/lib/constants.js +3 -0
- package/lib/fiware-iotagent-lib.js +12 -15
- package/lib/jexlTranformsMap.js +3 -1
- package/lib/model/dbConn.js +1 -4
- package/lib/services/common/alarmManagement.js +3 -0
- package/lib/services/groups/groupService.js +1 -1
- package/lib/services/ngsi/entities-NGSI-LD.js +320 -570
- package/lib/services/ngsi/entities-NGSI-v2.js +36 -1
- package/lib/services/ngsi/ngsiService.js +3 -1
- package/lib/services/northBound/deviceGroupAdministrationServer.js +42 -6
- package/lib/services/northBound/deviceProvisioningServer.js +0 -1
- package/lib/services/northBound/northboundServer.js +2 -0
- package/lib/services/stats/statsRegistry.js +128 -101
- package/lib/templates/createDevice.json +0 -24
- package/lib/templates/createDeviceLax.json +0 -23
- package/lib/templates/deviceGroup.json +1 -25
- package/lib/templates/updateDevice.json +0 -24
- package/lib/templates/updateDeviceLax.json +0 -23
- package/package.json +2 -2
- package/scripts/legacy_expression_tool/README.md +0 -1
- package/test/functional/README.md +22 -17
- package/test/functional/functional-tests-runner.js +9 -4
- package/test/functional/functional-tests.js +4 -4
- package/test/functional/testCases.js +245 -4
- package/test/unit/examples/deviceProvisioningRequests/provisionFullDevice.json +1 -13
- package/test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json +44 -0
- package/test/unit/examples/groupProvisioningRequests/provisionDuplicateConfigGroup.json +35 -0
- package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroup.json +36 -0
- package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroupAlternate.json +36 -0
- package/test/unit/general/deviceService-test.js +102 -0
- package/test/unit/general/statistics-service_test.js +1 -74
- package/test/unit/mongodb/mongodb-configGroup-registry-test.js +452 -0
- package/test/unit/mongodb/mongodb-connectionoptions-test.js +2 -3
- package/test/unit/mongodb/mongodb-group-registry-test.js +34 -33
- package/test/unit/mongodb/mongodb-service-registry-test.js +477 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +4 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +22 -22
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +4 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +14 -15
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +23 -23
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin15.json +0 -5
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +11 -16
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +23 -28
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +8 -13
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +24 -29
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +12 -17
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextStaticLinkedAttributes.json +12 -10
- package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +0 -102
- package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +4 -5
- package/test/unit/ngsi-ld/provisioning/listProvisionedDevices-test.js +0 -4
- package/test/unit/ngsiv2/general/deviceService-test.js +94 -1
- package/test/unit/ngsiv2/general/iotam-autoregistration-test.js +195 -0
- package/test/unit/ngsiv2/provisioning/device-group-api-test.js +259 -0
- package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +1189 -0
- package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +0 -4
- package/test/unit/statsRegistry/openmetrics-test.js +167 -0
- package/lib/templates/queryContext.json +0 -25
- package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +0 -35
- package/test/unit/examples/deviceProvisioningRequests/provisionDeviceBidirectionalGroup.json +0 -17
- package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +0 -31
- package/test/unit/general/statistics-persistence_test.js +0 -121
- package/test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json +0 -17
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +0 -12
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +0 -21
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -17
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -23
- package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +0 -132
- package/test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json +0 -8
- package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
- package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -19
- package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -24
|
@@ -156,6 +156,34 @@ const groupCreation = {
|
|
|
156
156
|
'fiware-servicepath': '/testingPath'
|
|
157
157
|
}
|
|
158
158
|
};
|
|
159
|
+
const configGroupCreation = {
|
|
160
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/groups',
|
|
161
|
+
method: 'POST',
|
|
162
|
+
json: {
|
|
163
|
+
groups: [
|
|
164
|
+
{
|
|
165
|
+
resource: '',
|
|
166
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
167
|
+
entity_type: 'TheLightType',
|
|
168
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
169
|
+
cbHost: 'http://192.168.1.1:1026',
|
|
170
|
+
commands: [],
|
|
171
|
+
lazy: [],
|
|
172
|
+
attributes: [
|
|
173
|
+
{
|
|
174
|
+
name: 'status',
|
|
175
|
+
type: 'Boolean'
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
static_attributes: []
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
headers: {
|
|
183
|
+
'fiware-service': 'testservice',
|
|
184
|
+
'fiware-servicepath': '/testingPath'
|
|
185
|
+
}
|
|
186
|
+
};
|
|
159
187
|
const deviceCreation = {
|
|
160
188
|
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
|
|
161
189
|
method: 'POST',
|
|
@@ -182,7 +210,7 @@ describe('NGSI-v2 - Device Service: utils', function () {
|
|
|
182
210
|
nock.cleanAll();
|
|
183
211
|
async.series([iotAgentLib.clearAll, iotAgentLib.deactivate], done);
|
|
184
212
|
});
|
|
185
|
-
|
|
213
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
186
214
|
describe('When an existing device tries to be retrieved with retrieveOrCreate()', function () {
|
|
187
215
|
beforeEach(function (done) {
|
|
188
216
|
// This mock does not check the payload since the aim of the test is not to verify
|
|
@@ -212,7 +240,39 @@ describe('NGSI-v2 - Device Service: utils', function () {
|
|
|
212
240
|
});
|
|
213
241
|
});
|
|
214
242
|
});
|
|
243
|
+
describe('When an existing device tries to be retrieved with retrieveOrCreate()', function () {
|
|
244
|
+
beforeEach(function (done) {
|
|
245
|
+
// This mock does not check the payload since the aim of the test is not to verify
|
|
246
|
+
// device provisioning functionality. Appropriate verification is done in tests under
|
|
247
|
+
// provisioning folder
|
|
248
|
+
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
249
|
+
.matchHeader('fiware-service', 'testservice')
|
|
250
|
+
.matchHeader('fiware-servicepath', '/testingPath')
|
|
251
|
+
.post('/v2/entities?options=upsert')
|
|
252
|
+
.reply(204);
|
|
253
|
+
|
|
254
|
+
async.series(
|
|
255
|
+
[
|
|
256
|
+
utils.request.bind(utils.request, configGroupCreation),
|
|
257
|
+
utils.request.bind(utils.request, deviceCreation)
|
|
258
|
+
],
|
|
259
|
+
function (error, results) {
|
|
260
|
+
done();
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('should return the existing device', function (done) {
|
|
266
|
+
iotAgentLib.retrieveDevice('Light1', '801230BJKL23Y9090DSFL123HJK09H324HV8732', function (error, device) {
|
|
267
|
+
should.not.exist(error);
|
|
268
|
+
should.exist(device);
|
|
215
269
|
|
|
270
|
+
device.id.should.equal('Light1');
|
|
271
|
+
done();
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
216
276
|
describe('When an unexisting device tries to be retrieved for an existing APIKey', function () {
|
|
217
277
|
beforeEach(function (done) {
|
|
218
278
|
// This mock does not check the payload since the aim of the test is not to verify
|
|
@@ -246,6 +306,39 @@ describe('NGSI-v2 - Device Service: utils', function () {
|
|
|
246
306
|
});
|
|
247
307
|
});
|
|
248
308
|
|
|
309
|
+
describe('When an unexisting device tries to be retrieved for an existing APIKey', function () {
|
|
310
|
+
beforeEach(function (done) {
|
|
311
|
+
// This mock does not check the payload since the aim of the test is not to verify
|
|
312
|
+
// device provisioning functionality. Appropriate verification is done in tests under
|
|
313
|
+
// provisioning folder
|
|
314
|
+
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
315
|
+
.matchHeader('fiware-service', 'testservice')
|
|
316
|
+
.matchHeader('fiware-servicepath', '/testingPath')
|
|
317
|
+
.post('/v2/entities?options=upsert')
|
|
318
|
+
.reply(204);
|
|
319
|
+
|
|
320
|
+
async.series([utils.request.bind(utils.request, configGroupCreation)], function (error, results) {
|
|
321
|
+
done();
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('should register the device and return it', function (done) {
|
|
326
|
+
iotAgentLib.retrieveDevice(
|
|
327
|
+
'UNEXISTENT_DEV',
|
|
328
|
+
'801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
329
|
+
function (error, device) {
|
|
330
|
+
should.not.exist(error);
|
|
331
|
+
should.exist(device);
|
|
332
|
+
|
|
333
|
+
device.id.should.equal('UNEXISTENT_DEV');
|
|
334
|
+
should.exist(device.protocol);
|
|
335
|
+
device.protocol.should.equal('MQTT_UL');
|
|
336
|
+
done();
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
249
342
|
describe('When an unexisting device tries to be retrieved for an unexisting APIKey', function () {
|
|
250
343
|
it('should raise an error', function (done) {
|
|
251
344
|
iotAgentLib.retrieveDevice(
|
|
@@ -134,6 +134,43 @@ const optionsCreation = {
|
|
|
134
134
|
'fiware-servicepath': 'theSubService'
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
|
+
const configGroupCreation = {
|
|
138
|
+
url: 'http://localhost:4041/iot/groups',
|
|
139
|
+
method: 'POST',
|
|
140
|
+
json: {
|
|
141
|
+
groups: [
|
|
142
|
+
{
|
|
143
|
+
resource: '/deviceTest',
|
|
144
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
145
|
+
entity_type: 'SensorMachine',
|
|
146
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
147
|
+
cbHost: 'http://unexistentHost:1026',
|
|
148
|
+
commands: [
|
|
149
|
+
{
|
|
150
|
+
name: 'wheel1',
|
|
151
|
+
type: 'Wheel'
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
lazy: [
|
|
155
|
+
{
|
|
156
|
+
name: 'luminescence',
|
|
157
|
+
type: 'Lumens'
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
attributes: [
|
|
161
|
+
{
|
|
162
|
+
name: 'status',
|
|
163
|
+
type: 'Boolean'
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
headers: {
|
|
170
|
+
'fiware-service': 'theservice',
|
|
171
|
+
'fiware-servicepath': 'theSubService'
|
|
172
|
+
}
|
|
173
|
+
};
|
|
137
174
|
const optionsCreationStatic = {
|
|
138
175
|
url: 'http://localhost:4041/iot/services',
|
|
139
176
|
method: 'POST',
|
|
@@ -172,6 +209,44 @@ const optionsCreationStatic = {
|
|
|
172
209
|
'fiware-servicepath': 'theSubService'
|
|
173
210
|
}
|
|
174
211
|
};
|
|
212
|
+
const configGroupCreationStatic = {
|
|
213
|
+
url: 'http://localhost:4041/iot/groups',
|
|
214
|
+
method: 'POST',
|
|
215
|
+
json: {
|
|
216
|
+
groups: [
|
|
217
|
+
{
|
|
218
|
+
resource: '/deviceTest',
|
|
219
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
220
|
+
entity_type: 'SensorMachine',
|
|
221
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
222
|
+
cbHost: 'http://unexistentHost:1026',
|
|
223
|
+
commands: [
|
|
224
|
+
{
|
|
225
|
+
name: 'wheel1',
|
|
226
|
+
type: 'Wheel'
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
static_attributes: [
|
|
230
|
+
{
|
|
231
|
+
name: 'position',
|
|
232
|
+
type: 'location',
|
|
233
|
+
values: '123,12'
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
attributes: [
|
|
237
|
+
{
|
|
238
|
+
name: 'status',
|
|
239
|
+
type: 'Boolean'
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
headers: {
|
|
246
|
+
'fiware-service': 'theservice',
|
|
247
|
+
'fiware-servicepath': 'theSubService'
|
|
248
|
+
}
|
|
249
|
+
};
|
|
175
250
|
const optionsDelete = {
|
|
176
251
|
url: 'http://localhost:4041/iot/services',
|
|
177
252
|
method: 'DELETE',
|
|
@@ -185,6 +260,19 @@ const optionsDelete = {
|
|
|
185
260
|
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
186
261
|
}
|
|
187
262
|
};
|
|
263
|
+
const configGroupDelete = {
|
|
264
|
+
url: 'http://localhost:4041/iot/groups',
|
|
265
|
+
method: 'DELETE',
|
|
266
|
+
json: {},
|
|
267
|
+
headers: {
|
|
268
|
+
'fiware-service': 'theservice',
|
|
269
|
+
'fiware-servicepath': 'theSubService'
|
|
270
|
+
},
|
|
271
|
+
qs: {
|
|
272
|
+
resource: '/deviceTest',
|
|
273
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
274
|
+
}
|
|
275
|
+
};
|
|
188
276
|
let iotamMock;
|
|
189
277
|
|
|
190
278
|
describe('NGSI-v2 - IoT Manager autoregistration', function () {
|
|
@@ -263,6 +351,7 @@ describe('NGSI-v2 - IoT Manager autoregistration', function () {
|
|
|
263
351
|
});
|
|
264
352
|
});
|
|
265
353
|
|
|
354
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
266
355
|
describe('When a new service is created in the IoT Agent', function () {
|
|
267
356
|
beforeEach(function (done) {
|
|
268
357
|
nock.cleanAll();
|
|
@@ -298,6 +387,42 @@ describe('NGSI-v2 - IoT Manager autoregistration', function () {
|
|
|
298
387
|
});
|
|
299
388
|
});
|
|
300
389
|
|
|
390
|
+
describe('When a new configGroup is created in the IoT Agent', function () {
|
|
391
|
+
beforeEach(function (done) {
|
|
392
|
+
nock.cleanAll();
|
|
393
|
+
|
|
394
|
+
iotamMock = nock('http://mockediotam.com:9876')
|
|
395
|
+
.post('/protocols', utils.readExampleFile('./test/unit/examples/iotamRequests/registrationEmpty.json'))
|
|
396
|
+
.reply(200, utils.readExampleFile('./test/unit/examples/iotamResponses/registrationSuccess.json'));
|
|
397
|
+
|
|
398
|
+
iotamMock
|
|
399
|
+
.post(
|
|
400
|
+
'/protocols',
|
|
401
|
+
utils.readExampleFile('./test/unit/examples/iotamRequests/registrationWithGroups.json')
|
|
402
|
+
)
|
|
403
|
+
.reply(200, utils.readExampleFile('./test/unit/examples/iotamResponses/registrationSuccess.json'));
|
|
404
|
+
|
|
405
|
+
iotAgentLib.activate(iotAgentConfig, function (error) {
|
|
406
|
+
done();
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
afterEach(function (done) {
|
|
411
|
+
groupRegistryMemory.clear(function () {
|
|
412
|
+
iotAgentLib.deactivate(done);
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('should update the registration in the IoT Manager', function (done) {
|
|
417
|
+
request(configGroupCreation, function (error, result, body) {
|
|
418
|
+
should.not.exist(error);
|
|
419
|
+
iotamMock.done();
|
|
420
|
+
done();
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
301
426
|
describe('When a service is removed from the IoT Agent', function () {
|
|
302
427
|
beforeEach(function (done) {
|
|
303
428
|
nock.cleanAll();
|
|
@@ -333,6 +458,42 @@ describe('NGSI-v2 - IoT Manager autoregistration', function () {
|
|
|
333
458
|
});
|
|
334
459
|
});
|
|
335
460
|
|
|
461
|
+
describe('When a configGroup is removed from the IoT Agent', function () {
|
|
462
|
+
beforeEach(function (done) {
|
|
463
|
+
nock.cleanAll();
|
|
464
|
+
|
|
465
|
+
iotamMock = nock('http://mockediotam.com:9876')
|
|
466
|
+
.post(
|
|
467
|
+
'/protocols',
|
|
468
|
+
utils.readExampleFile('./test/unit/examples/iotamRequests/registrationWithGroups.json')
|
|
469
|
+
)
|
|
470
|
+
.reply(200, utils.readExampleFile('./test/unit/examples/iotamResponses/registrationSuccess.json'));
|
|
471
|
+
|
|
472
|
+
iotamMock
|
|
473
|
+
.post('/protocols', utils.readExampleFile('./test/unit/examples/iotamRequests/registrationEmpty.json'))
|
|
474
|
+
.reply(200, utils.readExampleFile('./test/unit/examples/iotamResponses/registrationSuccess.json'));
|
|
475
|
+
|
|
476
|
+
groupRegistryMemory.create(groupCreation, function () {
|
|
477
|
+
iotAgentLib.activate(iotAgentConfig, done);
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
afterEach(function (done) {
|
|
482
|
+
groupRegistryMemory.clear(function () {
|
|
483
|
+
iotAgentLib.deactivate(done);
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it('should update the registration in the IoT Manager', function (done) {
|
|
488
|
+
request(configGroupDelete, function (error, result, body) {
|
|
489
|
+
should.not.exist(error);
|
|
490
|
+
iotamMock.done();
|
|
491
|
+
done();
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
336
497
|
describe('When a new service with static attributes is created in the IoT Agent', function () {
|
|
337
498
|
beforeEach(function (done) {
|
|
338
499
|
nock.cleanAll();
|
|
@@ -367,4 +528,38 @@ describe('NGSI-v2 - IoT Manager autoregistration', function () {
|
|
|
367
528
|
});
|
|
368
529
|
});
|
|
369
530
|
});
|
|
531
|
+
describe('When a new configGroup with static attributes is created in the IoT Agent', function () {
|
|
532
|
+
beforeEach(function (done) {
|
|
533
|
+
nock.cleanAll();
|
|
534
|
+
|
|
535
|
+
iotamMock = nock('http://mockediotam.com:9876')
|
|
536
|
+
.post('/protocols', utils.readExampleFile('./test/unit/examples/iotamRequests/registrationEmpty.json'))
|
|
537
|
+
.reply(200, utils.readExampleFile('./test/unit/examples/iotamResponses/registrationSuccess.json'));
|
|
538
|
+
|
|
539
|
+
iotamMock
|
|
540
|
+
.post(
|
|
541
|
+
'/protocols',
|
|
542
|
+
utils.readExampleFile('./test/unit/examples/iotamRequests/registrationWithStaticGroups.json')
|
|
543
|
+
)
|
|
544
|
+
.reply(200, utils.readExampleFile('./test/unit/examples/iotamResponses/registrationSuccess.json'));
|
|
545
|
+
|
|
546
|
+
iotAgentLib.activate(iotAgentConfig, function (error) {
|
|
547
|
+
done();
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
afterEach(function (done) {
|
|
552
|
+
groupRegistryMemory.clear(function () {
|
|
553
|
+
iotAgentLib.deactivate(done);
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('should update the registration in the IoT Manager', function (done) {
|
|
558
|
+
request(configGroupCreationStatic, function (error, result, body) {
|
|
559
|
+
should.not.exist(error);
|
|
560
|
+
iotamMock.done();
|
|
561
|
+
done();
|
|
562
|
+
});
|
|
563
|
+
});
|
|
564
|
+
});
|
|
370
565
|
});
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
/* eslint-disable no-unused-vars */
|
|
25
25
|
|
|
26
|
+
// #FIXME1649: parallel tests in device-provisioning-configGroup-api_test.js.
|
|
27
|
+
|
|
26
28
|
const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
|
|
27
29
|
const _ = require('underscore');
|
|
28
30
|
const async = require('async');
|
|
@@ -118,6 +120,19 @@ const optionsDelete = {
|
|
|
118
120
|
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
119
121
|
}
|
|
120
122
|
};
|
|
123
|
+
const optionsDeleteGroup = {
|
|
124
|
+
url: 'http://localhost:4041/iot/services',
|
|
125
|
+
method: 'DELETE',
|
|
126
|
+
json: {},
|
|
127
|
+
headers: {
|
|
128
|
+
'fiware-service': 'Testservice',
|
|
129
|
+
'fiware-servicepath': '/testingPath'
|
|
130
|
+
},
|
|
131
|
+
qs: {
|
|
132
|
+
resource: '/deviceTest',
|
|
133
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
134
|
+
}
|
|
135
|
+
};
|
|
121
136
|
const optionsDeleteDevice = {
|
|
122
137
|
url: 'http://localhost:4041/iot/services',
|
|
123
138
|
method: 'DELETE',
|
|
@@ -175,6 +190,49 @@ const optionsUpdate = {
|
|
|
175
190
|
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
176
191
|
}
|
|
177
192
|
};
|
|
193
|
+
const optionsUpdateGroup = {
|
|
194
|
+
url: 'http://localhost:4041/iot/services',
|
|
195
|
+
method: 'PUT',
|
|
196
|
+
json: {
|
|
197
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
198
|
+
cbHost: 'http://anotherUnexistentHost:1026',
|
|
199
|
+
transport: 'MQTT',
|
|
200
|
+
endpoint: 'http://yourendpoint.com',
|
|
201
|
+
commands: [
|
|
202
|
+
{
|
|
203
|
+
name: 'wheel1',
|
|
204
|
+
type: 'Wheel'
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
lazy: [
|
|
208
|
+
{
|
|
209
|
+
name: 'luminescence',
|
|
210
|
+
type: 'Lumens'
|
|
211
|
+
}
|
|
212
|
+
],
|
|
213
|
+
attributes: [
|
|
214
|
+
{
|
|
215
|
+
name: 'status',
|
|
216
|
+
type: 'Boolean'
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
static_attributes: [
|
|
220
|
+
{
|
|
221
|
+
name: 'identifier',
|
|
222
|
+
type: 'UUID',
|
|
223
|
+
value: 'WERTYUIOP234567890'
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
headers: {
|
|
228
|
+
'fiware-service': 'Testservice',
|
|
229
|
+
'fiware-servicepath': '/testingPath'
|
|
230
|
+
},
|
|
231
|
+
qs: {
|
|
232
|
+
resource: '/deviceTest',
|
|
233
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
234
|
+
}
|
|
235
|
+
};
|
|
178
236
|
const optionsList = {
|
|
179
237
|
url: 'http://localhost:4041/iot/services',
|
|
180
238
|
method: 'GET',
|
|
@@ -194,6 +252,20 @@ const optionsGet = {
|
|
|
194
252
|
}
|
|
195
253
|
};
|
|
196
254
|
|
|
255
|
+
// Add new options using the literal groups instead of services
|
|
256
|
+
const configGroupTerm = 'groups';
|
|
257
|
+
|
|
258
|
+
const newOptionsCreation = JSON.parse(JSON.stringify(optionsCreation));
|
|
259
|
+
newOptionsCreation.url = newOptionsCreation.url.replace('services', configGroupTerm);
|
|
260
|
+
newOptionsCreation.json[configGroupTerm] = newOptionsCreation.json.services;
|
|
261
|
+
delete newOptionsCreation.json.services;
|
|
262
|
+
|
|
263
|
+
const newOptionsList = JSON.parse(JSON.stringify(optionsList));
|
|
264
|
+
newOptionsList.url = newOptionsList.url.replace('services', configGroupTerm);
|
|
265
|
+
|
|
266
|
+
const newOptionsGet = JSON.parse(JSON.stringify(optionsGet));
|
|
267
|
+
newOptionsGet.url = newOptionsGet.url.replace('services', configGroupTerm);
|
|
268
|
+
|
|
197
269
|
describe('NGSI-v2 - Device Group Configuration API', function () {
|
|
198
270
|
beforeEach(function (done) {
|
|
199
271
|
iotAgentLib.activate(iotAgentConfig, function () {
|
|
@@ -411,6 +483,33 @@ describe('NGSI-v2 - Device Group Configuration API', function () {
|
|
|
411
483
|
});
|
|
412
484
|
});
|
|
413
485
|
});
|
|
486
|
+
describe('When a device group removal request arrives with service-header in uppercase', function () {
|
|
487
|
+
beforeEach(function (done) {
|
|
488
|
+
request(optionsCreation, done);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
it('should return a 204 OK', function (done) {
|
|
492
|
+
request(optionsDeleteGroup, function (error, response, body) {
|
|
493
|
+
should.not.exist(error);
|
|
494
|
+
response.statusCode.should.equal(204);
|
|
495
|
+
done();
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
it('should remove it from the database', function (done) {
|
|
499
|
+
request(optionsDeleteGroup, function (error, response, body) {
|
|
500
|
+
request(optionsList, function (error, response, body) {
|
|
501
|
+
body.count.should.equal(0);
|
|
502
|
+
done();
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
it('should remove it from the configuration', function (done) {
|
|
507
|
+
request(optionsDeleteGroup, function (error, response, body) {
|
|
508
|
+
should.not.exist(iotAgentConfig.types.SensorMachine);
|
|
509
|
+
done();
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
});
|
|
414
513
|
describe('When a device group removal request arrives with device=true option', function () {
|
|
415
514
|
let contextBrokerMock;
|
|
416
515
|
|
|
@@ -704,6 +803,83 @@ describe('NGSI-v2 - Device Group Configuration API', function () {
|
|
|
704
803
|
});
|
|
705
804
|
});
|
|
706
805
|
|
|
806
|
+
describe('When a device group update request arrives with service-header in uppercase', function () {
|
|
807
|
+
beforeEach(function (done) {
|
|
808
|
+
const optionsCreation1 = _.clone(optionsCreation);
|
|
809
|
+
const optionsCreation2 = _.clone(optionsCreation);
|
|
810
|
+
const optionsCreation3 = _.clone(optionsCreation);
|
|
811
|
+
|
|
812
|
+
optionsCreation1.json = { services: [] };
|
|
813
|
+
optionsCreation3.json = { services: [] };
|
|
814
|
+
|
|
815
|
+
optionsCreation1.json.services[0] = _.clone(optionsCreation.json.services[0]);
|
|
816
|
+
optionsCreation3.json.services[0] = _.clone(optionsCreation.json.services[0]);
|
|
817
|
+
|
|
818
|
+
optionsCreation1.json.services[0].apikey = 'qwertyuiop';
|
|
819
|
+
optionsCreation3.json.services[0].apikey = 'lkjhgfds';
|
|
820
|
+
|
|
821
|
+
async.series(
|
|
822
|
+
[
|
|
823
|
+
async.apply(request, optionsCreation1),
|
|
824
|
+
async.apply(request, optionsCreation2),
|
|
825
|
+
async.apply(request, optionsCreation3)
|
|
826
|
+
],
|
|
827
|
+
done
|
|
828
|
+
);
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
it('should return a 204 OK', function (done) {
|
|
832
|
+
request(optionsUpdateGroup, function (error, response, body) {
|
|
833
|
+
should.not.exist(error);
|
|
834
|
+
response.statusCode.should.equal(204);
|
|
835
|
+
done();
|
|
836
|
+
});
|
|
837
|
+
});
|
|
838
|
+
it('should update the appropriate values in the database', function (done) {
|
|
839
|
+
request(optionsUpdateGroup, function (error, response, body) {
|
|
840
|
+
request(optionsList, function (error, response, body) {
|
|
841
|
+
let found = false;
|
|
842
|
+
body.count.should.equal(3);
|
|
843
|
+
|
|
844
|
+
for (let i = 0; i < body.services.length; i++) {
|
|
845
|
+
if (
|
|
846
|
+
body.services[i].apikey === '801230BJKL23Y9090DSFL123HJK09H324HV8732' &&
|
|
847
|
+
body.services[i].resource === '/deviceTest'
|
|
848
|
+
) {
|
|
849
|
+
body.services[i].cbHost.should.equal('http://anotherUnexistentHost:1026');
|
|
850
|
+
body.services[i].static_attributes.length.should.equal(1);
|
|
851
|
+
found = true;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
found.should.equal(true);
|
|
856
|
+
done();
|
|
857
|
+
});
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
it('should call the configuration creation handler', function (done) {
|
|
861
|
+
let handlerCalled = false;
|
|
862
|
+
|
|
863
|
+
iotAgentLib.setConfigurationHandler(function (newConfiguration, callback) {
|
|
864
|
+
should.exist(newConfiguration);
|
|
865
|
+
should.exist(callback);
|
|
866
|
+
newConfiguration.cbHost.should.equal('http://anotherUnexistentHost:1026');
|
|
867
|
+
newConfiguration.trust.should.equal('8970A9078A803H3BL98PINEQRW8342HBAMS');
|
|
868
|
+
newConfiguration.service.should.equal('Testservice');
|
|
869
|
+
newConfiguration.subservice.should.equal('/testingPath');
|
|
870
|
+
newConfiguration.resource.should.equal('/deviceTest');
|
|
871
|
+
newConfiguration.apikey.should.equal('801230BJKL23Y9090DSFL123HJK09H324HV8732');
|
|
872
|
+
handlerCalled = true;
|
|
873
|
+
callback();
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
request(optionsUpdateGroup, function (error, response, body) {
|
|
877
|
+
handlerCalled.should.equal(true);
|
|
878
|
+
done();
|
|
879
|
+
});
|
|
880
|
+
});
|
|
881
|
+
});
|
|
882
|
+
|
|
707
883
|
describe('When a device group update request arrives declaring a different service', function () {
|
|
708
884
|
beforeEach(function (done) {
|
|
709
885
|
optionsUpdate.headers['fiware-service'] = 'UnexistentService';
|
|
@@ -996,4 +1172,87 @@ describe('NGSI-v2 - Device Group Configuration API', function () {
|
|
|
996
1172
|
});
|
|
997
1173
|
});
|
|
998
1174
|
});
|
|
1175
|
+
|
|
1176
|
+
describe('When a new device group creation request arrives with the NEW API endpoint ', function () {
|
|
1177
|
+
it('should return a 200 OK', function (done) {
|
|
1178
|
+
request(newOptionsCreation, function (error, response, body) {
|
|
1179
|
+
should.not.exist(error);
|
|
1180
|
+
response.statusCode.should.equal(201);
|
|
1181
|
+
done();
|
|
1182
|
+
});
|
|
1183
|
+
});
|
|
1184
|
+
it('should be recovered using the OLD API endpoint', function (done) {
|
|
1185
|
+
request(newOptionsCreation, function (error, response, body) {
|
|
1186
|
+
request(optionsList, function (error, response, body) {
|
|
1187
|
+
body.count.should.equal(1);
|
|
1188
|
+
body.services[0].apikey.should.equal('801230BJKL23Y9090DSFL123HJK09H324HV8732');
|
|
1189
|
+
body.services[0].transport.should.equal('HTTP');
|
|
1190
|
+
body.services[0].endpoint.should.equal('http://myendpoint.com');
|
|
1191
|
+
|
|
1192
|
+
body.count.should.equal(1);
|
|
1193
|
+
should.exist(body.services[0].attributes);
|
|
1194
|
+
body.services[0].attributes.length.should.equal(1);
|
|
1195
|
+
body.services[0].attributes[0].name.should.equal('status');
|
|
1196
|
+
|
|
1197
|
+
should.exist(body.services[0].lazy);
|
|
1198
|
+
body.services[0].lazy.length.should.equal(1);
|
|
1199
|
+
body.services[0].lazy[0].name.should.equal('luminescence');
|
|
1200
|
+
|
|
1201
|
+
should.exist(body.services[0].commands);
|
|
1202
|
+
body.services[0].commands.length.should.equal(1);
|
|
1203
|
+
body.services[0].commands[0].name.should.equal('wheel1');
|
|
1204
|
+
|
|
1205
|
+
should.exist(body.services[0].static_attributes);
|
|
1206
|
+
body.services[0].static_attributes.length.should.equal(1);
|
|
1207
|
+
body.services[0].static_attributes[0].name.should.equal('bootstrapServer');
|
|
1208
|
+
|
|
1209
|
+
body.count.should.equal(1);
|
|
1210
|
+
body.services[0].service.should.equal('testservice');
|
|
1211
|
+
body.services[0].subservice.should.equal('/testingPath');
|
|
1212
|
+
done();
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1215
|
+
});
|
|
1216
|
+
});
|
|
1217
|
+
describe('When a new device group creation request arrives with the NEW OLD endpoint ', function () {
|
|
1218
|
+
it('should return a 200 OK', function (done) {
|
|
1219
|
+
request(optionsCreation, function (error, response, body) {
|
|
1220
|
+
should.not.exist(error);
|
|
1221
|
+
response.statusCode.should.equal(201);
|
|
1222
|
+
done();
|
|
1223
|
+
});
|
|
1224
|
+
});
|
|
1225
|
+
it('should be recovered using the NEW API endpoint', function (done) {
|
|
1226
|
+
request(optionsCreation, function (error, response, body) {
|
|
1227
|
+
request(newOptionsList, function (error, response, body) {
|
|
1228
|
+
body.count.should.equal(1);
|
|
1229
|
+
body[configGroupTerm][0].apikey.should.equal('801230BJKL23Y9090DSFL123HJK09H324HV8732');
|
|
1230
|
+
body[configGroupTerm][0].transport.should.equal('HTTP');
|
|
1231
|
+
body[configGroupTerm][0].endpoint.should.equal('http://myendpoint.com');
|
|
1232
|
+
|
|
1233
|
+
body.count.should.equal(1);
|
|
1234
|
+
should.exist(body[configGroupTerm][0].attributes);
|
|
1235
|
+
body[configGroupTerm][0].attributes.length.should.equal(1);
|
|
1236
|
+
body[configGroupTerm][0].attributes[0].name.should.equal('status');
|
|
1237
|
+
|
|
1238
|
+
should.exist(body[configGroupTerm][0].lazy);
|
|
1239
|
+
body[configGroupTerm][0].lazy.length.should.equal(1);
|
|
1240
|
+
body[configGroupTerm][0].lazy[0].name.should.equal('luminescence');
|
|
1241
|
+
|
|
1242
|
+
should.exist(body[configGroupTerm][0].commands);
|
|
1243
|
+
body[configGroupTerm][0].commands.length.should.equal(1);
|
|
1244
|
+
body[configGroupTerm][0].commands[0].name.should.equal('wheel1');
|
|
1245
|
+
|
|
1246
|
+
should.exist(body[configGroupTerm][0].static_attributes);
|
|
1247
|
+
body[configGroupTerm][0].static_attributes.length.should.equal(1);
|
|
1248
|
+
body[configGroupTerm][0].static_attributes[0].name.should.equal('bootstrapServer');
|
|
1249
|
+
|
|
1250
|
+
body.count.should.equal(1);
|
|
1251
|
+
body[configGroupTerm][0].service.should.equal('testservice');
|
|
1252
|
+
body[configGroupTerm][0].subservice.should.equal('/testingPath');
|
|
1253
|
+
done();
|
|
1254
|
+
});
|
|
1255
|
+
});
|
|
1256
|
+
});
|
|
1257
|
+
});
|
|
999
1258
|
});
|