iotagent-node-lib 4.5.0 → 4.7.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 (124) hide show
  1. package/.github/workflows/ci.yml +0 -1
  2. package/Changelog +12 -0
  3. package/README.md +67 -272
  4. package/config.js +3 -1
  5. package/doc/README.md +1 -1
  6. package/doc/admin.md +40 -18
  7. package/doc/api.md +532 -136
  8. package/doc/deprecated.md +4 -0
  9. package/doc/devel/architecture.md +5 -135
  10. package/doc/devel/development.md +224 -12
  11. package/doc/getting-started.md +114 -53
  12. package/doc/requirements.txt +1 -1
  13. package/doc/roadmap.md +5 -5
  14. package/docker/Mosquitto/Dockerfile +2 -2
  15. package/docker/Mosquitto/README.md +14 -11
  16. package/lib/commonConfig.js +21 -2
  17. package/lib/constants.js +3 -0
  18. package/lib/fiware-iotagent-lib.js +12 -15
  19. package/lib/jexlTranformsMap.js +3 -1
  20. package/lib/model/Command.js +2 -2
  21. package/lib/model/Device.js +7 -3
  22. package/lib/model/Group.js +5 -3
  23. package/lib/model/dbConn.js +53 -115
  24. package/lib/services/commands/commandRegistryMongoDB.js +115 -75
  25. package/lib/services/common/alarmManagement.js +3 -0
  26. package/lib/services/common/iotManagerService.js +3 -1
  27. package/lib/services/devices/deviceRegistryMemory.js +36 -0
  28. package/lib/services/devices/deviceRegistryMongoDB.js +160 -87
  29. package/lib/services/devices/deviceService.js +33 -3
  30. package/lib/services/devices/devices-NGSI-v2.js +6 -1
  31. package/lib/services/groups/groupRegistryMongoDB.js +120 -83
  32. package/lib/services/groups/groupService.js +1 -1
  33. package/lib/services/ngsi/entities-NGSI-LD.js +320 -570
  34. package/lib/services/ngsi/entities-NGSI-v2.js +51 -3
  35. package/lib/services/ngsi/ngsiService.js +34 -1
  36. package/lib/services/northBound/deviceGroupAdministrationServer.js +42 -6
  37. package/lib/services/northBound/deviceProvisioningServer.js +12 -4
  38. package/lib/services/northBound/northboundServer.js +2 -0
  39. package/lib/services/stats/statsRegistry.js +128 -101
  40. package/lib/templates/createDevice.json +0 -24
  41. package/lib/templates/createDeviceLax.json +0 -23
  42. package/lib/templates/deviceGroup.json +1 -25
  43. package/lib/templates/updateDevice.json +12 -24
  44. package/lib/templates/updateDeviceLax.json +12 -23
  45. package/package.json +5 -5
  46. package/scripts/legacy_expression_tool/README.md +0 -1
  47. package/test/functional/README.md +22 -17
  48. package/test/functional/config-test.js +3 -2
  49. package/test/functional/functional-tests-runner.js +9 -4
  50. package/test/functional/functional-tests.js +4 -4
  51. package/test/functional/testCases.js +245 -4
  52. package/test/functional/testUtils.js +2 -2
  53. package/test/unit/examples/deviceProvisioningRequests/provisionFullDevice.json +1 -13
  54. package/test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json +44 -0
  55. package/test/unit/examples/groupProvisioningRequests/provisionDuplicateConfigGroup.json +35 -0
  56. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroup.json +36 -0
  57. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroupAlternate.json +36 -0
  58. package/test/unit/examples/groupProvisioningRequests/provisionFullGroup.json +1 -0
  59. package/test/unit/general/config-multi-core-test.js +1 -2
  60. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +5 -4
  61. package/test/unit/general/deviceService-test.js +106 -3
  62. package/test/unit/general/statistics-service_test.js +1 -74
  63. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +6 -5
  64. package/test/unit/mongodb/mongodb-configGroup-registry-test.js +452 -0
  65. package/test/unit/mongodb/mongodb-connectionoptions-test.js +9 -42
  66. package/test/unit/mongodb/mongodb-group-registry-test.js +34 -33
  67. package/test/unit/mongodb/mongodb-service-registry-test.js +477 -0
  68. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +4 -4
  69. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +22 -22
  70. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +4 -4
  71. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +14 -15
  72. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +23 -23
  73. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin15.json +0 -5
  74. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +11 -16
  75. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +23 -28
  76. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +8 -13
  77. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
  78. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +24 -29
  79. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +12 -17
  80. package/test/unit/ngsi-ld/examples/contextRequests/updateContextStaticLinkedAttributes.json +12 -10
  81. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +1 -104
  82. package/test/unit/ngsi-ld/general/config-jsonld-contexts-test.js +1 -2
  83. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +4 -5
  84. package/test/unit/ngsi-ld/provisioning/listProvisionedDevices-test.js +0 -4
  85. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +8 -5
  86. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +42 -41
  87. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +11 -10
  88. package/test/unit/ngsiv2/general/deviceService-test.js +98 -4
  89. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  90. package/test/unit/ngsiv2/general/iotam-autoregistration-test.js +195 -0
  91. package/test/unit/ngsiv2/lazyAndCommands/active-devices-attribute-update-test.js +4 -3
  92. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +6 -5
  93. package/test/unit/ngsiv2/lazyAndCommands/lazy-devices-test.js +17 -16
  94. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +10 -18
  95. package/test/unit/ngsiv2/ngsiService/active-devices-test.js +21 -20
  96. package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +8 -7
  97. package/test/unit/ngsiv2/plugins/alias-plugin_test.js +12 -11
  98. package/test/unit/ngsiv2/plugins/custom-plugin_test.js +3 -2
  99. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +28 -27
  100. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +265 -4
  101. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +12 -11
  102. package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +1190 -0
  103. package/test/unit/ngsiv2/provisioning/device-registration_test.js +5 -4
  104. package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +6 -9
  105. package/test/unit/ngsiv2/provisioning/provisionDeviceMultientity-test.js +1 -1
  106. package/test/unit/ngsiv2/provisioning/removeProvisionedDevice-test.js +5 -4
  107. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +8 -7
  108. package/test/unit/statsRegistry/openmetrics-test.js +167 -0
  109. package/lib/templates/queryContext.json +0 -25
  110. package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +0 -35
  111. package/test/unit/examples/deviceProvisioningRequests/provisionDeviceBidirectionalGroup.json +0 -17
  112. package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +0 -31
  113. package/test/unit/general/statistics-persistence_test.js +0 -121
  114. package/test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json +0 -17
  115. package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +0 -12
  116. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  117. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +0 -21
  118. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -17
  119. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -23
  120. package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +0 -132
  121. package/test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json +0 -8
  122. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  123. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -19
  124. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -24
@@ -31,7 +31,6 @@ const config = require('../commonConfig');
31
31
  const constants = require('../constants');
32
32
  const alarms = require('../services/common/alarmManagement');
33
33
  const logger = require('logops');
34
- const async = require('async');
35
34
  const errors = require('../errors');
36
35
  let defaultDb;
37
36
  const DEFAULT_DB_NAME = 'iotagent';
@@ -40,9 +39,9 @@ const context = {
40
39
  };
41
40
 
42
41
  function loadModels() {
43
- require('./Device').load(defaultDb);
44
- require('./Group').load(defaultDb);
45
- require('./Command').load(defaultDb);
42
+ require('./Device').load();
43
+ require('./Group').load();
44
+ require('./Command').load();
46
45
  }
47
46
 
48
47
  /**
@@ -50,93 +49,52 @@ function loadModels() {
50
49
  *
51
50
  * @this Reference to the dbConn module itself.
52
51
  */
52
+
53
53
  function init(host, db, port, options, callback) {
54
- /*jshint camelcase:false, validthis:true */
55
54
  let url;
56
55
  let retries = 0;
57
56
  let lastError;
58
- const maxRetries =
59
- (config.getConfig().mongodb && config.getConfig().mongodb.retries) || constants.DEFAULT_MONGODB_RETRIES;
57
+ const maxRetries = config.getConfig().mongodb?.retries || constants.DEFAULT_MONGODB_RETRIES;
60
58
 
61
59
  function addPort(item) {
62
- return item + ':' + port;
63
- }
64
-
65
- function commaConcat(previous, current, currentIndex) {
66
- if (currentIndex !== 0) {
67
- previous += ',';
68
- }
69
-
70
- previous += current;
71
-
72
- return previous;
60
+ return `${item}:${port}`;
73
61
  }
74
62
 
75
63
  url = 'mongodb://';
76
64
 
77
65
  if (options.auth) {
78
- url += options.auth.user + ':' + options.auth.password + '@';
66
+ url += `${encodeURIComponent(options.auth.user)}:${encodeURIComponent(options.auth.password)}@`;
79
67
  }
80
68
 
81
- const hosts = host.split(',').map(addPort).reduce(commaConcat, '');
82
-
83
- url += hosts + '/' + db;
69
+ const hosts = host.split(',').map(addPort).join(',');
70
+ url += `${hosts}/${db}`;
84
71
 
85
72
  if (options.extraArgs) {
86
- if (options.extraArgs instanceof Object && Object.keys(options.extraArgs).length > 0) {
87
- url += '?';
88
- url += Object.entries(options.extraArgs)
89
- .map(function ([k, v]) {
90
- return encodeURIComponent(k) + '=' + encodeURIComponent(v);
91
- })
92
- .join('&');
73
+ const query = new URLSearchParams(options.extraArgs).toString();
74
+ if (query) {
75
+ url += `?${query}`;
93
76
  }
94
77
  delete options.extraArgs;
95
78
  }
96
79
 
97
- /* eslint-disable-next-line no-unused-vars */
98
- function createConnectionHandler(error, results) {
99
- if (defaultDb) {
100
- logger.info(context, 'Successfully connected to MongoDB.');
101
- module.exports.db = defaultDb;
102
- loadModels();
103
- } else {
104
- logger.error(context, 'MONGODB-002: Error found after [%d] attempts: %s', retries, error || lastError);
105
- }
106
-
107
- callback(error);
108
- }
109
-
110
- function retryCheck() {
111
- return !defaultDb && retries < maxRetries;
112
- }
113
-
114
- function connectionAttempt(url, options, callback) {
115
- logger.info(context, 'Attempting to connect to MongoDB instance with url %j. Attempt %d', url, retries);
116
- // FIXME: useNewUrlParser is no longer used in underlying mongodb driver 4.x
117
- // (see https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_4.0.0.md)
118
- // but not sure if current mongoose version is still using mongodb 3.x internally
119
- // probably mongodb-connectionoptions-test.js needs to be fixed if useNewUrlParser is removed at the end
120
- options.useNewUrlParser = true;
121
- options.useUnifiedTopology = true;
122
- mongoose.set('useCreateIndex', true);
123
- /* eslint-disable-next-line no-unused-vars */
124
- const candidateDb = mongoose.createConnection(url, options, function (error, result) {
125
- if (error) {
126
- logger.error(context, 'MONGODB-001: Error trying to connect to MongoDB: %s', error);
127
- lastError = error;
128
- } else {
129
- defaultDb = candidateDb;
80
+ function connectionAttempt(callback) {
81
+ logger.info(context, `Attempting to connect to MongoDB at ${url}. Attempt ${retries + 1}`);
130
82
 
83
+ mongoose
84
+ .connect(url, options)
85
+ .then(() => {
86
+ defaultDb = mongoose.connection;
87
+ logger.info(context, 'Successfully connected to MongoDB.');
88
+ loadModels();
131
89
  defaultDb.on('error', function (error) {
132
90
  logger.error(context, 'Mongo Driver error: %j', error);
91
+ lastError = error;
133
92
  alarms.raise(constants.MONGO_ALARM, error);
134
93
  });
135
94
  /* eslint-disable-next-line no-unused-vars */
136
95
  defaultDb.on('connecting', function (error) {
137
96
  logger.debug(context, 'Mongo Driver connecting');
138
97
  });
139
-
140
98
  defaultDb.on('connected', function () {
141
99
  logger.debug(context, 'Mongo Driver connected');
142
100
  });
@@ -159,72 +117,52 @@ function init(host, db, port, options, callback) {
159
117
  defaultDb.on('close', function () {
160
118
  logger.debug(context, 'Mongo Driver close');
161
119
  });
162
- }
163
-
164
- callback();
165
- });
166
- }
167
-
168
- function tryCreateConnection(callback) {
169
- const attempt = async.apply(connectionAttempt, url, options, callback);
170
- const seconds =
171
- (config.getConfig().mongodb && config.getConfig().mongodb.retryTime) ||
172
- constants.DEFAULT_MONGODB_RETRY_TIME;
173
-
174
- retries++;
175
-
176
- if (retries === 1) {
177
- logger.info(context, 'First connection attempt');
178
- attempt();
179
- } else {
180
- logger.info(context, 'Waiting %d seconds before attempting again.', seconds);
181
- setTimeout(attempt, seconds * 1000);
182
- }
120
+ callback();
121
+ })
122
+ .catch((err) => {
123
+ logger.error(context, `MONGODB-001: Error trying to connect to MongoDB: ${err}`);
124
+ lastError = err;
125
+ retries++;
126
+ if (retries < maxRetries) {
127
+ const retryTime = config.getConfig().mongodb?.retryTime || constants.DEFAULT_MONGODB_RETRY_TIME;
128
+ logger.info(context, `Retrying in ${retryTime} seconds...`);
129
+ setTimeout(() => connectionAttempt(callback), retryTime * 1000);
130
+ } else {
131
+ logger.error(
132
+ context,
133
+ 'MONGODB-002: Error to connect found after %d attempts: %s',
134
+ retries,
135
+ lastError
136
+ );
137
+ callback(err);
138
+ }
139
+ });
183
140
  }
184
141
 
185
- defaultDb = null;
186
- async.whilst(retryCheck, tryCreateConnection, createConnectionHandler);
142
+ connectionAttempt(callback);
187
143
  }
188
144
 
189
145
  function configureDb(callback) {
190
- /*jshint camelcase:false, validthis:true */
191
146
  const currentConfig = config.getConfig();
192
-
193
- if (
194
- (currentConfig.deviceRegistry && currentConfig.deviceRegistry.type === 'mongodb') ||
195
- (currentConfig.stats && currentConfig.stats.persistence === true)
196
- ) {
197
- if (!currentConfig.mongodb || !currentConfig.mongodb.host) {
147
+ if (currentConfig.deviceRegistry?.type === 'mongodb') {
148
+ if (!currentConfig.mongodb?.host) {
198
149
  logger.fatal(context, 'MONGODB-003: No host found for MongoDB driver.');
199
150
  callback(new errors.BadConfiguration('No host found for MongoDB driver'));
200
151
  } else {
201
- let dbName = currentConfig.mongodb.db;
152
+ const dbName = currentConfig.mongodb.db || DEFAULT_DB_NAME;
202
153
  const port = currentConfig.mongodb.port || 27017;
203
154
  const options = {};
204
155
 
205
- if (!currentConfig.mongodb.db) {
206
- dbName = DEFAULT_DB_NAME;
207
- }
208
-
209
- if (currentConfig.mongodb.replicaSet) {
210
- options.replicaSet = currentConfig.mongodb.replicaSet;
211
- }
212
-
213
- if (currentConfig.mongodb.ssl) {
214
- options.ssl = currentConfig.mongodb.ssl;
215
- }
216
-
217
- if (currentConfig.mongodb.extraArgs) {
218
- options.extraArgs = currentConfig.mongodb.extraArgs;
219
- }
156
+ if (currentConfig.mongodb.replicaSet) options.replicaSet = currentConfig.mongodb.replicaSet;
157
+ if (currentConfig.mongodb.ssl) options.ssl = currentConfig.mongodb.ssl;
158
+ if (currentConfig.mongodb.extraArgs) options.extraArgs = currentConfig.mongodb.extraArgs;
220
159
 
221
160
  if (currentConfig.mongodb.user && currentConfig.mongodb.password) {
222
- options.auth = {};
223
- options.auth.user = currentConfig.mongodb.user;
224
- options.auth.password = currentConfig.mongodb.password;
225
- // authSource only applies if auth is set
161
+ options.auth = {
162
+ user: currentConfig.mongodb.user,
163
+ password: currentConfig.mongodb.password
164
+ };
226
165
  if (currentConfig.mongodb.authSource) {
227
- // Overload extraArgs if it was set
228
166
  options.extraArgs = {
229
167
  ...options.extraArgs,
230
168
  authSource: currentConfig.mongodb.authSource
@@ -232,7 +170,7 @@ function configureDb(callback) {
232
170
  }
233
171
  }
234
172
 
235
- init(config.getConfig().mongodb.host, dbName, port, options, callback);
173
+ init(currentConfig.mongodb.host, dbName, port, options, callback);
236
174
  }
237
175
  } else {
238
176
  callback();
@@ -22,7 +22,7 @@
22
22
  */
23
23
 
24
24
  const logger = require('logops');
25
- const dbService = require('../../model/dbConn');
25
+ const mongoose = require('mongoose');
26
26
  const intoTrans = require('../common/domain').intoTrans;
27
27
  const errors = require('../../errors');
28
28
  const Command = require('../../model/Command');
@@ -45,24 +45,26 @@ function findCommand(service, subservice, deviceId, name, callback) {
45
45
 
46
46
  query.select({ __v: 0 });
47
47
 
48
- query.exec(function handleGet(error, data) {
49
- if (error) {
48
+ query
49
+ .exec({})
50
+ .then((data) => {
51
+ if (data) {
52
+ callback(null, data);
53
+ } else {
54
+ logger.debug(
55
+ context,
56
+ 'Command for DeviceID [%j] with name [%j] not found with [%j]',
57
+ deviceId,
58
+ name,
59
+ queryObj
60
+ );
61
+ callback(new errors.CommandNotFound(name, queryObj));
62
+ }
63
+ })
64
+ .catch((error) => {
50
65
  logger.debug(context, 'Internal MongoDB Error getting command: %s', error);
51
-
52
66
  callback(new errors.InternalDbError(error));
53
- } else if (data) {
54
- callback(null, data);
55
- } else {
56
- logger.debug(
57
- context,
58
- 'Command for DeviceID [%j] with name [%j] not found with [%j]',
59
- deviceId,
60
- name,
61
- queryObj
62
- );
63
- callback(new errors.CommandNotFound(name, queryObj));
64
- }
65
- });
67
+ });
66
68
  }
67
69
 
68
70
  function updateCommand(service, subservice, deviceId, command, callback) {
@@ -72,9 +74,14 @@ function updateCommand(service, subservice, deviceId, command, callback) {
72
74
  } else {
73
75
  commandDAO.value = command.value;
74
76
 
75
- commandDAO.save(function (error) {
76
- callback(error, commandDAO.toObject());
77
- });
77
+ commandDAO
78
+ .save({})
79
+ .then((commandDAOs) => {
80
+ callback(null, commandDAOs.toObject());
81
+ })
82
+ .catch((error) => {
83
+ callback(error);
84
+ });
78
85
  }
79
86
  });
80
87
  }
@@ -94,15 +101,15 @@ function createCommand(service, subservice, deviceId, command, callback) {
94
101
 
95
102
  logger.debug(context, 'Storing command for deviceId [%s] with name [%s]', deviceId, command.name);
96
103
 
97
- commandObj.save(function saveHandler(error, commandDAO) {
98
- if (error) {
104
+ commandObj
105
+ .save({})
106
+ .then((commandDAO) => {
107
+ callback(null, commandDAO.toObject());
108
+ })
109
+ .catch((error) => {
99
110
  logger.debug(context, 'Error storing command information: %s', error);
100
-
101
111
  callback(new errors.InternalDbError(error));
102
- } else {
103
- callback(null, commandDAO.toObject());
104
- }
105
- });
112
+ });
106
113
  }
107
114
 
108
115
  function addCommand(service, subservice, deviceId, command, callback) {
@@ -129,16 +136,33 @@ function listCommands(service, subservice, deviceId, callback) {
129
136
  condition.deviceId = deviceId;
130
137
 
131
138
  const query = Command.model.find(condition).sort();
132
-
133
- async.series(
134
- [query.exec.bind(query), Command.model.countDocuments.bind(Command.model, condition)],
135
- function (error, results) {
136
- callback(error, {
137
- count: results[1],
138
- commands: results[0].map(toObjectFn)
139
+ const queryCount = Command.model.countDocuments(condition);
140
+ function funcQuery(cb) {
141
+ query
142
+ .exec({})
143
+ .then((res) => {
144
+ cb(null, res);
145
+ })
146
+ .catch((error) => {
147
+ cb(error);
139
148
  });
140
- }
141
- );
149
+ }
150
+ function funcQueryCount(cb) {
151
+ queryCount
152
+ .exec({})
153
+ .then((res) => {
154
+ cb(null, res);
155
+ })
156
+ .catch((error) => {
157
+ cb(error);
158
+ });
159
+ }
160
+ async.series([funcQuery, funcQueryCount], function (error, results) {
161
+ callback(error, {
162
+ count: results[1],
163
+ commands: results[0].map(toObjectFn)
164
+ });
165
+ });
142
166
  }
143
167
 
144
168
  function remove(service, subservice, deviceId, name, callback) {
@@ -155,26 +179,29 @@ function remove(service, subservice, deviceId, name, callback) {
155
179
  if (error) {
156
180
  callback(error);
157
181
  } else {
158
- Command.model.deleteOne({ _id: command._id }, function (error, commandResult) {
159
- if (error) {
182
+ const query = Command.model.deleteOne({ _id: command._id });
183
+ query
184
+ .exec({})
185
+ .then((commandResult) => {
186
+ if (commandResult && commandResult.result && commandResult.result.n === 1) {
187
+ logger.debug(context, 'Command [%s] successfully removed.', name);
188
+
189
+ callback(null, commandResult);
190
+ } else {
191
+ const deviceInfo = {
192
+ service,
193
+ subservice,
194
+ deviceId,
195
+ name
196
+ };
197
+ logger.debug(context, 'Command [%s] not found for removal with %j', name, deviceInfo);
198
+ callback(new errors.CommandNotFound(name, deviceInfo));
199
+ }
200
+ })
201
+ .catch((error) => {
160
202
  logger.debug(context, 'Internal MongoDB Error getting command: %s', error);
161
-
162
203
  callback(new errors.InternalDbError(error));
163
- } else if (commandResult && commandResult.result && commandResult.result.n === 1) {
164
- logger.debug(context, 'Command [%s] successfully removed.', name);
165
-
166
- callback(null, commandResult);
167
- } else {
168
- const deviceInfo = {
169
- service,
170
- subservice,
171
- deviceId,
172
- name
173
- };
174
- logger.debug(context, 'Command [%s] not found for removal with %j', name, deviceInfo);
175
- callback(new errors.CommandNotFound(name, deviceInfo));
176
- }
177
- });
204
+ });
178
205
  }
179
206
  });
180
207
  }
@@ -190,35 +217,48 @@ function listToObject(commandList) {
190
217
  }
191
218
 
192
219
  function removeFromDate(creationDate, callback) {
193
- const query = { creationDate: { $lt: creationDate } };
220
+ const condition = { creationDate: { $lt: creationDate } };
194
221
 
195
222
  if (Command.model) {
196
- Command.model.find(query).exec(function (error, commandList) {
197
- if (!error && commandList && commandList.length > 0) {
198
- Command.model.deleteOne(query, function (error) {
199
- if (error) {
200
- logger.debug(context, 'Internal MongoDB Error removing expired commands: %s', error);
201
-
202
- callback(new errors.InternalDbError(error));
203
- } else {
204
- logger.debug(
205
- context,
206
- 'Expired commands successfully removed from MongoDB for date [%s]',
207
- creationDate
208
- );
209
-
210
- callback(null, listToObject(commandList));
211
- }
212
- });
213
- }
214
- });
223
+ const query = Command.model.find(condition);
224
+ query
225
+ .exec({})
226
+ .then((commandList) => {
227
+ if (commandList && commandList.length > 0) {
228
+ const queryDel = Command.model.deleteOne(condition);
229
+ queryDel
230
+ .exec({})
231
+ .then(() => {
232
+ logger.debug(
233
+ context,
234
+ 'Expired commands successfully removed from MongoDB for date [%s]',
235
+ creationDate
236
+ );
237
+ callback(null, listToObject(commandList));
238
+ })
239
+ .catch((error) => {
240
+ logger.debug(context, 'Internal MongoDB Error removing expired commands: %s', error);
241
+ callback(new errors.InternalDbError(error));
242
+ });
243
+ }
244
+ })
245
+ .catch((error) => {
246
+ logger.debug(context, 'Internal MongoDB Error looking for expired commands: %s', error);
247
+ });
215
248
  } else {
216
249
  callback(null, []);
217
250
  }
218
251
  }
219
252
 
220
253
  function clear(callback) {
221
- dbService.db.db.dropDatabase(callback);
254
+ mongoose.connection
255
+ .dropDatabase()
256
+ .then(() => {
257
+ callback(null);
258
+ })
259
+ .catch((error) => {
260
+ callback(error);
261
+ });
222
262
  }
223
263
 
224
264
  function init(newConfig, callback) {
@@ -22,6 +22,7 @@
22
22
  */
23
23
 
24
24
  let alarmRepository = {};
25
+ const statsRegistry = require('../stats/statsRegistry');
25
26
  const logger = require('logops');
26
27
  const context = {
27
28
  op: 'IoTAgentNGSI.Alarms'
@@ -41,6 +42,7 @@ function raise(alarmName, description) {
41
42
  };
42
43
 
43
44
  logger.error(context, 'Raising [%s]: %j', alarmName, description);
45
+ statsRegistry.add('raiseAlarm', 1, function () {});
44
46
  }
45
47
  }
46
48
 
@@ -53,6 +55,7 @@ function release(alarmName) {
53
55
  if (alarmRepository[alarmName]) {
54
56
  delete alarmRepository[alarmName];
55
57
  logger.error(context, 'Releasing [%s]', alarmName);
58
+ statsRegistry.add('releaseAlarm', 1, function () {});
56
59
  }
57
60
  }
58
61
 
@@ -63,7 +63,9 @@ function register(callback) {
63
63
  entityNameExp: service.entityNameExp,
64
64
  payloadType: service.payloadType,
65
65
  endpoint: service.endpoint,
66
- transport: service.transport
66
+ transport: service.transport,
67
+ useCBflowControl: service.useCBflowControl,
68
+ storeLastMeasure: service.storeLastMeasure
67
69
  };
68
70
  }
69
71
 
@@ -210,8 +210,44 @@ function getDevicesByAttribute(name, value, service, subservice, callback) {
210
210
  }
211
211
  }
212
212
 
213
+ function storeDeviceField(fieldName, fieldValue, typeInformation, callback) {
214
+ if (
215
+ typeInformation &&
216
+ typeInformation.id &&
217
+ typeInformation.apikey &&
218
+ typeInformation.service &&
219
+ typeInformation.subservice
220
+ ) {
221
+ getDevice(
222
+ typeInformation.id,
223
+ typeInformation.apikey,
224
+ typeInformation.service,
225
+ typeInformation.subservice,
226
+ function (error, data) {
227
+ if (!error) {
228
+ if (data) {
229
+ if (fieldName === 'lastMeasure') {
230
+ data.lastMeasure = { timestamp: new Date().toISOString(), measure: fieldValue };
231
+ } else {
232
+ data[fieldName] = fieldValue;
233
+ }
234
+ }
235
+ if (callback) {
236
+ callback(null, data);
237
+ }
238
+ } else {
239
+ callback(error, null);
240
+ }
241
+ }
242
+ );
243
+ } else {
244
+ callback(null, null);
245
+ }
246
+ }
247
+
213
248
  exports.getDevicesByAttribute = getDevicesByAttribute;
214
249
  exports.store = storeDevice;
250
+ exports.storeDeviceField = storeDeviceField;
215
251
  exports.update = update;
216
252
  exports.remove = removeDevice;
217
253
  exports.list = listDevices;