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
|
@@ -153,6 +153,36 @@ const groupCreation = {
|
|
|
153
153
|
'fiware-servicepath': '/testingPath'
|
|
154
154
|
}
|
|
155
155
|
};
|
|
156
|
+
|
|
157
|
+
const configGroupCreation = {
|
|
158
|
+
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/groups',
|
|
159
|
+
method: 'POST',
|
|
160
|
+
json: {
|
|
161
|
+
groups: [
|
|
162
|
+
{
|
|
163
|
+
resource: '',
|
|
164
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
165
|
+
entity_type: 'TheLightType',
|
|
166
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
167
|
+
cbHost: 'http://192.168.1.1:1026',
|
|
168
|
+
commands: [],
|
|
169
|
+
lazy: [],
|
|
170
|
+
attributes: [
|
|
171
|
+
{
|
|
172
|
+
name: 'status',
|
|
173
|
+
type: 'Boolean'
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
static_attributes: []
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
headers: {
|
|
181
|
+
'fiware-service': 'testservice',
|
|
182
|
+
'fiware-servicepath': '/testingPath'
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
156
186
|
const deviceCreation = {
|
|
157
187
|
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
|
|
158
188
|
method: 'POST',
|
|
@@ -180,6 +210,7 @@ describe('NGSI-v2 - Device Service: utils', function () {
|
|
|
180
210
|
async.series([iotAgentLib.clearAll, iotAgentLib.deactivate], done);
|
|
181
211
|
});
|
|
182
212
|
|
|
213
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
183
214
|
describe('When an existing device tries to be retrieved with retrieveOrCreate()', function () {
|
|
184
215
|
beforeEach(function (done) {
|
|
185
216
|
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
@@ -213,6 +244,41 @@ describe('NGSI-v2 - Device Service: utils', function () {
|
|
|
213
244
|
});
|
|
214
245
|
});
|
|
215
246
|
|
|
247
|
+
describe('When an existing device tries to be retrieved with retrieveOrCreate()', function () {
|
|
248
|
+
beforeEach(function (done) {
|
|
249
|
+
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
250
|
+
.matchHeader('fiware-service', 'testservice')
|
|
251
|
+
.matchHeader('fiware-servicepath', '/testingPath')
|
|
252
|
+
.post('/v2/registrations')
|
|
253
|
+
.reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
|
|
254
|
+
|
|
255
|
+
contextBrokerMock
|
|
256
|
+
.matchHeader('fiware-service', 'testservice')
|
|
257
|
+
.matchHeader('fiware-servicepath', '/testingPath')
|
|
258
|
+
.post('/v2/entities?options=upsert')
|
|
259
|
+
.reply(204);
|
|
260
|
+
|
|
261
|
+
async.series(
|
|
262
|
+
[request.bind(request, configGroupCreation), request.bind(request, deviceCreation)],
|
|
263
|
+
function (error, results) {
|
|
264
|
+
done();
|
|
265
|
+
}
|
|
266
|
+
);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should return the existing device', function (done) {
|
|
270
|
+
iotAgentLib.retrieveDevice('Light1', '801230BJKL23Y9090DSFL123HJK09H324HV8732', function (error, device) {
|
|
271
|
+
should.not.exist(error);
|
|
272
|
+
should.exist(device);
|
|
273
|
+
|
|
274
|
+
device.id.should.equal('Light1');
|
|
275
|
+
done();
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// #FIXME1649: this test will be removed if at the end /iot/services API (now Deprecated) is removed
|
|
281
|
+
|
|
216
282
|
describe('When an unexisting device tries to be retrieved for an existing APIKey', function () {
|
|
217
283
|
beforeEach(function (done) {
|
|
218
284
|
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
@@ -249,6 +315,42 @@ describe('NGSI-v2 - Device Service: utils', function () {
|
|
|
249
315
|
});
|
|
250
316
|
});
|
|
251
317
|
|
|
318
|
+
describe('When an unexisting device tries to be retrieved for an existing APIKey', function () {
|
|
319
|
+
beforeEach(function (done) {
|
|
320
|
+
contextBrokerMock = nock('http://192.168.1.1:1026')
|
|
321
|
+
.matchHeader('fiware-service', 'testservice')
|
|
322
|
+
.matchHeader('fiware-servicepath', '/testingPath')
|
|
323
|
+
.post('/v2/registrations')
|
|
324
|
+
.reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
|
|
325
|
+
|
|
326
|
+
contextBrokerMock
|
|
327
|
+
.matchHeader('fiware-service', 'testservice')
|
|
328
|
+
.matchHeader('fiware-servicepath', '/testingPath')
|
|
329
|
+
.post('/v2/entities?options=upsert')
|
|
330
|
+
.reply(204);
|
|
331
|
+
|
|
332
|
+
async.series([request.bind(request, configGroupCreation)], function (error, results) {
|
|
333
|
+
done();
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it('should register the device and return it', function (done) {
|
|
338
|
+
iotAgentLib.retrieveDevice(
|
|
339
|
+
'UNEXISTENT_DEV',
|
|
340
|
+
'801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
341
|
+
function (error, device) {
|
|
342
|
+
should.not.exist(error);
|
|
343
|
+
should.exist(device);
|
|
344
|
+
|
|
345
|
+
device.id.should.equal('UNEXISTENT_DEV');
|
|
346
|
+
should.exist(device.protocol);
|
|
347
|
+
device.protocol.should.equal('MQTT_UL');
|
|
348
|
+
done();
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
|
|
252
354
|
describe('When an unexisting device tries to be retrieved for an unexisting APIKey', function () {
|
|
253
355
|
it('should raise an error', function (done) {
|
|
254
356
|
iotAgentLib.retrieveDevice(
|
|
@@ -35,9 +35,6 @@ const iotAgentConfig = {
|
|
|
35
35
|
host: 'localhost',
|
|
36
36
|
baseRoot: '/'
|
|
37
37
|
},
|
|
38
|
-
stats: {
|
|
39
|
-
interval: 100
|
|
40
|
-
},
|
|
41
38
|
types: {},
|
|
42
39
|
service: 'smartgondor',
|
|
43
40
|
subservice: 'gardens',
|
|
@@ -51,9 +48,7 @@ describe('Statistics service', function () {
|
|
|
51
48
|
oldConfig = commonConfig.getConfig();
|
|
52
49
|
commonConfig.setConfig(iotAgentConfig);
|
|
53
50
|
|
|
54
|
-
statsService.globalLoad({},
|
|
55
|
-
statsService.clearTimers(done);
|
|
56
|
-
});
|
|
51
|
+
statsService.globalLoad({}, done);
|
|
57
52
|
});
|
|
58
53
|
|
|
59
54
|
afterEach(function (done) {
|
|
@@ -74,16 +69,6 @@ describe('Statistics service', function () {
|
|
|
74
69
|
);
|
|
75
70
|
});
|
|
76
71
|
|
|
77
|
-
it('should appear the modified value in the getCurrent() statistics', function (done) {
|
|
78
|
-
statsService.add(statName, statValue, function () {
|
|
79
|
-
statsService.getCurrent(statName, function (error, value) {
|
|
80
|
-
should.not.exist(error);
|
|
81
|
-
should.exist(value);
|
|
82
|
-
value.should.equal(statValue);
|
|
83
|
-
done();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
72
|
it('should add the value to the global values', function (done) {
|
|
88
73
|
statsService.add(statName, statValue, function () {
|
|
89
74
|
statsService.getGlobal(statName, function (error, value) {
|
|
@@ -119,62 +104,4 @@ describe('Statistics service', function () {
|
|
|
119
104
|
});
|
|
120
105
|
});
|
|
121
106
|
});
|
|
122
|
-
describe('When the current statistics are reset', function () {
|
|
123
|
-
beforeEach(function (done) {
|
|
124
|
-
statsService.add('statA', 42, function () {
|
|
125
|
-
statsService.add('statB', 52, done);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should return a value of zero for any of the individual statistics', function (done) {
|
|
130
|
-
statsService.resetCurrent(function (error) {
|
|
131
|
-
should.not.exist(error);
|
|
132
|
-
|
|
133
|
-
statsService.getAllCurrent(function (error, data) {
|
|
134
|
-
should.exist(data);
|
|
135
|
-
should.exist(data.statA);
|
|
136
|
-
should.exist(data.statB);
|
|
137
|
-
data.statA.should.equal(0);
|
|
138
|
-
data.statB.should.equal(0);
|
|
139
|
-
done();
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
describe('When a new periodic stats action is set', function () {
|
|
145
|
-
let valueCurrent = 0;
|
|
146
|
-
let valueGlobal = 0;
|
|
147
|
-
let times = 0;
|
|
148
|
-
|
|
149
|
-
beforeEach(function (done) {
|
|
150
|
-
statsService.globalLoad(
|
|
151
|
-
{
|
|
152
|
-
stat1: 10
|
|
153
|
-
},
|
|
154
|
-
function () {
|
|
155
|
-
statsService.add('stat1', 5, done);
|
|
156
|
-
}
|
|
157
|
-
);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
function mockedAction(current, global, callback) {
|
|
161
|
-
valueCurrent = current.stat1;
|
|
162
|
-
valueGlobal = global.stat1;
|
|
163
|
-
times++;
|
|
164
|
-
callback();
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
it('should be triggered with the periodicity stated in the config.stats.interval parameter', function (done) {
|
|
168
|
-
statsService.addTimerAction(mockedAction, function () {
|
|
169
|
-
setTimeout(function () {
|
|
170
|
-
statsService.clearTimers(function () {
|
|
171
|
-
valueCurrent.should.equal(5);
|
|
172
|
-
valueGlobal.should.equal(15);
|
|
173
|
-
times.should.equal(4);
|
|
174
|
-
done();
|
|
175
|
-
});
|
|
176
|
-
}, 480);
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
107
|
});
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 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 _ = require('underscore');
|
|
30
|
+
const utils = require('../../tools/utils');
|
|
31
|
+
const request = utils.request;
|
|
32
|
+
const async = require('async');
|
|
33
|
+
const should = require('should');
|
|
34
|
+
const iotAgentConfig = {
|
|
35
|
+
logLevel: 'FATAL',
|
|
36
|
+
contextBroker: {
|
|
37
|
+
host: '192.168.1.1',
|
|
38
|
+
port: '1026'
|
|
39
|
+
},
|
|
40
|
+
server: {
|
|
41
|
+
name: 'testAgent',
|
|
42
|
+
port: 4041,
|
|
43
|
+
host: 'localhost',
|
|
44
|
+
baseRoot: '/'
|
|
45
|
+
},
|
|
46
|
+
types: {},
|
|
47
|
+
deviceRegistry: {
|
|
48
|
+
type: 'mongodb'
|
|
49
|
+
},
|
|
50
|
+
mongodb: {
|
|
51
|
+
host: 'localhost',
|
|
52
|
+
port: '27017',
|
|
53
|
+
db: 'iotagent'
|
|
54
|
+
},
|
|
55
|
+
service: 'smartgondor',
|
|
56
|
+
subservice: 'gardens',
|
|
57
|
+
providerUrl: 'http://smartgondor.com',
|
|
58
|
+
deviceRegistrationDuration: 'P1M'
|
|
59
|
+
};
|
|
60
|
+
const mongo = require('mongodb').MongoClient;
|
|
61
|
+
const mongoUtils = require('./mongoDBUtils');
|
|
62
|
+
const optionsCreation = {
|
|
63
|
+
url: 'http://localhost:4041/iot/groups',
|
|
64
|
+
method: 'POST',
|
|
65
|
+
json: {
|
|
66
|
+
groups: [
|
|
67
|
+
{
|
|
68
|
+
resource: '/deviceTest',
|
|
69
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
70
|
+
entity_type: 'Light',
|
|
71
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
72
|
+
cbHost: 'http://unexistentHost:1026',
|
|
73
|
+
commands: [
|
|
74
|
+
{
|
|
75
|
+
name: 'wheel1',
|
|
76
|
+
type: 'Wheel'
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
lazy: [
|
|
80
|
+
{
|
|
81
|
+
name: 'luminescence',
|
|
82
|
+
type: 'Lumens'
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
attributes: [
|
|
86
|
+
{
|
|
87
|
+
name: 'status',
|
|
88
|
+
type: 'Boolean'
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
internal_attributes: [
|
|
92
|
+
{
|
|
93
|
+
customField: 'customValue'
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
headers: {
|
|
100
|
+
'fiware-service': 'testservice',
|
|
101
|
+
'fiware-servicepath': '/testingPath'
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const optionsDelete = {
|
|
105
|
+
url: 'http://localhost:4041/iot/groups',
|
|
106
|
+
method: 'DELETE',
|
|
107
|
+
json: {},
|
|
108
|
+
headers: {
|
|
109
|
+
'fiware-service': 'testservice',
|
|
110
|
+
'fiware-servicepath': '/testingPath'
|
|
111
|
+
},
|
|
112
|
+
qs: {
|
|
113
|
+
resource: '/deviceTest',
|
|
114
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const optionsList = {
|
|
118
|
+
url: 'http://localhost:4041/iot/groups',
|
|
119
|
+
method: 'GET',
|
|
120
|
+
json: {},
|
|
121
|
+
headers: {
|
|
122
|
+
'fiware-service': 'testservice',
|
|
123
|
+
'fiware-servicepath': '/*'
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const optionsUpdate = {
|
|
127
|
+
url: 'http://localhost:4041/iot/groups',
|
|
128
|
+
method: 'PUT',
|
|
129
|
+
json: {
|
|
130
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
|
|
131
|
+
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
|
|
132
|
+
cbHost: 'http://anotherUnexistentHost:1026',
|
|
133
|
+
commands: [
|
|
134
|
+
{
|
|
135
|
+
name: 'wheel1',
|
|
136
|
+
type: 'Wheel'
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
lazy: [
|
|
140
|
+
{
|
|
141
|
+
name: 'luminescence',
|
|
142
|
+
type: 'Lumens'
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
attributes: [
|
|
146
|
+
{
|
|
147
|
+
name: 'status',
|
|
148
|
+
type: 'Boolean'
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
static_attributes: [
|
|
152
|
+
{
|
|
153
|
+
name: 'bootstrapServer',
|
|
154
|
+
type: 'Address',
|
|
155
|
+
value: '127.0.0.1'
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
headers: {
|
|
160
|
+
'fiware-service': 'testservice',
|
|
161
|
+
'fiware-servicepath': '/testingPath'
|
|
162
|
+
},
|
|
163
|
+
qs: {
|
|
164
|
+
resource: '/deviceTest',
|
|
165
|
+
apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732'
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const optionsGet = {
|
|
169
|
+
url: 'http://localhost:4041/iot/groups',
|
|
170
|
+
method: 'GET',
|
|
171
|
+
json: {},
|
|
172
|
+
headers: {
|
|
173
|
+
'fiware-service': 'testservice',
|
|
174
|
+
'fiware-servicepath': '/testingPath'
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
let iotAgentDb;
|
|
178
|
+
|
|
179
|
+
describe('MongoDB Group Registry test', function () {
|
|
180
|
+
beforeEach(function (done) {
|
|
181
|
+
mongoUtils.cleanDbs(function () {
|
|
182
|
+
iotAgentLib.activate(iotAgentConfig, function () {
|
|
183
|
+
mongo.connect('mongodb://localhost:27017/iotagent', { useNewUrlParser: true }, function (err, db) {
|
|
184
|
+
iotAgentDb = db;
|
|
185
|
+
done();
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
afterEach(function (done) {
|
|
192
|
+
iotAgentLib.deactivate(function () {
|
|
193
|
+
iotAgentDb.close(function (error) {
|
|
194
|
+
mongoUtils.cleanDbs(done);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
describe('When a new device group creation request arrives', function () {
|
|
199
|
+
it('should store it in the DB', function (done) {
|
|
200
|
+
request(optionsCreation, function (error, response, body) {
|
|
201
|
+
iotAgentDb
|
|
202
|
+
.db()
|
|
203
|
+
.collection('groups')
|
|
204
|
+
.find({})
|
|
205
|
+
.toArray(function (err, docs) {
|
|
206
|
+
should.not.exist(err);
|
|
207
|
+
should.exist(docs);
|
|
208
|
+
should.exist(docs.length);
|
|
209
|
+
docs.length.should.equal(1);
|
|
210
|
+
should.exist(docs[0].type);
|
|
211
|
+
should.exist(docs[0].internalAttributes);
|
|
212
|
+
should.exist(docs[0].attributes);
|
|
213
|
+
should.exist(docs[0].apikey);
|
|
214
|
+
docs[0].type.should.equal('Light');
|
|
215
|
+
docs[0].apikey.should.equal('801230BJKL23Y9090DSFL123HJK09H324HV8732');
|
|
216
|
+
docs[0].internalAttributes.length.should.equal(1);
|
|
217
|
+
docs[0].internalAttributes[0].customField.should.equal('customValue');
|
|
218
|
+
docs[0].attributes.length.should.equal(1);
|
|
219
|
+
docs[0].attributes[0].name.should.equal('status');
|
|
220
|
+
done();
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
it('should store the service information from the headers into the DB', function (done) {
|
|
225
|
+
request(optionsCreation, function (error, response, body) {
|
|
226
|
+
iotAgentDb
|
|
227
|
+
.db()
|
|
228
|
+
.collection('groups')
|
|
229
|
+
.find({})
|
|
230
|
+
.toArray(function (err, docs) {
|
|
231
|
+
should.not.exist(err);
|
|
232
|
+
should.exist(docs[0].service);
|
|
233
|
+
should.exist(docs[0].subservice);
|
|
234
|
+
docs[0].service.should.equal('testservice');
|
|
235
|
+
docs[0].subservice.should.equal('/testingPath');
|
|
236
|
+
done();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('When a new device group creation request arrives with an existant (apikey, resource) pair', function () {
|
|
243
|
+
it('should return a DUPLICATE_GROUP error', function (done) {
|
|
244
|
+
request(optionsCreation, function (error, response, body) {
|
|
245
|
+
request(optionsCreation, function (error, response, body) {
|
|
246
|
+
response.statusCode.should.equal(409);
|
|
247
|
+
body.name.should.equal('DUPLICATE_GROUP');
|
|
248
|
+
done();
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
describe('When a device group removal request arrives', function () {
|
|
255
|
+
beforeEach(function (done) {
|
|
256
|
+
request(optionsCreation, done);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should remove it from the database', function (done) {
|
|
260
|
+
request(optionsDelete, function (error, response, body) {
|
|
261
|
+
iotAgentDb
|
|
262
|
+
.db()
|
|
263
|
+
.collection('groups')
|
|
264
|
+
.find({})
|
|
265
|
+
.toArray(function (err, docs) {
|
|
266
|
+
should.not.exist(err);
|
|
267
|
+
should.exist(docs);
|
|
268
|
+
should.exist(docs.length);
|
|
269
|
+
docs.length.should.equal(0);
|
|
270
|
+
done();
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('should return a 204 OK statusCode', function (done) {
|
|
276
|
+
request(optionsDelete, function (error, response, body) {
|
|
277
|
+
response.statusCode.should.equal(204);
|
|
278
|
+
done();
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe('When a device group update request arrives', function () {
|
|
284
|
+
beforeEach(function (done) {
|
|
285
|
+
request(optionsCreation, done);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('should update the values in the database', function (done) {
|
|
289
|
+
request(optionsUpdate, function (error, response, body) {
|
|
290
|
+
iotAgentDb
|
|
291
|
+
.db()
|
|
292
|
+
.collection('groups')
|
|
293
|
+
.find({})
|
|
294
|
+
.toArray(function (err, docs) {
|
|
295
|
+
should.not.exist(err);
|
|
296
|
+
should.exist(docs);
|
|
297
|
+
should.exist(docs[0].cbHost);
|
|
298
|
+
docs[0].cbHost.should.equal('http://anotherUnexistentHost:1026');
|
|
299
|
+
should.exist(docs[0].staticAttributes);
|
|
300
|
+
docs[0].staticAttributes.length.should.equal(1);
|
|
301
|
+
done();
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
describe('When a multiple device group creation arrives', function () {
|
|
308
|
+
const optionsMultipleCreation = _.clone(optionsCreation);
|
|
309
|
+
|
|
310
|
+
beforeEach(function (done) {
|
|
311
|
+
optionsMultipleCreation.json = utils.readExampleFile(
|
|
312
|
+
'./test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json'
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
done();
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('should create the values in the database', function (done) {
|
|
319
|
+
request(optionsMultipleCreation, function (error, response, body) {
|
|
320
|
+
iotAgentDb
|
|
321
|
+
.db()
|
|
322
|
+
.collection('groups')
|
|
323
|
+
.find({})
|
|
324
|
+
.toArray(function (err, docs) {
|
|
325
|
+
should.not.exist(err);
|
|
326
|
+
should.exist(docs);
|
|
327
|
+
docs.length.should.equal(2);
|
|
328
|
+
done();
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
describe('When a device group listing request arrives', function () {
|
|
335
|
+
beforeEach(function (done) {
|
|
336
|
+
const optionsCreation1 = _.clone(optionsCreation);
|
|
337
|
+
const optionsCreation2 = _.clone(optionsCreation);
|
|
338
|
+
const optionsCreation3 = _.clone(optionsCreation);
|
|
339
|
+
|
|
340
|
+
optionsCreation2.json = { groups: [] };
|
|
341
|
+
optionsCreation3.json = { groups: [] };
|
|
342
|
+
|
|
343
|
+
optionsCreation2.json.groups[0] = _.clone(optionsCreation.json.groups[0]);
|
|
344
|
+
optionsCreation3.json.groups[0] = _.clone(optionsCreation.json.groups[0]);
|
|
345
|
+
|
|
346
|
+
optionsCreation2.json.groups[0].apikey = 'qwertyuiop';
|
|
347
|
+
optionsCreation3.json.groups[0].apikey = 'lkjhgfds';
|
|
348
|
+
|
|
349
|
+
async.series(
|
|
350
|
+
[
|
|
351
|
+
async.apply(request, optionsCreation1),
|
|
352
|
+
async.apply(request, optionsCreation2),
|
|
353
|
+
async.apply(request, optionsCreation3)
|
|
354
|
+
],
|
|
355
|
+
done
|
|
356
|
+
);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it('should return all the configured device groups from the database', function (done) {
|
|
360
|
+
request(optionsList, function (error, response, body) {
|
|
361
|
+
body.count.should.equal(3);
|
|
362
|
+
done();
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
describe('When a device group listing arrives with a limit', function () {
|
|
368
|
+
const optionsConstrained = {
|
|
369
|
+
url: 'http://localhost:4041/iot/groups',
|
|
370
|
+
method: 'GET',
|
|
371
|
+
qs: {
|
|
372
|
+
limit: 3,
|
|
373
|
+
offset: 2
|
|
374
|
+
},
|
|
375
|
+
json: {},
|
|
376
|
+
headers: {
|
|
377
|
+
'fiware-service': 'testservice',
|
|
378
|
+
'fiware-servicepath': '/*'
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
beforeEach(function (done) {
|
|
383
|
+
const optionsCreationList = [];
|
|
384
|
+
const creationFns = [];
|
|
385
|
+
|
|
386
|
+
for (let i = 0; i < 10; i++) {
|
|
387
|
+
optionsCreationList[i] = _.clone(optionsCreation);
|
|
388
|
+
optionsCreationList[i].json = { groups: [] };
|
|
389
|
+
optionsCreationList[i].json.groups[0] = _.clone(optionsCreation.json.groups[0]);
|
|
390
|
+
optionsCreationList[i].json.groups[0].apikey = 'qwertyuiop' + i;
|
|
391
|
+
creationFns.push(async.apply(request, optionsCreationList[i]));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async.series(creationFns, done);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it('should return the appropriate count of groups', function (done) {
|
|
398
|
+
request(optionsConstrained, function (error, response, body) {
|
|
399
|
+
body.count.should.equal(10);
|
|
400
|
+
done();
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
describe('When a device info request arrives', function () {
|
|
406
|
+
beforeEach(function (done) {
|
|
407
|
+
async.series([async.apply(request, optionsCreation)], done);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it('should return all the configured device groups from the database', function (done) {
|
|
411
|
+
request(optionsGet, function (error, response, body) {
|
|
412
|
+
should.exist(body);
|
|
413
|
+
should.exist(body.count);
|
|
414
|
+
body.count.should.equal(1);
|
|
415
|
+
should.exist(body.groups);
|
|
416
|
+
should.exist(body.groups.length);
|
|
417
|
+
body.groups.length.should.equal(1);
|
|
418
|
+
body.groups[0].service.should.equal('testservice');
|
|
419
|
+
done();
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
describe('When a device info request arrives and multiple groups have been created', function () {
|
|
425
|
+
beforeEach(function (done) {
|
|
426
|
+
const optionsCreationList = [];
|
|
427
|
+
const creationFns = [];
|
|
428
|
+
|
|
429
|
+
for (let i = 0; i < 10; i++) {
|
|
430
|
+
optionsCreationList[i] = _.clone(optionsCreation);
|
|
431
|
+
optionsCreationList[i].json = { groups: [] };
|
|
432
|
+
optionsCreationList[i].json.groups[0] = _.clone(optionsCreation.json.groups[0]);
|
|
433
|
+
optionsCreationList[i].json.groups[0].apikey = 'qwertyuiop' + i;
|
|
434
|
+
creationFns.push(async.apply(request, optionsCreationList[i]));
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async.series(creationFns, done);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it('should return all the configured device groups from the database', function (done) {
|
|
441
|
+
request(optionsGet, function (error, response, body) {
|
|
442
|
+
should.exist(body);
|
|
443
|
+
should.exist(body.count);
|
|
444
|
+
body.count.should.equal(10);
|
|
445
|
+
should.exist(body.groups);
|
|
446
|
+
should.exist(body.groups.length);
|
|
447
|
+
body.groups.length.should.equal(10);
|
|
448
|
+
done();
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
});
|