iotagent-node-lib 2.20.0 → 2.23.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 (68) hide show
  1. package/.nyc_output/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +1 -0
  2. package/.nyc_output/processinfo/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +1 -0
  3. package/.nyc_output/processinfo/index.json +1 -1
  4. package/.readthedocs.yml +3 -1
  5. package/CHANGES_NEXT_RELEASE +1 -0
  6. package/README.md +2 -2
  7. package/config +0 -0
  8. package/doc/Contribution.md +3 -3
  9. package/doc/advanced-topics.md +19 -8
  10. package/doc/api.md +14 -3
  11. package/doc/expressionLanguage.md +17 -0
  12. package/doc/northboundinteractions.md +40 -33
  13. package/doc/operations.md +8 -5
  14. package/doc/requirements.txt +4 -0
  15. package/{docs → doc}/roadmap.md +21 -6
  16. package/doc/usermanual.md +4 -4
  17. package/docker/Mosquitto/Dockerfile +28 -12
  18. package/docker/Mosquitto/Dockerfile.debian +38 -0
  19. package/docker/Mosquitto/Dockerfile.debian~ +23 -0
  20. package/docker/Mosquitto/README.md +8 -7
  21. package/docker/Mosquitto/startMosquitto.sh +8 -0
  22. package/lib/fiware-iotagent-lib.js +1 -0
  23. package/lib/jexlTranformsMap.js +3 -1
  24. package/lib/model/Group.js +2 -1
  25. package/lib/model/dbConn.js +4 -0
  26. package/lib/plugins/expressionPlugin.js +56 -21
  27. package/lib/plugins/multiEntity.js +43 -49
  28. package/lib/plugins/multiEntity.js_avg2 +343 -0
  29. package/lib/plugins/pluginUtils.js +16 -0
  30. package/lib/services/commands/commandService.js +29 -2
  31. package/lib/services/common/iotManagerService.js +2 -1
  32. package/lib/services/devices/deviceRegistryMemory.js +13 -2
  33. package/lib/services/devices/deviceRegistryMongoDB.js +15 -7
  34. package/lib/services/devices/deviceService.js +52 -16
  35. package/lib/services/groups/groupRegistryMongoDB.js +13 -12
  36. package/lib/services/ngsi/entities-NGSI-LD.js +13 -4
  37. package/lib/services/ngsi/entities-NGSI-v2.js +64 -13
  38. package/lib/services/ngsi/ngsiService.js +3 -3
  39. package/lib/services/northBound/contextServer-NGSI-LD.js +20 -1
  40. package/lib/services/northBound/contextServer-NGSI-v2.js +39 -30
  41. package/lib/services/northBound/contextServerUtils.js +10 -10
  42. package/lib/services/northBound/deviceProvisioningServer.js +4 -1
  43. package/lib/templates/createDevice.json +13 -2
  44. package/lib/templates/createDeviceLax.json +2 -3
  45. package/lib/templates/updateDevice.json +13 -2
  46. package/package.json +26 -26
  47. package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +14 -0
  48. package/test/unit/mongodb/mongoDBUtils.js +2 -2
  49. package/test/unit/mongodb/mongodb-group-registry-test.js +1 -1
  50. package/test/unit/mongodb/mongodb-registry-test.js +2 -3
  51. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +2 -1
  52. package/test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json +15 -0
  53. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +315 -1
  54. package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +112 -0
  55. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +1 -1
  56. package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +8 -0
  57. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +6 -0
  58. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin35.json +2 -0
  59. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +12 -0
  60. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +27 -0
  61. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +72 -9
  62. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +151 -0
  63. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +63 -0
  64. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js_avg2 +1224 -0
  65. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +60 -0
  66. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +2 -1
  67. package/.nyc_output/76bc24ff-5fac-4b5a-997d-de2799342eb0.json +0 -1
  68. package/.nyc_output/processinfo/76bc24ff-5fac-4b5a-997d-de2799342eb0.json +0 -1
@@ -1,19 +1,35 @@
1
- FROM centos:7.9.2009
1
+ ARG IMAGE_TAG=11.3-slim
2
+ FROM debian:${IMAGE_TAG}
2
3
 
3
- COPY aclfile /root/
4
- COPY startMosquitto.sh /bin
4
+ ARG CLEAN_DEV_TOOLS
5
+ ENV CLEAN_DEV_TOOLS ${CLEAN_DEV_TOOLS:-1}
5
6
 
6
7
  ENV CONGIF_FROM_ENV true
7
8
 
8
- RUN yum update -y && yum install -y wget \
9
- && yum install -y epel-release \
10
- && yum update -y epel-release \
11
- && yum install -y mosquitto \
12
- && cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.orig \
13
- && chmod 755 /bin/startMosquitto.sh \
14
- && mkdir /var/log/mosquitto \
15
- && chown mosquitto:mosquitto /var/log/mosquitto \
16
- && yum clean all
9
+ COPY aclfile /root/
10
+ COPY startMosquitto.sh /bin
11
+
12
+ RUN \
13
+ # Install security updates
14
+ apt-get -y update && \
15
+ apt-get -y upgrade && \
16
+ # Install dependencies
17
+ apt-get -y install \
18
+ wget \
19
+ mosquitto && \
20
+ cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.orig && \
21
+ chmod 755 /bin/startMosquitto.sh && \
22
+ mkdir -p /var/log/mosquitto && \
23
+ chown mosquitto:mosquitto /var/log/mosquitto && \
24
+ mkdir -p /var/run/mosquitto/ && \
25
+ chown mosquitto:mosquitto /var/run/mosquitto && \
26
+ echo "INFO: Cleaning unused software..." && \
27
+ apt-get clean && \
28
+ apt-get -y autoremove --purge && \
29
+ if [ ${CLEAN_DEV_TOOLS} -eq 0 ] ; then exit 0 ; fi && \
30
+ # remove the same packages we installed at the beginning to build Orch
31
+ apt-get -y autoremove --purge \
32
+ wget
17
33
 
18
34
 
19
35
  EXPOSE 1883
@@ -0,0 +1,38 @@
1
+ ARG IMAGE_TAG=11.2-slim
2
+ FROM debian:${IMAGE_TAG}
3
+
4
+ ARG CLEAN_DEV_TOOLS
5
+ ENV CLEAN_DEV_TOOLS ${CLEAN_DEV_TOOLS:-1}
6
+
7
+ ENV CONGIF_FROM_ENV true
8
+
9
+ COPY aclfile /root/
10
+ COPY startMosquitto.sh /bin
11
+
12
+ RUN \
13
+ # Install security updates
14
+ apt-get -y update && \
15
+ apt-get -y upgrade && \
16
+ # Install dependencies
17
+ apt-get -y install \
18
+ wget \
19
+ mosquitto && \
20
+ cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.orig && \
21
+ chmod 755 /bin/startMosquitto.sh && \
22
+ mkdir -p /var/log/mosquitto && \
23
+ chown mosquitto:mosquitto /var/log/mosquitto && \
24
+ echo "INFO: Cleaning unused software..." && \
25
+ apt-get clean && \
26
+ apt-get -y autoremove --purge && \
27
+ if [ ${CLEAN_DEV_TOOLS} -eq 0 ] ; then exit 0 ; fi && \
28
+ # remove the same packages we installed at the beginning to build Orch
29
+ apt-get -y autoremove --purge \
30
+ wget && \
31
+ # Don't need old log files inside docker images
32
+ rm -f /var/log/*log
33
+
34
+
35
+ EXPOSE 1883
36
+ EXPOSE 9001
37
+
38
+ ENTRYPOINT /bin/startMosquitto.sh
@@ -0,0 +1,23 @@
1
+ ARG IMAGE_TAG=11.2-slim
2
+ FROM debian:${IMAGE_TAG}
3
+
4
+ COPY aclfile /root/
5
+ COPY startMosquitto.sh /bin
6
+
7
+ ENV CONGIF_FROM_ENV true
8
+
9
+ RUN yum update -y && yum install -y wget \
10
+ && yum install -y epel-release \
11
+ && yum update -y epel-release \
12
+ && yum install -y mosquitto \
13
+ && cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.orig \
14
+ && chmod 755 /bin/startMosquitto.sh \
15
+ && mkdir /var/log/mosquitto \
16
+ && chown mosquitto:mosquitto /var/log/mosquitto \
17
+ && yum clean all
18
+
19
+
20
+ EXPOSE 1883
21
+ EXPOSE 9001
22
+
23
+ ENTRYPOINT /bin/startMosquitto.sh
@@ -2,10 +2,11 @@ Thi directory containts the Dockerfile (and associated files) for a container of
2
2
  This container is provide as a help for users to test with MQTT, but it is just an auxiliary material in this repository.
3
3
 
4
4
  The following releases matches with eclipse-mosquitto version:
5
- - 1.6.0 uses mosquitto-1.6.10-1.el7.x86_64
6
- - 1.5.0 uses mosquitto-1.6.10-1.el7.x86_64
7
- - 1.4.0 uses mosquitto-1.6.10-1.el7.x86_64
8
- - 1.3.0 uses mosquitto-1.6.8-1.el7.x86_64
9
- - 1.2.0 uses mosquitto-1.6.7-1.el7.x86_64
10
- - 1.1.0 uses mosquitto-1.5.8-1.el7.x86_64
11
- - 1.0.0 uses mosquitto-1.4.8-1.el7.x86_64
5
+ - 2.0.0 uses mosquitto-2.0.11 from Debian 11
6
+ - 1.6.0 uses mosquitto-1.6.10-1.el7.x86_64 (from Centos7)
7
+ - 1.5.0 uses mosquitto-1.6.10-1.el7.x86_64 (from Centos7)
8
+ - 1.4.0 uses mosquitto-1.6.10-1.el7.x86_64 (from Centos7)
9
+ - 1.3.0 uses mosquitto-1.6.8-1.el7.x86_64 (from Centos7)
10
+ - 1.2.0 uses mosquitto-1.6.7-1.el7.x86_64 (from Centos7)
11
+ - 1.1.0 uses mosquitto-1.5.8-1.el7.x86_64 (from Centos7)
12
+ - 1.0.0 uses mosquitto-1.4.8-1.el7.x86_64 (from Centos7)
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
+ echo "INFO: startMosquitto..."
4
+
3
5
  if [ "${CONGIF_FROM_ENV}" = true ] ; then
4
6
  cp /etc/mosquitto/mosquitto.conf.orig /etc/mosquitto/mosquitto.conf
7
+ sed -i 's/log_dest file \/var\/log\/mosquitto\/mosquitto.log/log_dest stderr/g' /etc/mosquitto/mosquitto.conf
5
8
  echo "log_timestamp true" >> /etc/mosquitto/mosquitto.conf
6
9
  echo "log_timestamp_format %Y-%m-%dT%H:%M:%S" >> /etc/mosquitto/mosquitto.conf
7
10
  echo 'listener 9001' >> /etc/mosquitto/mosquitto.conf
@@ -18,4 +21,9 @@ if [ "${CONGIF_FROM_ENV}" = true ] ; then
18
21
  fi
19
22
  fi
20
23
 
24
+ echo "INFO: content /etc/mosquitto/mosquitto.conf: "
25
+ cat /etc/mosquitto/mosquitto.conf
26
+
27
+ echo "INFO: start: startMosquitto -c /etc/mosquitto/mosquitto.conf"
28
+
21
29
  /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
@@ -314,6 +314,7 @@ exports.listDevices = deviceService.listDevices;
314
314
  exports.getDevice = deviceService.getDevice;
315
315
  exports.getDeviceSilently = deviceService.getDeviceSilently;
316
316
  exports.getDeviceByName = deviceService.getDeviceByName;
317
+ exports.getDeviceByNameAndType = deviceService.getDeviceByNameAndType;
317
318
  exports.getDevicesByAttribute = deviceService.getDevicesByAttribute;
318
319
  exports.mergeDeviceWithConfiguration = deviceService.mergeDeviceWithConfiguration;
319
320
  exports.retrieveDevice = deviceService.retrieveDevice;
@@ -65,7 +65,9 @@ const map = {
65
65
  let s = new Set(arr);
66
66
  s.delete(x);
67
67
  return Array.from(s);
68
- }
68
+ },
69
+ touppercase: (val) => String(val).toUpperCase(),
70
+ tolowercase: (val) => String(val).toLowerCase()
69
71
  };
70
72
 
71
73
  exports.map = map;
@@ -62,7 +62,8 @@ const Group = new Schema({
62
62
  expressionLanguage: String,
63
63
  explicitAttrs: ExplicitAttrsType,
64
64
  defaultEntityNameConjunction: String,
65
- ngsiVersion: String
65
+ ngsiVersion: String,
66
+ entityNameExp: String
66
67
  });
67
68
 
68
69
  function load(db) {
@@ -113,6 +113,10 @@ function init(host, db, port, options, callback) {
113
113
  options,
114
114
  retries
115
115
  );
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
116
120
  options.useNewUrlParser = true;
117
121
  mongoose.set('useCreateIndex', true);
118
122
  /* eslint-disable-next-line no-unused-vars */
@@ -30,6 +30,8 @@ const jexlParser = require('./jexlParser');
30
30
  const config = require('../commonConfig');
31
31
  /* eslint-disable no-unused-vars */
32
32
  const logger = require('logops');
33
+ const errors = require('../errors');
34
+ const constants = require('../constants');
33
35
  const context = {
34
36
  op: 'IoTAgentNGSI.expressionPlugin'
35
37
  };
@@ -42,6 +44,22 @@ function setJEXLTransforms(transformationMap) {
42
44
  jexlParser.setTransforms(transformationMap);
43
45
  }
44
46
 
47
+ function applyExpression(expression, context, typeInformation) {
48
+ let parser = jexlParser;
49
+ if (!checkJexl(typeInformation)) {
50
+ parser = legacyParser;
51
+ }
52
+ return parser.applyExpression(expression, context, typeInformation);
53
+ }
54
+
55
+ function extractContext(attributeList, typeInformation) {
56
+ let parser = jexlParser;
57
+ if (!checkJexl(typeInformation)) {
58
+ parser = legacyParser;
59
+ }
60
+ return parser.extractContext(attributeList);
61
+ }
62
+
45
63
  function mergeAttributes(attrList1, attrList2) {
46
64
  const finalCollection = _.clone(attrList1);
47
65
  const additionalItems = [];
@@ -70,26 +88,26 @@ function mergeAttributes(attrList1, attrList2) {
70
88
  return finalCollection.concat(additionalItems);
71
89
  }
72
90
 
73
- function update(entity, typeInformation, callback) {
74
- function checkJexl(typeInformation) {
75
- if (
76
- config.getConfig().defaultExpressionLanguage === 'jexl' &&
77
- typeInformation.expressionLanguage &&
78
- typeInformation.expressionLanguage !== 'legacy'
79
- ) {
80
- return true;
81
- } else if (config.getConfig().defaultExpressionLanguage === 'jexl' && !typeInformation.expressionLanguage) {
82
- return true;
83
- } else if (
84
- config.getConfig().defaultExpressionLanguage === 'legacy' &&
85
- typeInformation.expressionLanguage &&
86
- typeInformation.expressionLanguage === 'jexl'
87
- ) {
88
- return true;
89
- }
90
- return false;
91
+ function checkJexl(typeInformation) {
92
+ if (
93
+ config.getConfig().defaultExpressionLanguage === 'jexl' &&
94
+ typeInformation.expressionLanguage &&
95
+ typeInformation.expressionLanguage !== 'legacy'
96
+ ) {
97
+ return true;
98
+ } else if (config.getConfig().defaultExpressionLanguage === 'jexl' && !typeInformation.expressionLanguage) {
99
+ return true;
100
+ } else if (
101
+ config.getConfig().defaultExpressionLanguage === 'legacy' &&
102
+ typeInformation.expressionLanguage &&
103
+ typeInformation.expressionLanguage === 'jexl'
104
+ ) {
105
+ return true;
91
106
  }
107
+ return false;
108
+ }
92
109
 
110
+ function update(entity, typeInformation, callback) {
93
111
  function processEntityUpdateNgsi2(attributes) {
94
112
  let parser = legacyParser;
95
113
  if (checkJexl(typeInformation)) {
@@ -114,15 +132,32 @@ function update(entity, typeInformation, callback) {
114
132
 
115
133
  try {
116
134
  logger.debug(context, 'expressionPlugin entity %j', entity);
117
- let attsArray = utils.extractAttributesArrayFromNgsi2Entity(entity);
118
- attsArray = processEntityUpdateNgsi2(attsArray);
119
- entity = utils.createNgsi2Entity(entity.id, entity.type, attsArray, true);
135
+ const attsArray = utils.extractAttributesArrayFromNgsi2Entity(entity);
136
+ // Exclude processing all attr expressions when current attr is of type 'commandStatus' or 'commandResult'
137
+ const attsArrayFiltered = attsArray.filter((obj) => {
138
+ return ![constants.COMMAND_STATUS, constants.COMMAND_RESULT].includes(obj.type);
139
+ });
140
+ const attsArrayCmd = attsArray.filter((obj) => {
141
+ // just attr of type 'commandStatus' or 'commandResult'
142
+ return [constants.COMMAND_STATUS, constants.COMMAND_RESULT].includes(obj.type);
143
+ });
144
+ let attsArrayFinal = [];
145
+ if (attsArrayFiltered.length > 0) {
146
+ attsArrayFinal = processEntityUpdateNgsi2(attsArrayFiltered);
147
+ }
148
+ attsArrayFinal = attsArrayFinal.concat(attsArrayCmd);
149
+ entity = utils.createNgsi2Entity(entity.id, entity.type, attsArrayFinal, true);
120
150
 
121
151
  callback(null, entity, typeInformation);
122
152
  } catch (e) {
153
+ logger.info(context, 'expressionPlugin error %j procesing entity %j', e, entity);
123
154
  callback(e);
155
+ return;
124
156
  }
125
157
  }
126
158
 
127
159
  exports.update = update;
128
160
  exports.setJEXLTransforms = setJEXLTransforms;
161
+ exports.applyExpression = applyExpression;
162
+ exports.extractContext = extractContext;
163
+ exports.checkJexl = checkJexl;
@@ -30,7 +30,7 @@ const _ = require('underscore');
30
30
  const constants = require('../constants');
31
31
  const legacyParser = require('./expressionParser');
32
32
  const jexlParser = require('./jexlParser');
33
- const config = require('../commonConfig');
33
+ const expressionPlugin = require('./expressionPlugin');
34
34
  /* eslint-disable-next-line no-unused-vars */
35
35
  const logger = require('logops');
36
36
  /* eslint-disable-next-line no-unused-vars */
@@ -41,27 +41,8 @@ const utils = require('./pluginUtils');
41
41
  /* eslint-disable-next-line no-unused-vars */
42
42
  const aliasPlugin = require('./attributeAlias');
43
43
 
44
- function checkJexl(typeInformation) {
45
- if (
46
- config.getConfig().defaultExpressionLanguage === 'jexl' &&
47
- typeInformation.expressionLanguage &&
48
- typeInformation.expressionLanguage !== 'legacy'
49
- ) {
50
- return true;
51
- } else if (config.getConfig().defaultExpressionLanguage === 'jexl' && !typeInformation.expressionLanguage) {
52
- return true;
53
- } else if (
54
- config.getConfig().defaultExpressionLanguage === 'legacy' &&
55
- typeInformation.expressionLanguage &&
56
- typeInformation.expressionLanguage === 'jexl'
57
- ) {
58
- return true;
59
- }
60
- return false;
61
- }
62
-
63
- function hasEntityName(item) {
64
- return item.entity_name;
44
+ function hasEntityNameOrEntityType(item) {
45
+ return item.entity_name || item.entity_type;
65
46
  }
66
47
 
67
48
  /**
@@ -225,37 +206,50 @@ function propagateTimestamp(entity, entities) {
225
206
  }
226
207
 
227
208
  function updateAttribute(entity, typeInformation, callback) {
228
- let parser = legacyParser;
229
- if (checkJexl(typeInformation)) {
230
- parser = jexlParser;
231
- }
232
- const attsArray = utils.extractAttributesArrayFromNgsi2Entity(entity);
233
- const ctx = parser.extractContext(attsArray);
234
-
235
- let entities = [entity];
236
- if (typeInformation.active) {
237
- const multiEntityAttributes = typeInformation.active.filter(hasEntityName);
238
- for (let i in multiEntityAttributes) {
239
- if (parser.contextAvailable(multiEntityAttributes[i].entity_name, ctx)) {
240
- let entityName = parser.applyExpression(multiEntityAttributes[i].entity_name, ctx, typeInformation);
241
- // An entity_name could not be null, but a result or expression could be null
242
- if (entityName !== null) {
243
- multiEntityAttributes[i].entity_name = entityName;
209
+ try {
210
+ logger.debug(context, 'multiEntityPlugin entity %j', entity);
211
+ let parser = jexlParser;
212
+ if (!expressionPlugin.checkJexl(typeInformation)) {
213
+ parser = legacyParser;
214
+ }
215
+ // The context for the JEXL expression should be the ID, TYPE, S, SS
216
+ let attrList = utils.getIdTypeServSubServiceFromDevice(typeInformation);
217
+ const attsArray = utils.extractAttributesArrayFromNgsi2Entity(entity);
218
+ attrList = attrList.concat(attsArray);
219
+ const ctx = parser.extractContext(attrList);
220
+ let entities = [entity];
221
+ if (typeInformation.active) {
222
+ const multiEntityAttributes = typeInformation.active.filter(hasEntityNameOrEntityType);
223
+ for (let i in multiEntityAttributes) {
224
+ if (!multiEntityAttributes[i].entity_name) {
225
+ // Then hasEntityType and entity_name should be device.name
226
+ multiEntityAttributes[i].entity_name = typeInformation.name;
227
+ }
228
+ if (parser.contextAvailable(multiEntityAttributes[i].entity_name, ctx)) {
229
+ let entityName = parser.applyExpression(multiEntityAttributes[i].entity_name, ctx, typeInformation);
230
+ // An entity_name could not be null, but a result or expression could be null
231
+ if (entityName !== null) {
232
+ multiEntityAttributes[i].entity_name = entityName;
233
+ }
244
234
  }
245
235
  }
236
+ const newEntities = extractNewEntities(multiEntityAttributes, typeInformation.type);
237
+
238
+ if (multiEntityAttributes.length > 0) {
239
+ let resultAttributes = filterOutMultientitiesNgsi2(entity, multiEntityAttributes);
240
+ const newCes = generateNewCEsNgsi2(entity, newEntities, multiEntityAttributes);
241
+ entities = [resultAttributes].concat(newCes);
242
+ propagateTimestamp(entity, entities);
243
+ } else {
244
+ entities = entity;
245
+ }
246
246
  }
247
- const newEntities = extractNewEntities(multiEntityAttributes, typeInformation.type);
248
-
249
- if (multiEntityAttributes.length > 0) {
250
- let resultAttributes = filterOutMultientitiesNgsi2(entity, multiEntityAttributes);
251
- const newCes = generateNewCEsNgsi2(entity, newEntities, multiEntityAttributes);
252
- entities = [resultAttributes].concat(newCes);
253
- propagateTimestamp(entity, entities);
254
- } else {
255
- entities = entity;
256
- }
247
+ callback(null, entities, typeInformation);
248
+ } catch (e) {
249
+ logger.info(context, 'multiEntityPlugin error %j procesing entity %j', e, entity);
250
+ callback(e);
251
+ return;
257
252
  }
258
- callback(null, entities, typeInformation);
259
253
  }
260
254
 
261
255
  exports.update = updateAttribute;