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
@@ -60,33 +60,9 @@
60
60
  "commands": {
61
61
  "description": "list of commands of the devices",
62
62
  "type": "array"
63
- },
64
- "reverse": {
65
- "description": "Define the attribute as bidirectional",
66
- "type": "array",
67
- "items": {
68
- "type": "object",
69
- "additionalProperties": false,
70
- "properties": {
71
- "object_id": {
72
- "description": "ID of the attribute in the device",
73
- "type": "string",
74
- "pattern": "^([^<>();'=\"]+)+$"
75
- },
76
- "type": {
77
- "description": "Type of the attribute in the target entity",
78
- "type": "string",
79
- "pattern": "^([^<>();'=\"]+)+$"
80
- },
81
- "expression": {
82
- "description": "Optional expression for measurement transformation",
83
- "type": "string"
84
- }
85
- }
86
- }
87
63
  }
88
64
  }
89
65
  }
90
66
  }
91
- }
67
+ }
92
68
  }
@@ -105,30 +105,6 @@
105
105
  "type": "string",
106
106
  "pattern": "^([^<>;'=\"]+)+$"
107
107
  },
108
- "reverse": {
109
- "description": "Define the attribute as bidirectional",
110
- "type": "array",
111
- "items": {
112
- "type": "object",
113
- "additionalProperties": false,
114
- "properties": {
115
- "object_id": {
116
- "description": "ID of the attribute in the device",
117
- "type": "string",
118
- "pattern": "^([^<>();'=\"]+)+$"
119
- },
120
- "type": {
121
- "description": "Type of the attribute in the target entity",
122
- "type": "string",
123
- "pattern": "^([^<>();'=\"]+)+$"
124
- },
125
- "expression": {
126
- "description": "Optional expression for measurement transformation",
127
- "type": "string"
128
- }
129
- }
130
- }
131
- },
132
108
  "metadata": {
133
109
  "description": "Attribute Metadata",
134
110
  "type": "object"
@@ -173,6 +149,10 @@
173
149
  "description": "Payload type",
174
150
  "type": "string"
175
151
  },
152
+ "useCBflowControl": {
153
+ "description": "use CB flowControl option",
154
+ "type": "boolean"
155
+ },
176
156
  "contentType": {
177
157
  "description": "Content type",
178
158
  "type": "string"
@@ -218,6 +198,14 @@
218
198
  "payloadType": {
219
199
  "description": "Payload type allowed for measures for this device",
220
200
  "type": "string"
201
+ },
202
+ "storeLastMeasure": {
203
+ "description": "Store last measure",
204
+ "type": "boolean"
205
+ },
206
+ "lastMeasure": {
207
+ "description": "last measure",
208
+ "type": "object"
221
209
  }
222
210
  }
223
211
  }
@@ -89,29 +89,6 @@
89
89
  "description": "Optional entity type for multientity updatess",
90
90
  "type": "string",
91
91
  "pattern": "^([^<>;'=\"]+)+$"
92
- },
93
- "reverse": {
94
- "description": "Define the attribute as bidirectional",
95
- "type": "array",
96
- "items": {
97
- "type": "object",
98
- "additionalProperties": false,
99
- "properties": {
100
- "object_id": {
101
- "description": "ID of the attribute in the device",
102
- "type": "string"
103
- },
104
- "type": {
105
- "description": "Type of the attribute in the target entity",
106
- "type": "string",
107
- "pattern": "^([^<>();'=\"]+)+$"
108
- },
109
- "expression": {
110
- "description": "Optional expression for measurement transformation",
111
- "type": "string"
112
- }
113
- }
114
- }
115
92
  }
116
93
  }
117
94
  }
@@ -169,6 +146,18 @@
169
146
  "payloadType": {
170
147
  "description": "Payload type allowed for measures for this device",
171
148
  "type": "string"
149
+ },
150
+ "useCBflowControl": {
151
+ "description": "use CB flowControl option",
152
+ "type": "boolean"
153
+ },
154
+ "storeLastMeasure": {
155
+ "description": "Store last measure",
156
+ "type": "boolean"
157
+ },
158
+ "lastMeasure": {
159
+ "description": "last measure",
160
+ "type": "object"
172
161
  }
173
162
  }
174
163
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "iotagent-node-lib",
3
3
  "license": "AGPL-3.0-only",
4
4
  "description": "IoT Agent library to interface with NGSI Context Broker",
5
- "version": "4.5.0",
5
+ "version": "4.7.0",
6
6
  "homepage": "https://github.com/telefonicaid/iotagent-node-lib",
7
7
  "keywords": [
8
8
  "fiware",
@@ -44,15 +44,15 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "async": "2.6.4",
47
- "body-parser": "~1.20.0",
48
- "express": "~4.19.2",
47
+ "body-parser": "~1.20.3",
48
+ "express": "~4.21.2",
49
49
  "got": "~11.8.5",
50
50
  "jexl": "2.3.0",
51
51
  "jison": "0.4.18",
52
52
  "logops": "2.1.2",
53
53
  "moment": "~2.29.2",
54
54
  "moment-timezone": "~0.5.34",
55
- "mongoose": "5.13.20",
55
+ "mongoose": "8.9.5",
56
56
  "query-string": "7.1.1",
57
57
  "revalidator": "~0.3.1",
58
58
  "underscore": "~1.13.4",
@@ -69,7 +69,7 @@
69
69
  "husky": "~4.2.5",
70
70
  "lint-staged": "~12.3.8",
71
71
  "mocha": "10.0.0",
72
- "mongodb": "4.17.1",
72
+ "mongodb": "4.17.2",
73
73
  "nock": "13.2.7",
74
74
  "nyc": "~15.1.0",
75
75
  "prettier": "~2.7.1",
@@ -249,7 +249,6 @@ The script implements expression detection and translation in the following fiel
249
249
 
250
250
  - active.expression
251
251
  - active.entity_name
252
- - active.reverse
253
252
  - attributes.expression
254
253
  - attributes.entity_name
255
254
  - attributes.expression
@@ -21,8 +21,10 @@ pattern than the one supported by the test runner).
21
21
  Each test case is defined as a JSON object in the `testCases.js` file. This file is loaded by the test suite and the
22
22
  test cases are automatically generated. Each test case is defined as an object with the following elements:
23
23
 
24
- - `describeName`: The name of the `DESCRIBE` test case. This will be used to generate the test case name in the mocha. Note this name is prefixed by a pure number (e.g `0010 - Simple group without attributes`) which specifies the group to which the test belong (usually meaning a feature) or by a number preced by the `#` symbol to refer to an issue number (e.g. `#1234 - Bug foobar`).
25
- test suite.
24
+ - `describeName`: The name of the `DESCRIBE` test case. This will be used to generate the test case name in the mocha.
25
+ Note this name is prefixed by a pure number (e.g `0010 - Simple group without attributes`) which specifies the group
26
+ to which the test belong (usually meaning a feature) or by a number preced by the `#` symbol to refer to an issue
27
+ number (e.g. `#1234 - Bug foobar`). test suite.
26
28
  - `provision`: The JSON object that will be sent to the IoTA JSON provisioning API. This will be used to create the
27
29
  group. It contains the following elements:
28
30
  - `url`: The URL of the provisioning API (group)
@@ -30,17 +32,19 @@ test cases are automatically generated. Each test case is defined as an object w
30
32
  - `json`: The JSON object that defines the group
31
33
  - `headers`: The headers to send to the provisioning API. This should contain the `fiware-service` and
32
34
  `fiware-servicepath` headers.
33
- - `skip`: optional. Allow to skip test cases (at `describe` level). It allows diferent values: `false` (default, meaning that the test is not skipped in any circustance),
34
- `true` (meaning the test is always skipped), `"lib"` (meaning the test has to be skipped when running it in IoTA Node lib repo) and
35
- `"json"` (meaning the test has to be skipped when running it in IOTA JSON repo). The latter alternatives are useful to skip test cases that are not supported by
36
- the lib (I.E: all tests related to the transport) or by the IOTA. Combinations (e.g `"lib,json"`) and negation (e.g. `"!lib"`) are also supported.
35
+ - `skip`: optional. Allow to skip test cases (at `describe` level). It allows diferent values: `false` (default,
36
+ meaning that the test is not skipped in any circustance), `true` (meaning the test is always skipped), `"lib"`
37
+ (meaning the test has to be skipped when running it in IoTA Node lib repo) and `"json"` (meaning the test has to
38
+ be skipped when running it in IOTA JSON repo). The latter alternatives are useful to skip test cases that are
39
+ not supported by the lib (I.E: all tests related to the transport) or by the IOTA. Combinations (e.g
40
+ `"lib,json"`) and negation (e.g. `"!lib"`) are also supported.
37
41
  - `should`: The array of test cases to execute. Each test case is defined as an object with the following elements:
38
42
  - `transport`: The transport to use to send the measure. This can be `HTTP` or `MQTT`. It uses `HTTP` by default
39
43
  or if the `transport` element is not defined. See the "Advanced features" section for more information.
40
44
  - `shouldName`: The name of the `IT` test case. This will be used to generate the test case name in the mocha test
41
45
  suite.
42
- - `type`: The type of the test case. This can be `single`, `multimeasure` or `multientity`. See the "Advanced features" section
43
- for more information.
46
+ - `type`: The type of the test case. This can be `single`, `multimeasure` or `multientity`. See the "Advanced
47
+ features" section for more information.
44
48
  - `measure`: The JSON object that will be sent to the IoTA JSON measure API. This will be used to send the
45
49
  measure. It contains the following elements:
46
50
  - `url`: The URL of the measure API (group)
@@ -64,10 +68,10 @@ test cases are automatically generated. Each test case is defined as an object w
64
68
  {
65
69
  describeName: 'Basic group provision with attributes',
66
70
  provision: {
67
- url: 'http://localhost:' + config.iota.server.port + '/iot/services',
71
+ url: 'http://localhost:' + config.iota.server.port + '/iot/groups',
68
72
  method: 'POST',
69
73
  json: {
70
- services: [
74
+ groups: [
71
75
  {
72
76
  resource: '/iot/json',
73
77
  apikey: '123456',
@@ -199,11 +203,11 @@ as a batch operation (see the following example).
199
203
 
200
204
  #### Multimeasures
201
205
 
202
- It is also supported to test cases in which is sent more than one measure. To do so, you need to set add to the test case
203
- the parameter `should.type` to the value `'multimeasure'`.
206
+ It is also supported to test cases in which is sent more than one measure. To do so, you need to set add to the test
207
+ case the parameter `should.type` to the value `'multimeasure'`.
204
208
 
205
- You must define the measure as multimeasure. This is done by defining the `measure` JSON element as an array of
206
- objects. I.E:
209
+ You must define the measure as multimeasure. This is done by defining the `measure` JSON element as an array of objects.
210
+ I.E:
207
211
 
208
212
  ```javascript
209
213
  measure: {
@@ -276,8 +280,8 @@ expectation: {
276
280
  }
277
281
  ```
278
282
 
279
- Then, a batch request would be sent to the Context Broker containing the different measures. More information about
280
- how the IoT Agent send multimeasures to the Context Broker [here](/doc/api.md#multimeasure-support).
283
+ Then, a batch request would be sent to the Context Broker containing the different measures. More information about how
284
+ the IoT Agent send multimeasures to the Context Broker [here](/doc/api.md#multimeasure-support).
281
285
 
282
286
  #### Transport
283
287
 
@@ -332,7 +336,8 @@ the expectation as an empty object. I.E:
332
336
  ...
333
337
  ```
334
338
 
335
- Note that this means the CB *must not* receive any payload. In other words, if the CB would receive any payload, the test will fail.
339
+ Note that this means the CB _must not_ receive any payload. In other words, if the CB would receive any payload, the
340
+ test will fail.
336
341
 
337
342
  ### Debugging automated tests
338
343
 
@@ -45,7 +45,7 @@ config.amqp = {
45
45
  };
46
46
 
47
47
  config.iota = {
48
- logLevel: 'FATAL',
48
+ logLevel: 'DEBUG',
49
49
  contextBroker: {
50
50
  host: '192.168.1.1',
51
51
  port: '1026',
@@ -61,7 +61,8 @@ config.iota = {
61
61
  service: 'smartgondor',
62
62
  subservice: '/gardens',
63
63
  providerUrl: 'http://localhost:4041',
64
- types: {}
64
+ types: {},
65
+ useCBflowControl: true
65
66
  };
66
67
 
67
68
  config.defaultKey = '1234';
@@ -63,12 +63,17 @@ describe('FUNCTIONAL TESTS AUTO', function () {
63
63
  if (testCase.loglevel) {
64
64
  logger.setLevel(testCase.loglevel);
65
65
  }
66
- let type = testUtils.groupToIoTAConfigType(
66
+ let confType = testUtils.groupToIoTAConfigType(
67
67
  testCase.provision.json.services[0],
68
- testCase.provision.headers.fiwareService,
69
- testCase.provision.headers.fiwareServicepath
68
+ testCase.provision.headers['fiware-service'],
69
+ testCase.provision.headers['fiware-servicepath']
70
70
  );
71
- config.iota.types[type.name] = type.type;
71
+ // Inject device id into config as real typeInformation
72
+ if (testCase.should[0] && testCase.should[0].measure.qs.i) {
73
+ confType.type['id'] = testCase.should[0].measure.qs.i;
74
+ }
75
+ config.iota.types[confType.name] = confType.type;
76
+
72
77
  iotAgentLib.activate(config.iota, function (error) {
73
78
  done(error);
74
79
  });
@@ -115,8 +115,8 @@ describe('FUNCTIONAL TESTS', function () {
115
115
  beforeEach(function (done) {
116
116
  let type = testUtils.groupToIoTAConfigType(
117
117
  provision.json.services[0],
118
- provision.headers.fiwareService,
119
- provision.headers.fiwareServicepath
118
+ provision.headers['fiware-service'],
119
+ provision.headers['fiware-servicepath']
120
120
  );
121
121
  config.iota.types[type.name] = type.type;
122
122
  iotAgentLib.activate(config.iota, function (error) {
@@ -214,8 +214,8 @@ describe('FUNCTIONAL TESTS', function () {
214
214
  beforeEach(function (done) {
215
215
  let type = testUtils.groupToIoTAConfigType(
216
216
  provision.json.services[0],
217
- provision.headers.fiwareService,
218
- provision.headers.fiwareServicepath
217
+ provision.headers['fiware-service'],
218
+ provision.headers['fiware-servicepath']
219
219
  );
220
220
  config.iota.types[type.name] = type.type;
221
221
  iotAgentLib.activate(config.iota, function (error) {
@@ -513,6 +513,84 @@ const testCases = [
513
513
  }
514
514
  ]
515
515
  },
516
+ {
517
+ describeName: '0021b - Simple group with active attributes with special names in object_id',
518
+ provision: {
519
+ url: 'http://localhost:' + config.iota.server.port + '/iot/services',
520
+ method: 'POST',
521
+ json: {
522
+ services: [
523
+ {
524
+ resource: '/iot/json',
525
+ apikey: globalEnv.apikey,
526
+ entity_type: globalEnv.entity_type,
527
+ commands: [],
528
+ lazy: [],
529
+ attributes: [
530
+ {
531
+ object_id: 'a',
532
+ name: 'attr_a',
533
+ type: 'Boolean',
534
+ metadata: {
535
+ accuracy: {
536
+ value: 0.8,
537
+ type: 'Float'
538
+ }
539
+ }
540
+ },
541
+ {
542
+ object_id: '.1.0.0.1',
543
+ name: 'psBatteryVoltage',
544
+ type: 'Number'
545
+ }
546
+ ],
547
+ static_attributes: []
548
+ }
549
+ ]
550
+ },
551
+ headers: {
552
+ 'fiware-service': globalEnv.service,
553
+ 'fiware-servicepath': globalEnv.servicePath
554
+ }
555
+ },
556
+ should: [
557
+ {
558
+ shouldName:
559
+ 'A - WHEN sending defined object_ids with special format names (measures) through http IT should send measures to Context Broker preserving value types, name mappings and metadatas',
560
+ type: 'single',
561
+ measure: {
562
+ url: 'http://localhost:' + config.http.port + '/iot/json',
563
+ method: 'POST',
564
+ qs: {
565
+ i: globalEnv.deviceId,
566
+ k: globalEnv.apikey
567
+ },
568
+ json: {
569
+ a: false,
570
+ '.1.0.0.1': 23.5
571
+ }
572
+ },
573
+ expectation: {
574
+ id: globalEnv.entity_name,
575
+ type: globalEnv.entity_type,
576
+ attr_a: {
577
+ value: false,
578
+ type: 'Boolean',
579
+ metadata: {
580
+ accuracy: {
581
+ value: 0.8,
582
+ type: 'Float'
583
+ }
584
+ }
585
+ },
586
+ psBatteryVoltage: {
587
+ type: 'Number',
588
+ value: 23.5
589
+ }
590
+ }
591
+ }
592
+ ]
593
+ },
516
594
  {
517
595
  describeName: '0022 - Simple group with active attributes and multimeasures',
518
596
  provision: {
@@ -1690,7 +1768,6 @@ const testCases = [
1690
1768
  },
1691
1769
  {
1692
1770
  describeName: '0170 - Simple group with active attribute + JEXL expression referencing context attributes',
1693
- skip: 'lib', // Explanation in #1523
1694
1771
  provision: {
1695
1772
  url: 'http://localhost:' + config.iota.server.port + '/iot/services',
1696
1773
  method: 'POST',
@@ -1750,9 +1827,101 @@ const testCases = [
1750
1827
  }
1751
1828
  ]
1752
1829
  },
1830
+ {
1831
+ describeName:
1832
+ '0175 - Simple group with active attribute + JEXL expression referencing metadata context attributes',
1833
+ provision: {
1834
+ url: 'http://localhost:' + config.iota.server.port + '/iot/services',
1835
+ method: 'POST',
1836
+ json: {
1837
+ services: [
1838
+ {
1839
+ resource: '/iot/json',
1840
+ apikey: globalEnv.apikey,
1841
+ entity_type: globalEnv.entity_type,
1842
+ commands: [],
1843
+ lazy: [],
1844
+ static_attributes: [
1845
+ {
1846
+ name: 'st_attr1',
1847
+ type: 'Number',
1848
+ value: 1.5,
1849
+ metadata: {
1850
+ coef1: {
1851
+ value: 0.8,
1852
+ type: 'Float'
1853
+ }
1854
+ }
1855
+ },
1856
+ {
1857
+ name: 'st_attr',
1858
+ type: 'Number',
1859
+ value: 1.5,
1860
+ metadata: {
1861
+ coef: {
1862
+ value: 0.8,
1863
+ type: 'Float'
1864
+ }
1865
+ }
1866
+ },
1867
+ {
1868
+ name: 'st_attr2',
1869
+ type: 'Number',
1870
+ value: 1.5,
1871
+ metadata: {
1872
+ coef2: {
1873
+ value: 0.8,
1874
+ type: 'Float'
1875
+ }
1876
+ }
1877
+ }
1878
+ ],
1879
+ attributes: [
1880
+ {
1881
+ object_id: 'a',
1882
+ name: 'attr_a',
1883
+ type: 'Number',
1884
+ expression: 'a*st_attr*metadata.st_attr.coef'
1885
+ }
1886
+ ],
1887
+ explicitAttrs: "['attr_a']"
1888
+ }
1889
+ ]
1890
+ },
1891
+ headers: {
1892
+ 'fiware-service': globalEnv.service,
1893
+ 'fiware-servicepath': globalEnv.servicePath
1894
+ }
1895
+ },
1896
+ should: [
1897
+ {
1898
+ shouldName:
1899
+ 'A - WHEN sending a value (number) through http IT should apply the expression using the context attributes value and send to Context Broker the value "39.60" ',
1900
+ type: 'single',
1901
+ measure: {
1902
+ url: 'http://localhost:' + config.http.port + '/iot/json',
1903
+ method: 'POST',
1904
+ qs: {
1905
+ i: globalEnv.deviceId,
1906
+ k: globalEnv.apikey
1907
+ },
1908
+ json: {
1909
+ a: 33
1910
+ }
1911
+ },
1912
+ expectation: {
1913
+ id: globalEnv.entity_name,
1914
+ type: globalEnv.entity_type,
1915
+ attr_a: {
1916
+ value: 39.6,
1917
+ type: 'Number'
1918
+ }
1919
+ }
1920
+ }
1921
+ ]
1922
+ },
1753
1923
  {
1754
1924
  describeName: '0180 - Simple group with active attributes + JEXL multiples expressions at same time',
1755
- skip: 'lib', // Explanation in #1523
1756
1925
  provision: {
1757
1926
  url: 'http://localhost:' + config.iota.server.port + '/iot/services',
1758
1927
  method: 'POST',
@@ -4125,7 +4294,7 @@ const testCases = [
4125
4294
  type: 'Number',
4126
4295
  entity_name: 'TestType:TestDevice2',
4127
4296
  entity_type: 'TestType',
4128
- expression: 'type+":"+(t*2*static_a)' // Only type is used as JEXL context attr due to #1523
4297
+ expression: 'type+":"+(t*2*static_a)'
4129
4298
  }
4130
4299
  ],
4131
4300
  static_attributes: [
@@ -4211,7 +4380,7 @@ const testCases = [
4211
4380
  object_id: 't',
4212
4381
  name: 'temperature',
4213
4382
  type: 'Number',
4214
- entity_name: 'type+":"+(t*2*static_a)', // Only type is used as JEXL context attr due to #1523
4383
+ entity_name: 'type+":"+(t*2*static_a)',
4215
4384
  entity_type: 'TestType'
4216
4385
  }
4217
4386
  ],
@@ -4483,6 +4652,78 @@ const testCases = [
4483
4652
  }
4484
4653
  }
4485
4654
  ]
4655
+ },
4656
+ // 0900 - JEXL FUNCTION TESTS
4657
+ {
4658
+ describeName: '0900 - JEXL function - valuePicker and valuePickerMulti',
4659
+ provision: {
4660
+ url: 'http://localhost:' + config.iota.server.port + '/iot/services',
4661
+ method: 'POST',
4662
+ json: {
4663
+ services: [
4664
+ {
4665
+ resource: '/iot/json',
4666
+ apikey: globalEnv.apikey,
4667
+ entity_type: globalEnv.entity_type,
4668
+ explicitAttrs: true,
4669
+ commands: [],
4670
+ lazy: [],
4671
+ attributes: [
4672
+ {
4673
+ object_id: 'single',
4674
+ name: 'single',
4675
+ type: 'Number',
4676
+ expression: '{alarm1:alarm1,alarm2:alarm2,alarm3:alarm3}|valuePicker(true)'
4677
+ },
4678
+ {
4679
+ object_id: 'multi',
4680
+ name: 'multi',
4681
+ type: 'Number',
4682
+ expression: "a|valuePickerMulti([true,1,'on','nok'])"
4683
+ }
4684
+ ],
4685
+ static_attributes: []
4686
+ }
4687
+ ]
4688
+ },
4689
+ headers: {
4690
+ 'fiware-service': globalEnv.service,
4691
+ 'fiware-servicepath': globalEnv.servicePath
4692
+ }
4693
+ },
4694
+ should: [
4695
+ {
4696
+ shouldName:
4697
+ 'A - WHEN sending a boolean value (true) through http IT should send to Context Broker the value 3 ',
4698
+ type: 'single',
4699
+ measure: {
4700
+ url: 'http://localhost:' + config.http.port + '/iot/json',
4701
+ method: 'POST',
4702
+ qs: {
4703
+ i: globalEnv.deviceId,
4704
+ k: globalEnv.apikey
4705
+ },
4706
+ json: {
4707
+ a: { n1: true, n2: 1, n3: 'on', n4: 'nok', n5: 'ok', n6: true, n7: false, n8: 0 },
4708
+ alarm1: true,
4709
+ alarm2: false,
4710
+ alarm3: true
4711
+ }
4712
+ },
4713
+ expectation: {
4714
+ id: globalEnv.entity_name,
4715
+ type: globalEnv.entity_type,
4716
+ single: {
4717
+ value: ['alarm1', 'alarm3'],
4718
+ type: 'Number'
4719
+ },
4720
+ multi: {
4721
+ value: ['n1', 'n2', 'n3', 'n4', 'n6'],
4722
+ type: 'Number'
4723
+ }
4724
+ }
4725
+ }
4726
+ ]
4486
4727
  }
4487
4728
  ];
4488
4729
 
@@ -204,9 +204,9 @@ async function testCase(measure, expectation, provision, env, config, type, tran
204
204
  let cbMockRoute = '';
205
205
  // Set the correct route depending if the test is multientity or not
206
206
  if (type === 'multientity' || type === 'multimeasure') {
207
- cbMockRoute = '/v2/op/update';
207
+ cbMockRoute = '/v2/op/update?options=flowControl';
208
208
  } else {
209
- cbMockRoute = '/v2/entities?options=upsert';
209
+ cbMockRoute = '/v2/entities?options=upsert,flowControl';
210
210
  }
211
211
 
212
212
  // Set the correct mock times depending if the test is multimeasure or not
@@ -25,19 +25,7 @@
25
25
  {
26
26
  "name":"location",
27
27
  "type":"geo:point",
28
- "expression": "${latitude}, ${longitude}",
29
- "reverse": [
30
- {
31
- "object_id":"latitude",
32
- "type": "string",
33
- "expression": "${trim(substr(@location, indexOf(@location, \",\") + 1, length(@location)))}"
34
- },
35
- {
36
- "object_id":"longitude",
37
- "type": "string",
38
- "expression": "${trim(substr(@location, 0, indexOf(@location, \",\")))}"
39
- }
40
- ]
28
+ "expression": "${latitude}, ${longitude}"
41
29
  }
42
30
  ],
43
31
  "static_attributes": [],