iotagent-node-lib 2.21.0 → 2.24.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/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
- package/.nyc_output/processinfo/{76bc24ff-5fac-4b5a-997d-de2799342eb0.json → 33364de2-1199-4ec2-b33c-cae063ef8cc4.json} +1 -1
- package/.nyc_output/processinfo/index.json +1 -1
- package/CHANGES_NEXT_RELEASE +0 -1
- package/doc/Contribution.md +3 -3
- package/doc/advanced-topics.md +73 -9
- package/doc/api.md +7 -5
- package/doc/architecture.md +52 -5
- package/doc/expressionLanguage.md +18 -3
- package/doc/operations.md +8 -5
- package/doc/usermanual.md +18 -16
- package/docker/Mosquitto/Dockerfile +1 -1
- package/lib/errors.js +9 -1
- package/lib/model/Group.js +2 -1
- package/lib/model/dbConn.js +4 -0
- package/lib/plugins/bidirectionalData.js +104 -6
- package/lib/plugins/expressionPlugin.js +18 -7
- package/lib/plugins/multiEntity.js +42 -29
- package/lib/plugins/pluginUtils.js +17 -0
- package/lib/request-shim.js +2 -1
- package/lib/services/commands/commandService.js +29 -2
- package/lib/services/common/iotManagerService.js +2 -1
- package/lib/services/devices/deviceService.js +35 -9
- package/lib/services/groups/groupRegistryMongoDB.js +13 -12
- package/lib/services/ngsi/entities-NGSI-LD.js +7 -0
- package/lib/services/ngsi/entities-NGSI-v2.js +70 -11
- package/lib/services/ngsi/ngsiService.js +1 -1
- package/lib/services/northBound/contextServer-NGSI-LD.js +110 -15
- package/lib/services/northBound/contextServer-NGSI-v2.js +8 -3
- package/lib/services/northBound/contextServerUtils.js +9 -9
- package/lib/services/northBound/deviceProvisioningServer.js +2 -1
- package/lib/templates/createDevice.json +1 -2
- package/lib/templates/createDeviceLax.json +2 -3
- package/lib/templates/updateDevice.json +1 -2
- package/package.json +24 -24
- package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +14 -0
- package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +51 -0
- package/test/unit/mongodb/mongoDBUtils.js +2 -2
- package/test/unit/mongodb/mongodb-group-registry-test.js +25 -1
- package/test/unit/mongodb/mongodb-registry-test.js +51 -3
- package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +2 -1
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json +15 -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/lazyAndCommands/command-test.js +995 -27
- package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +112 -0
- 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 +1 -1
- package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +8 -0
- package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +6 -0
- package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +12 -1
- package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +27 -0
- package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
- package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +10 -8
- package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
- package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +151 -0
- package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
- package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +63 -0
- package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +60 -0
- package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +2 -1
- package/.nyc_output/76bc24ff-5fac-4b5a-997d-de2799342eb0.json +0 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 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, see http://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: Daniel Calvo - ATOS Research & Innovation
|
|
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
|
+
let contextBrokerMock;
|
|
35
|
+
const iotAgentConfig = {
|
|
36
|
+
autocast: true,
|
|
37
|
+
contextBroker: {
|
|
38
|
+
host: '192.168.1.1',
|
|
39
|
+
port: '1026',
|
|
40
|
+
ngsiVersion: 'ld',
|
|
41
|
+
jsonLdContext: 'http://context.json-ld'
|
|
42
|
+
},
|
|
43
|
+
server: {
|
|
44
|
+
port: 4041
|
|
45
|
+
},
|
|
46
|
+
types: {
|
|
47
|
+
Light: {
|
|
48
|
+
commands: [],
|
|
49
|
+
type: 'Light',
|
|
50
|
+
active: [
|
|
51
|
+
{
|
|
52
|
+
name: 'name',
|
|
53
|
+
type: 'LanguageProperty'
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
service: 'smartgondor',
|
|
59
|
+
subservice: 'gardens',
|
|
60
|
+
providerUrl: 'http://smartgondor.com'
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
describe('NGSI-LD - LanguageProperty test', function () {
|
|
64
|
+
beforeEach(function () {
|
|
65
|
+
logger.setLevel('FATAL');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
afterEach(function (done) {
|
|
69
|
+
iotAgentLib.deactivate(done);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe(
|
|
73
|
+
'When the IoT Agent receives new exonym from a device name with LanguageProperty type and a JSON object',
|
|
74
|
+
function () {
|
|
75
|
+
const values = [
|
|
76
|
+
{
|
|
77
|
+
name: 'name',
|
|
78
|
+
type: 'LanguageProperty',
|
|
79
|
+
value: {
|
|
80
|
+
el: "Κωνσταντινούπολις",
|
|
81
|
+
en: "Constantinople",
|
|
82
|
+
tr: "İstanbul"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
beforeEach(function (done) {
|
|
88
|
+
nock.cleanAll();
|
|
89
|
+
|
|
90
|
+
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
91
|
+
.matchHeader('fiware-service', 'smartgondor')
|
|
92
|
+
.post(
|
|
93
|
+
'/ngsi-ld/v1/entityOperations/upsert/?options=update',
|
|
94
|
+
utils.readExampleFile(
|
|
95
|
+
'./test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json'
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
.reply(204);
|
|
99
|
+
|
|
100
|
+
iotAgentLib.activate(iotAgentConfig, done);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should change the value of the corresponding attribute in the context broker', function (done) {
|
|
104
|
+
iotAgentLib.update('light1', 'Light', '', values, function (error) {
|
|
105
|
+
should.not.exist(error);
|
|
106
|
+
contextBrokerMock.done();
|
|
107
|
+
done();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 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, see http://www.gnu.org/licenses/.
|
|
19
|
+
*
|
|
20
|
+
* For those usages not covered by the GNU Affero General Public License
|
|
21
|
+
* please contact with::daniel.moranjimenez@telefonica.com
|
|
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
|
+
|
|
33
|
+
let contextBrokerMock;
|
|
34
|
+
const iotAgentConfig = {
|
|
35
|
+
contextBroker: {
|
|
36
|
+
host: '192.168.1.1',
|
|
37
|
+
port: '1026',
|
|
38
|
+
ngsiVersion: 'ld',
|
|
39
|
+
jsonLdContext: 'http://context.json-ld'
|
|
40
|
+
},
|
|
41
|
+
server: {
|
|
42
|
+
port: 4041
|
|
43
|
+
},
|
|
44
|
+
types: {},
|
|
45
|
+
service: 'smartgondor',
|
|
46
|
+
subservice: 'gardens',
|
|
47
|
+
providerUrl: 'http://smartgondor.com'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
describe('NGSI-LD - Unsupported Endpoints', function () {
|
|
51
|
+
beforeEach(function (done) {
|
|
52
|
+
iotAgentLib.activate(iotAgentConfig, function () {
|
|
53
|
+
iotAgentLib.clearAll(function () {
|
|
54
|
+
done();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(function (done) {
|
|
60
|
+
iotAgentLib.clearAll(function () {
|
|
61
|
+
iotAgentLib.deactivate(done);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('When accessing an Unsupported Endpoint', function () {
|
|
66
|
+
it('GET /entities should return a valid NSGI-LD error message', function (done) {
|
|
67
|
+
const options = {
|
|
68
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities',
|
|
69
|
+
method: 'GET'
|
|
70
|
+
};
|
|
71
|
+
request(options, function (error, response, body) {
|
|
72
|
+
response.statusCode.should.equal(501);
|
|
73
|
+
done();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it('POST /entities should return a valid NSGI-LD error message', function (done) {
|
|
77
|
+
const options = {
|
|
78
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities',
|
|
79
|
+
method: 'POST',
|
|
80
|
+
json: {}
|
|
81
|
+
};
|
|
82
|
+
request(options, function (error, response, body) {
|
|
83
|
+
response.statusCode.should.equal(501);
|
|
84
|
+
done();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
it('DELETE /entities/<entity-id> should return a valid NSGI-LD error message', function (done) {
|
|
88
|
+
const options = {
|
|
89
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities/urn:ngsi-ld:entity',
|
|
90
|
+
method: 'DELETE'
|
|
91
|
+
};
|
|
92
|
+
request(options, function (error, response, body) {
|
|
93
|
+
response.statusCode.should.equal(501);
|
|
94
|
+
done();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
it('DELETE /entities/<entity-id>/attrs/<attr-name> should return a valid NSGI-LD error message', function (done) {
|
|
98
|
+
const options = {
|
|
99
|
+
url:
|
|
100
|
+
'http://localhost:' +
|
|
101
|
+
iotAgentConfig.server.port +
|
|
102
|
+
'/ngsi-ld/v1/entities/urn:ngsi-ld:entity/attrs/att',
|
|
103
|
+
method: 'DELETE'
|
|
104
|
+
};
|
|
105
|
+
request(options, function (error, response, body) {
|
|
106
|
+
response.statusCode.should.equal(501);
|
|
107
|
+
done();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -264,6 +264,227 @@ describe('NGSI-LD - Bidirectional data plugin', function () {
|
|
|
264
264
|
});
|
|
265
265
|
});
|
|
266
266
|
|
|
267
|
+
describe('When a notification with metadata arrives for a bidirectional attribute', function () {
|
|
268
|
+
const notificationOptions = {
|
|
269
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/notify',
|
|
270
|
+
method: 'POST',
|
|
271
|
+
json: utils.readExampleFile(
|
|
272
|
+
'./test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json'
|
|
273
|
+
),
|
|
274
|
+
headers: {
|
|
275
|
+
'fiware-service': 'smartgondor',
|
|
276
|
+
'fiware-servicepath': '/gardens'
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
let executedHandler = false;
|
|
280
|
+
|
|
281
|
+
beforeEach(function () {
|
|
282
|
+
contextBrokerMock
|
|
283
|
+
.matchHeader('fiware-service', 'smartgondor')
|
|
284
|
+
.post(
|
|
285
|
+
'/ngsi-ld/v1/subscriptions/',
|
|
286
|
+
utils.readExampleFile(
|
|
287
|
+
'./test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json'
|
|
288
|
+
)
|
|
289
|
+
)
|
|
290
|
+
.reply(201, null, { Location: '/ngsi-ld/v1/subscriptions/51c0ac9ed714fb3b37d7d5a8' });
|
|
291
|
+
|
|
292
|
+
contextBrokerMock
|
|
293
|
+
.matchHeader('fiware-service', 'smartgondor')
|
|
294
|
+
.post(
|
|
295
|
+
'/ngsi-ld/v1/entityOperations/upsert/',
|
|
296
|
+
utils.readExampleFile('./test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json')
|
|
297
|
+
)
|
|
298
|
+
.reply(204);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
afterEach(function () {
|
|
302
|
+
iotAgentLib.setNotificationHandler();
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('should execute the original handler', function (done) {
|
|
306
|
+
function mockedHandler(device, notification, callback) {
|
|
307
|
+
notification[0].name.should.equal('location');
|
|
308
|
+
notification[0].value.should.equal('12.4, -9.6');
|
|
309
|
+
notification[0].metadata.qos.value.should.equal(1);
|
|
310
|
+
executedHandler = true;
|
|
311
|
+
callback();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
iotAgentLib.setNotificationHandler(mockedHandler);
|
|
315
|
+
|
|
316
|
+
request(options, function (error, response, body) {
|
|
317
|
+
request(notificationOptions, function (error, response, body) {
|
|
318
|
+
executedHandler.should.equal(true);
|
|
319
|
+
contextBrokerMock.done();
|
|
320
|
+
done();
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('should return a 200 OK', function (done) {
|
|
326
|
+
function mockedHandler(device, notification, callback) {
|
|
327
|
+
executedHandler = true;
|
|
328
|
+
callback();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
iotAgentLib.setNotificationHandler(mockedHandler);
|
|
332
|
+
|
|
333
|
+
request(options, function (error, response, body) {
|
|
334
|
+
request(notificationOptions, function (error, response, body) {
|
|
335
|
+
response.statusCode.should.equal(200);
|
|
336
|
+
contextBrokerMock.done();
|
|
337
|
+
done();
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('should return the transformed values', function (done) {
|
|
343
|
+
let transformedHandler = false;
|
|
344
|
+
|
|
345
|
+
function mockedHandler(device, values, callback) {
|
|
346
|
+
let latitudeFound = false;
|
|
347
|
+
let longitudeFound = false;
|
|
348
|
+
|
|
349
|
+
for (let i = 0; i < values.length; i++) {
|
|
350
|
+
if (values[i].name === 'latitude' && values[i].type === 'string' && values[i].value === '-9.6') {
|
|
351
|
+
latitudeFound = true;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (values[i].name === 'longitude' && values[i].type === 'string' && values[i].value === '12.4') {
|
|
355
|
+
longitudeFound = true;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
transformedHandler = values.length >= 2 && longitudeFound && latitudeFound;
|
|
360
|
+
callback();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
iotAgentLib.setNotificationHandler(mockedHandler);
|
|
364
|
+
|
|
365
|
+
request(options, function (error, response, body) {
|
|
366
|
+
request(notificationOptions, function (error, response, body) {
|
|
367
|
+
contextBrokerMock.done();
|
|
368
|
+
transformedHandler.should.equal(true);
|
|
369
|
+
done();
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
describe('When a sequential notification with datasetId arrives for a bidirectional attribute', function () {
|
|
376
|
+
const notificationOptions = {
|
|
377
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/notify',
|
|
378
|
+
method: 'POST',
|
|
379
|
+
json: utils.readExampleFile(
|
|
380
|
+
'./test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json'
|
|
381
|
+
),
|
|
382
|
+
headers: {
|
|
383
|
+
'fiware-service': 'smartgondor',
|
|
384
|
+
'fiware-servicepath': '/gardens'
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
let executedHandler = false;
|
|
388
|
+
|
|
389
|
+
beforeEach(function () {
|
|
390
|
+
contextBrokerMock
|
|
391
|
+
.matchHeader('fiware-service', 'smartgondor')
|
|
392
|
+
.post(
|
|
393
|
+
'/ngsi-ld/v1/subscriptions/',
|
|
394
|
+
utils.readExampleFile(
|
|
395
|
+
'./test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json'
|
|
396
|
+
)
|
|
397
|
+
)
|
|
398
|
+
.reply(201, null, { Location: '/ngsi-ld/v1/subscriptions/51c0ac9ed714fb3b37d7d5a8' });
|
|
399
|
+
|
|
400
|
+
contextBrokerMock
|
|
401
|
+
.matchHeader('fiware-service', 'smartgondor')
|
|
402
|
+
.post(
|
|
403
|
+
'/ngsi-ld/v1/entityOperations/upsert/',
|
|
404
|
+
utils.readExampleFile('./test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json')
|
|
405
|
+
)
|
|
406
|
+
.reply(204);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
afterEach(function () {
|
|
410
|
+
iotAgentLib.setNotificationHandler();
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it('should execute the original handler', function (done) {
|
|
414
|
+
function mockedHandler(device, notification, callback) {
|
|
415
|
+
notification[0].name.should.equal('location');
|
|
416
|
+
notification[0].value.should.equal('12.4, -9.6');
|
|
417
|
+
notification[0].datasetId.should.equal('urn:ngsi-ld:Property:do-this');
|
|
418
|
+
|
|
419
|
+
notification[1].name.should.equal('location');
|
|
420
|
+
notification[1].value.should.equal('6, 10');
|
|
421
|
+
notification[1].datasetId.should.equal('urn:ngsi-ld:Property:then-do-this');
|
|
422
|
+
|
|
423
|
+
executedHandler = true;
|
|
424
|
+
callback();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
iotAgentLib.setNotificationHandler(mockedHandler);
|
|
428
|
+
|
|
429
|
+
request(options, function (error, response, body) {
|
|
430
|
+
request(notificationOptions, function (error, response, body) {
|
|
431
|
+
executedHandler.should.equal(true);
|
|
432
|
+
contextBrokerMock.done();
|
|
433
|
+
done();
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it('should return a 200 OK', function (done) {
|
|
439
|
+
function mockedHandler(device, notification, callback) {
|
|
440
|
+
executedHandler = true;
|
|
441
|
+
callback();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
iotAgentLib.setNotificationHandler(mockedHandler);
|
|
445
|
+
|
|
446
|
+
request(options, function (error, response, body) {
|
|
447
|
+
request(notificationOptions, function (error, response, body) {
|
|
448
|
+
response.statusCode.should.equal(200);
|
|
449
|
+
contextBrokerMock.done();
|
|
450
|
+
done();
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it('should return the transformed values', function (done) {
|
|
456
|
+
let transformedHandler = false;
|
|
457
|
+
|
|
458
|
+
function mockedHandler(device, values, callback) {
|
|
459
|
+
let latitudeFound = false;
|
|
460
|
+
let longitudeFound = false;
|
|
461
|
+
|
|
462
|
+
for (let i = 0; i < values.length; i++) {
|
|
463
|
+
if (values[i].name === 'latitude' && values[i].type === 'string' && values[i].value === '-9.6') {
|
|
464
|
+
latitudeFound = true;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (values[i].name === 'longitude' && values[i].type === 'string' && values[i].value === '12.4') {
|
|
468
|
+
longitudeFound = true;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
transformedHandler = values.length >= 2 && longitudeFound && latitudeFound;
|
|
473
|
+
callback();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
iotAgentLib.setNotificationHandler(mockedHandler);
|
|
477
|
+
|
|
478
|
+
request(options, function (error, response, body) {
|
|
479
|
+
request(notificationOptions, function (error, response, body) {
|
|
480
|
+
contextBrokerMock.done();
|
|
481
|
+
transformedHandler.should.equal(true);
|
|
482
|
+
done();
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
|
|
267
488
|
describe('When a new Group provisioning request arrives with bidirectional attributes', function () {
|
|
268
489
|
const provisionGroup = {
|
|
269
490
|
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/services',
|
|
@@ -171,7 +171,7 @@ describe('Mixed Mode: ngsiVersion test', function () {
|
|
|
171
171
|
beforeEach(function (done) {
|
|
172
172
|
mongoUtils.cleanDbs(function () {
|
|
173
173
|
iotAgentLib.activate(iotAgentConfig, function () {
|
|
174
|
-
mongo.connect('mongodb://localhost:27017/iotagent',
|
|
174
|
+
mongo.connect('mongodb://localhost:27017/iotagent', function (err, db) {
|
|
175
175
|
iotAgentDb = db;
|
|
176
176
|
done();
|
|
177
177
|
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"actionType": "update",
|
|
3
|
+
"entities": [
|
|
4
|
+
{
|
|
5
|
+
"id": "ws9b",
|
|
6
|
+
"type": "WeatherStation",
|
|
7
|
+
"pressure": {
|
|
8
|
+
"type": "Hgmm",
|
|
9
|
+
"value": "52"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"humidity": {
|
|
14
|
+
"type": "Percentage",
|
|
15
|
+
"value": "12",
|
|
16
|
+
"metadata": {
|
|
17
|
+
"unitCode": {
|
|
18
|
+
"type": "Text",
|
|
19
|
+
"value": "Hgmm"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"type": "Higrometer",
|
|
24
|
+
"id": "ws9b"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"subscriptionId": "51c0ac9ed714fb3b37d7d5a8",
|
|
3
|
+
"data": [
|
|
4
|
+
{
|
|
5
|
+
"location": {
|
|
6
|
+
"type": "geo:point",
|
|
7
|
+
"value": "12.4, -9.6",
|
|
8
|
+
"metadata": {
|
|
9
|
+
"qos": {
|
|
10
|
+
"type": "Number",
|
|
11
|
+
"value": 1
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"type": "TheLightType",
|
|
16
|
+
"id": "TheFirstLight"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -271,7 +271,7 @@ const iotAgentConfig = {
|
|
|
271
271
|
expression: "{coordinates: [lon,lat], type: 'Point'}"
|
|
272
272
|
}
|
|
273
273
|
],
|
|
274
|
-
explicitAttrs: '[ "location" ]'
|
|
274
|
+
explicitAttrs: ' location&&price ? [ "location", "price" ] : location ? [ "location" ] : []'
|
|
275
275
|
},
|
|
276
276
|
GPS4: {
|
|
277
277
|
commands: [],
|
|
@@ -314,12 +314,14 @@ const iotAgentConfig = {
|
|
|
314
314
|
type: 'number'
|
|
315
315
|
},
|
|
316
316
|
{
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
317
|
+
object_id: 'theLocation',
|
|
318
|
+
name: 'mylocation',
|
|
319
|
+
type: 'geo:json'
|
|
320
320
|
}
|
|
321
321
|
],
|
|
322
|
-
explicitAttrs: "[
|
|
322
|
+
explicitAttrs: "theLocation ? ['mylocation'] : []"
|
|
323
|
+
// #1267 this is not working:
|
|
324
|
+
//explicitAttrs: "theLocation ? [{object_id: 'theLocation'}] : []"
|
|
323
325
|
},
|
|
324
326
|
GPS6: {
|
|
325
327
|
commands: [],
|
|
@@ -1184,9 +1186,9 @@ describe('Java expression language (JEXL) based transformations plugin', functio
|
|
|
1184
1186
|
value: 13
|
|
1185
1187
|
},
|
|
1186
1188
|
{
|
|
1187
|
-
name: '
|
|
1188
|
-
type: '
|
|
1189
|
-
value: '
|
|
1189
|
+
name: 'theLocation',
|
|
1190
|
+
type: 'geo:json',
|
|
1191
|
+
value: { coordinates: [13, 52], type: 'Point' }
|
|
1190
1192
|
},
|
|
1191
1193
|
{
|
|
1192
1194
|
name: 'TimeInstant',
|