iotagent-node-lib 3.1.0 → 3.3.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 (163) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +134 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +16 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.yml +55 -0
  4. package/.github/advanced-issue-labeler.yml +30 -0
  5. package/.github/workflows/issue-labeler.yml +43 -0
  6. package/CHANGES_NEXT_RELEASE +0 -2
  7. package/config.js +5 -5
  8. package/doc/api.md +1483 -298
  9. package/doc/deprecated.md +7 -1
  10. package/doc/development.md +120 -0
  11. package/doc/howto.md +58 -62
  12. package/doc/installationguide.md +3 -11
  13. package/doc/requirements.txt +1 -1
  14. package/docker/Mosquitto/Dockerfile +1 -1
  15. package/lib/commonConfig.js +7 -10
  16. package/lib/fiware-iotagent-lib.js +0 -10
  17. package/lib/jexlTranformsMap.js +2 -1
  18. package/lib/model/Device.js +0 -1
  19. package/lib/model/Group.js +0 -1
  20. package/lib/model/dbConn.js +1 -7
  21. package/lib/plugins/bidirectionalData.js +8 -26
  22. package/lib/plugins/expressionPlugin.js +8 -40
  23. package/lib/plugins/jexlParser.js +28 -0
  24. package/lib/services/commands/commandService.js +1 -1
  25. package/lib/services/common/iotManagerService.js +0 -1
  26. package/lib/services/devices/deviceRegistryMongoDB.js +10 -10
  27. package/lib/services/devices/deviceService.js +16 -20
  28. package/lib/services/devices/devices-NGSI-v2.js +2 -5
  29. package/lib/services/ngsi/entities-NGSI-LD.js +16 -60
  30. package/lib/services/ngsi/entities-NGSI-v2.js +179 -119
  31. package/lib/services/northBound/deviceProvisioningServer.js +17 -17
  32. package/lib/templates/createDevice.json +5 -6
  33. package/lib/templates/createDeviceLax.json +6 -8
  34. package/lib/templates/deviceGroup.json +1 -5
  35. package/lib/templates/updateDevice.json +9 -2
  36. package/lib/templates/updateDeviceLax.json +14 -5
  37. package/package.json +1 -1
  38. package/scripts/legacy_expression_tool/README.md +262 -0
  39. package/scripts/legacy_expression_tool/legacy_expression_tool.py +423 -0
  40. package/scripts/legacy_expression_tool/requirements.txt +3 -0
  41. package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +5 -5
  42. package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +4 -4
  43. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +3 -13
  44. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +0 -2
  45. package/test/unit/ngsi-ld/lazyAndCommands/merge-patch-test.js +31 -30
  46. package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +8 -8
  47. package/test/unit/ngsi-ld/plugins/custom-plugin_test.js +152 -0
  48. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +1 -1
  49. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +33 -37
  50. package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +5 -1
  51. package/test/unit/ngsiv2/examples/contextRequests/updateContext.json +2 -0
  52. package/test/unit/ngsiv2/examples/contextRequests/updateContext1.json +3 -1
  53. package/test/unit/ngsiv2/examples/contextRequests/updateContext3WithStatic.json +2 -0
  54. package/test/unit/ngsiv2/examples/contextRequests/updateContext4.json +4 -1
  55. package/test/unit/ngsiv2/examples/contextRequests/updateContext5.json +12 -0
  56. package/test/unit/ngsiv2/examples/contextRequests/updateContext6.json +10 -0
  57. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin1.json +2 -0
  58. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin2.json +3 -1
  59. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin3.json +3 -1
  60. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin4.json +3 -1
  61. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin5.json +3 -1
  62. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin6.json +3 -1
  63. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin7.json +3 -1
  64. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin8.json +3 -1
  65. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin9.json +3 -1
  66. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast1.json +2 -0
  67. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast2.json +2 -0
  68. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast3.json +3 -1
  69. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast4.json +3 -1
  70. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast5.json +3 -1
  71. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast6.json +3 -1
  72. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast7.json +3 -1
  73. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandError.json +3 -1
  74. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandExpired.json +3 -1
  75. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandFinish.json +3 -1
  76. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus.json +2 -0
  77. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +2 -0
  78. package/test/unit/ngsiv2/examples/contextRequests/updateContextCompressTimestamp1.json +3 -1
  79. package/test/unit/ngsiv2/examples/contextRequests/updateContextCompressTimestamp2.json +3 -1
  80. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin1.json +2 -0
  81. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin11.json +2 -0
  82. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin12.json +2 -0
  83. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin13.json +3 -1
  84. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin2.json +2 -0
  85. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin29.json +2 -0
  86. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin3.json +2 -0
  87. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin30.json +2 -0
  88. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin31.json +2 -8
  89. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin32.json +2 -0
  90. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin33.json +2 -0
  91. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin34.json +2 -0
  92. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin35.json +22 -0
  93. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +1 -0
  94. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin4.json +2 -0
  95. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin40.json +42 -0
  96. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin41.json +33 -0
  97. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin5.json +2 -0
  98. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin6.json +2 -0
  99. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin7.json +2 -0
  100. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin8.json +2 -0
  101. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin9.json +2 -0
  102. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionSkip.json +12 -0
  103. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityJexlExpressionPlugin1.json +1 -1
  104. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin1.json +1 -1
  105. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin10.json +1 -1
  106. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin11.json +1 -1
  107. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin12.json +1 -1
  108. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin13.json +1 -1
  109. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin14.json +1 -1
  110. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin15.json +1 -1
  111. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin16.json +1 -1
  112. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +1 -1
  113. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin2.json +1 -1
  114. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin25.json +37 -0
  115. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin3.json +1 -1
  116. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin4.json +1 -1
  117. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin5.json +1 -1
  118. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin6.json +1 -1
  119. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin7.json +1 -1
  120. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin8.json +1 -1
  121. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin9.json +1 -1
  122. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin1.json +1 -1
  123. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +1 -1
  124. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin3.json +1 -1
  125. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin4.json +2 -0
  126. package/test/unit/ngsiv2/examples/contextRequests/updateContextProcessTimestamp.json +2 -0
  127. package/test/unit/ngsiv2/examples/contextRequests/updateContextStaticAttributes.json +2 -0
  128. package/test/unit/ngsiv2/examples/contextRequests/updateContextStaticAttributesMetadata.json +3 -1
  129. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestamp.json +3 -1
  130. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampFalse.json +12 -0
  131. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampFalseTimeInstant.json +12 -0
  132. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampOverride.json +2 -0
  133. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampOverrideWithoutMilis.json +2 -0
  134. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampTimezone.json +3 -1
  135. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +355 -75
  136. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +18 -51
  137. package/test/unit/ngsiv2/general/https-support-test.js +1 -5
  138. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +4 -10
  139. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +9 -26
  140. package/test/unit/ngsiv2/ngsiService/active-devices-test.js +143 -57
  141. package/test/unit/ngsiv2/ngsiService/autocast-test.js +14 -21
  142. package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +3 -5
  143. package/test/unit/ngsiv2/ngsiService/subscriptions-test.js +1 -10
  144. package/test/unit/ngsiv2/plugins/alias-plugin_test.js +20 -30
  145. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +6 -69
  146. package/test/unit/ngsiv2/plugins/compress-timestamp-plugin_test.js +4 -6
  147. package/test/unit/ngsiv2/plugins/custom-plugin_test.js +150 -0
  148. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +87 -16
  149. package/test/unit/ngsiv2/plugins/timestamp-processing-plugin_test.js +2 -3
  150. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +2 -3
  151. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +15 -55
  152. package/test/unit/ngsiv2/provisioning/device-registration_test.js +1 -7
  153. package/test/unit/ngsiv2/provisioning/device-update-registration_test.js +2 -9
  154. package/test/unit/ngsiv2/provisioning/singleConfigurationMode-test.js +0 -11
  155. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +0 -7
  156. package/test/unit/plugins/capture-provision-inPlugins_test.js +0 -6
  157. package/doc/advanced-topics.md +0 -626
  158. package/doc/expressionLanguage.md +0 -762
  159. package/lib/plugins/expressionParser.js +0 -205
  160. package/test/unit/expressions/expression-test.js +0 -197
  161. package/test/unit/ngsi-ld/expressions/expressionBasedTransformations-test.js +0 -882
  162. package/test/unit/ngsiv2/expressions/expressionBasedTransformations-test.js +0 -951
  163. package/test/unit/ngsiv2/expressions/expressionCombinedTransformations-test.js +0 -296
@@ -36,10 +36,6 @@
36
36
  "description": "Transport protocol used by the platform to communicate with the device",
37
37
  "type": "string"
38
38
  },
39
- "expressionLanguage": {
40
- "description": "Expression language used to apply expressions for this device",
41
- "type": "string"
42
- },
43
39
  "explicitAttrs": {
44
40
  "description": "Flag about only provisioned attributes will be processed to Context Broker"
45
41
  },
@@ -102,10 +98,13 @@
102
98
  "description": "Optional expression for measurement transformation",
103
99
  "type": "string"
104
100
  },
101
+ "skipValue": {
102
+ "description": "Attribute is skipped when result of apply expression is this value",
103
+ "type": "any"
104
+ },
105
105
  "entity_name": {
106
106
  "description": "Optional entity name for multientity updates",
107
- "type": "string",
108
- "pattern": "^([^<>;'=\"]+)+$"
107
+ "type": "string"
109
108
  },
110
109
  "entity_type": {
111
110
  "description": "Optional entity type for multientity updatess",
@@ -36,10 +36,6 @@
36
36
  "description": "Transport protocol used by the platform to communicate with the device",
37
37
  "type": "string"
38
38
  },
39
- "expressionLanguage": {
40
- "description": "Expression language used to apply expressions for this device",
41
- "type": "boolean"
42
- },
43
39
  "explicitAttrs": {
44
40
  "description": "Flag about only provisioned attributes will be processed to Context Broker"
45
41
  },
@@ -98,13 +94,15 @@
98
94
  },
99
95
  "expression": {
100
96
  "description": "Optional expression for measurement transformation",
101
- "type": "string",
102
- "pattern": "^([^<>;'=]+)+$"
97
+ "type": "string"
98
+ },
99
+ "skipValue": {
100
+ "description": "Attribute is skipped when result of apply expression is this value",
101
+ "type": "any"
103
102
  },
104
103
  "entity_name": {
105
104
  "description": "Optional entity name for multientity updates",
106
- "type": "string",
107
- "pattern": "^([^<>;'=\"]+)+$"
105
+ "type": "string"
108
106
  },
109
107
  "entity_type": {
110
108
  "description": "Optional entity type for multientity updatess",
@@ -37,10 +37,6 @@
37
37
  "description": "list of lazy attributes of the devices",
38
38
  "type": "array"
39
39
  },
40
- "expressionLanguage": {
41
- "description": "Expression language used to for the group of devices",
42
- "type": "string"
43
- },
44
40
  "ngsiVersion": {
45
41
  "description": "NGSI Interface for this group of devices",
46
42
  "type": "string"
@@ -81,4 +77,4 @@
81
77
  }
82
78
  }
83
79
  }
84
- }
80
+ }
@@ -88,10 +88,13 @@
88
88
  "description": "Optional expression for measurement transformation",
89
89
  "type": "string"
90
90
  },
91
+ "skipValue": {
92
+ "description": "Attribute is skipped when result of apply expression is this value",
93
+ "type": "any"
94
+ },
91
95
  "entity_name": {
92
96
  "description": "Optional entity name for multientity updates",
93
- "type": "string",
94
- "pattern": "^([^<>;'=\"]+)+$"
97
+ "type": "string"
95
98
  },
96
99
  "entity_type": {
97
100
  "description": "Optional entity type for multientity updatess",
@@ -197,6 +200,10 @@
197
200
  "description": "Free form array of data to be appended to the target entity",
198
201
  "type": "array"
199
202
  },
203
+ "timestamp": {
204
+ "description": "Timestamp",
205
+ "type": "boolean"
206
+ },
200
207
  "explicitAttrs": {
201
208
  "description": "Flag to decide update of active attributes only"
202
209
  },
@@ -79,13 +79,11 @@
79
79
  },
80
80
  "expression": {
81
81
  "description": "Optional expression for measurement transformation",
82
- "type": "string",
83
- "pattern": "^([^<>;'=]+)+$"
82
+ "type": "string"
84
83
  },
85
84
  "entity_name": {
86
85
  "description": "Optional entity name for multientity updates",
87
- "type": "string",
88
- "pattern": "^([^<>;'=\"]+)+$"
86
+ "type": "string"
89
87
  },
90
88
  "entity_type": {
91
89
  "description": "Optional entity type for multientity updatess",
@@ -156,6 +154,17 @@
156
154
  "static_attributes": {
157
155
  "description": "Free form array of data to be appended to the target entity",
158
156
  "type": "array"
157
+ },
158
+ "timestamp": {
159
+ "description": "Timestamp",
160
+ "type": "boolean"
161
+ },
162
+ "explicitAttrs": {
163
+ "description": "Flag to decide update of active attributes only"
164
+ },
165
+ "ngsiVersion": {
166
+ "description": "NGSI Interface for this device",
167
+ "type": "string"
159
168
  }
160
169
  }
161
- }
170
+ }
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": "3.1.0",
5
+ "version": "3.3.0",
6
6
  "homepage": "https://github.com/telefonicaid/iotagent-node-lib",
7
7
  "keywords": [
8
8
  "fiware",
@@ -0,0 +1,262 @@
1
+ # Legacy Expression tool
2
+
3
+ With release 3.2.0 of IoT Agent Node lib, the legacy expressions language support has been removed. This folder contains
4
+ the scripts to ease to migrate the legacy expressions.
5
+
6
+ A manual migration is required, because the expressions need to be converted to JEXL expressions manually.
7
+
8
+ This python script will help you to migrate the legacy expressions to JEXL expressions. It will search for the legacy
9
+ expressions in the database and replace them with the new expressions.
10
+
11
+ This script will search for the legacy expressions in the database and replace them with the new expressions. By
12
+ default, it runs in dry-run mode, so database is not modified and the output is a series of files that can be used to
13
+ ease and verify data migration. We you are sure you want to modify the DB, then you have to enable it using the
14
+ `--commit` argument.
15
+
16
+ ## Installation
17
+
18
+ This script requires Python 3 to work (it has been tested with Python 3.9 and 3.10).
19
+
20
+ It is recommended to create virtual env to run this script, installing dependencies on it, this way:
21
+
22
+ ```
23
+ $ virtualenv /path/to/venv
24
+ $ source /path/to/venv/bin/active
25
+ (venv)$ pin install -r requirements.txt
26
+ ```
27
+
28
+ ## Output files
29
+
30
+ The script generates 4 different files each time it is executed:
31
+
32
+ ### `legacy_expression_ocurrences.json`
33
+
34
+ This file contains information about the document where the legacy expressions are found. It contains the following
35
+ information for each legacy expression found:
36
+
37
+ - \_id: The id of the document where the legacy expression is found
38
+ - expression: The legacy expression found
39
+ - type: The type of the property where the legacy expression is found (I.E: active.expression)
40
+ - fiware_service: The fiware service of the document where the legacy expression is found
41
+ - fiware_servicepath: The fiware service path of the document where the legacy expression is found
42
+
43
+ ### `legacy_expression_list.json`
44
+
45
+ This file contains just a list of all the legacy expressions found in the database. It can be used to build the
46
+ translation file. The file looks like this:
47
+
48
+ ```json
49
+ [
50
+ "${legacy-expression-1}",
51
+ "${legacy-expression-2}",
52
+ ...
53
+ "${legacy-expression-n}"
54
+ ]
55
+ ```
56
+
57
+ ### `documents_replaced.json`
58
+
59
+ This file contains a list of documents where the legacy expressions are going to be replaced with all the information
60
+ associated. This file is useful to preview the changes expected to be done in the database before applying them. This
61
+ file is generated every time the script is executed, so no matter if actual changes are going to be done in the DB (i.e.
62
+ --commit is used) or not".
63
+
64
+ ### `documents_backup.json`
65
+
66
+ This file contains a list of documents containing legacy expression that have been backed up. This file is useful to
67
+ preview the changes expected to be done in the database before modifying it. This file is generated every time the
68
+ script is executed, so no matter if actual changes are going to be done in the DB (i.e. --commit is used) or not".
69
+
70
+ ## Command line arguments
71
+
72
+ The script can be executed using the following command:
73
+
74
+ ```bash
75
+ python legacy_expression_tool.py \
76
+ --host <mongodb-host> \
77
+ --port <mongodb-port> \
78
+ --database <mongodb-db> \
79
+ --collection <mongodb-collection> \
80
+ --translation <translation-file>
81
+ ```
82
+
83
+ The list of possible arguments that the scripts accepts are:
84
+
85
+ | Argument | Description | Default value | Mandatory |
86
+ | ---------------------- | -------------------------------------------------------------------------------------------------------- | ---------------------------- | --------- |
87
+ | `--mongouri` | The MongoDB URI to connect to | `mongodb://localhost:27017/` | No |
88
+ | `--database` | The database name to replace the expressions | NA | Yes |
89
+ | `--collection` | The collection name to replace the expressions | NA | Yes |
90
+ | `--translation` | The translation dictionary file to replace the expressions | `translation.json` | No |
91
+ | `--debug` | Enable debug mode | `False` | No |
92
+ | `--commit` | Commit the changes to the database | `False` | No |
93
+ | `--expressionlanguage` | What to do with the expression language field. Possibles values: `delete`, `ignore`, `jexl` or `jexlall`. More detail on this bellow. | `ignore` | No |
94
+ | `--statistics` | Print match statistics. Aggregation modes are the possible values: `service` and `subservice` | `service` | No |
95
+ | `--service` | The fiware service filter to replace the expressions | All subservices | No |
96
+ | `--service-path` | The fiware service path filter to replace the expressions | All subservices | No |
97
+ | `--deviceid` | The device id filter to replace the expressions | All devices | No |
98
+ | `--entitytype` | The entity type filter to replace the expressions | All entity types | No |
99
+ | `--regexservice` | The fiware service regex filter to replace the expressions | All subservices | No |
100
+ | `--regexservicepath` | The fiware service path regex filter to replace the expressions | All subservices | No |
101
+ | `--regexdeviceid` | The device id regex filter to replace the expressions | All devices | No |
102
+ | `--regexentitytype` | The entity type regex filter to replace the expressions | All entity types | No |
103
+
104
+ Note that filters (`--service`, `--service-path`, `--deviceid` and `--entitytype`, and the regex versions) are
105
+ interpreted in additive way (i.e. like a logical AND).
106
+
107
+ With regards to `--expressionlanguage`:
108
+
109
+ * `delete`: changes expressions from legacy to JEXL equivalence in the [fields where expressions may be used](#fields-in-which-expressions-may-be-used) (based on the translation dictionary specified by `--translations`). In addition, deletes the `expressionLanguage` field (no matter its value) in the case it exists in the group/device.
110
+ * `ignore`: changes expressions from legacy to JEXL equivalence in the [fields where expressions may be used](#fields-in-which-expressions-may-be-used) (based on the translation dictionary specified by `--translations`). In addition, it leaves untouched the `expressionLanguage` field. This may cause inconsistencies, if the value of the `expressionLanguage` is `legacy`, as detailed [in this section](#replacing-expression-without-setting-jexl-at-group-or-device-level).
111
+ * `jexl`: changes expressions from legacy to JEXL equivalence in the [fields where expressions may be used](#fields-in-which-expressions-may-be-used) (based on the translation dictionary specified by `--translations`). In addition, it set `expressionLanguage` field to `jexl` (no matter if the field originally exists in the group/device or not) **if some JEXL expression were translated**.
112
+ * `jexlall`: changes expression from legacy to JEXL equivalence in the [fields where expressions may be used](#fields-in-which-expressions-may-be-used) (based on the translation dictionary specified by `--translations`). In addition, it set `expressionLanguage` field to `jexl` (no matter if the field originally exists in the group/device or not). The difference between `jexl`and `jexlall` is in the second case, the script is not only looking for documents that contains legacy expressions, it also includes all groups/devices that have `expressionLanguage` field defined. The `expressionLanguage` field on those documents (and also on the documents that contains legacy expresions) is set to `jexl`.
113
+
114
+ ## Usage
115
+
116
+ ### Getting legacy expressions matches
117
+
118
+ The recommended way to use the script is to execute it in first stage without passing the commit parameter. This will
119
+ generate the file [`legacy_expression_list.json`](#legacy_expression_listjson) containing all the legacy expressions
120
+ found in the database. Then, you can use this file to build the translation file.
121
+
122
+ ```bash
123
+ python legacy_expression_tool.py \
124
+ --host <mongodb-host> \
125
+ --port <mongodb-port> \
126
+ --database <mongodb-db> \
127
+ --collection <mongodb-collection>
128
+ ```
129
+
130
+ This will generate 4 files. At this point, the most relevants are
131
+ [`legacy_expression_list.json`](#legacy_expression_listjson) and
132
+ [`legacy_expression_ocurrences.json`](#legacy_expression_ocurrencesjson). The first one contains a list of all the
133
+ legacy expressions found in the database. The second one contains information about the documents where the legacy
134
+ expressions are found.
135
+
136
+ ## Generating translation file
137
+
138
+ It is needed to provide a translation file that contains the legacy expressions and the new JEXL expressions to replace
139
+ them. This is a json file containing an double dimensional array, having the following format:
140
+
141
+ ```json
142
+ [
143
+ [
144
+ "legacy-expression-1",
145
+ "legacy-expression-2",
146
+ ...
147
+ "legacy-expression-n"
148
+ ],
149
+ [
150
+ "jexl-expression-1",
151
+ "jexl-expression-2",
152
+ ...
153
+ "jexl-expression-n"
154
+ ]
155
+ ]
156
+ ```
157
+
158
+ To ease the migration, you can copy the file [`legacy_expression_list.json`](#legacy_expression_listjson) generated in
159
+ previous step and manualy translate the legacy expressions to JEXL expressions. This should be done in the second array
160
+ of the double dimensional array. The first array should contain the legacy expressions. This mechanism allows to verify
161
+ that the legacy expressions are replaced correctly.
162
+
163
+ For more information about JEXL expression language you can check the [official documentation](FIXME) and the
164
+ [IoT Agent expression language documentation](../doc/api.md#expression-language-support). You can also check the
165
+ [legacy expression language documentation](https://github.com/telefonicaid/iotagent-node-lib/blob/3.1.0/doc/expressionLanguage.md#legacy-expression-language-transformations)
166
+ (deprecated).
167
+
168
+ ### Verifying replacements
169
+
170
+ Once you have the translation file, you can execute the script without passing the commit parameter. This might be
171
+ helpful to check if the translation file is correct through the output files `documents_replaced.json` and
172
+ `documents_backup.json`. You can run the script using the following command:
173
+
174
+ ```bash
175
+ python legacy_expression_tool.py \
176
+ --host <mongodb-host> \
177
+ --port <mongodb-port> \
178
+ --database <mongodb-db> \
179
+ --collection <mongodb-collection> \
180
+ --translation <translation-file>
181
+ ```
182
+
183
+ In order to ensure that the replacement would work you have to consider:
184
+
185
+ - You didn't get an error while executing. If any expression is not found in the database, the script will raise an
186
+ error `ERROR: Expression not found in translation file: ${@myexpre*100} in document: 123481a8ac03ab212ab9e0c`. Note
187
+ that the script doesn't stop on error (if `--commit` is enabled, the expressions found in the translation file are
188
+ translated, remaining in the DB only the ones that result in an error like this, a next pass should be done one the
189
+ missing expression gets added to the translation document).
190
+
191
+ - Comparing files `documents_replaced.json` and `documents_backup.json`. The first one contains the documents where
192
+ the legacy expressions have been replaced with all the information associated. The second one contains a list of
193
+ documents containing legacy expression that have been backed up. You can compare the files using the following
194
+ command:
195
+
196
+ ```bash
197
+ diff documents_replaced.json documents_backup.json
198
+ ```
199
+
200
+ ### Executing the replacement in the database
201
+
202
+ If everithing is correct, you can execute the script passing the commit parameter to apply the changes to the database.
203
+ You only have to provide the `--commit` parameter to the previous command:
204
+
205
+ ```bash
206
+ python legacy_expression_tool.py \
207
+ --host <mongodb-host> \
208
+ --port <mongodb-port> \
209
+ --database <mongodb-db> \
210
+ --collection <mongodb-collection> \
211
+ --translation <translation-file> \
212
+ --commit
213
+ ```
214
+
215
+ ### Output statistics
216
+
217
+ When the script is executed, it prints some statistics about the matches found. This statistics can be printed filtered
218
+ by service or subservice. By default, no statistics are printed. You can change it using the `--statistics` plus the
219
+ aggregation mode. The possible values are `service` and `subservice`.
220
+
221
+ ```bash
222
+ Found 2 legacy expressions in 2 documents
223
+ _id
224
+ service service1 service2 All
225
+ expression
226
+ ${@value*100/total} 1 1 2
227
+ All 1 1 2
228
+ ```
229
+
230
+ ### Fields in which expressions may be used
231
+
232
+ The script implements expression detection and translation in the following fields in group/device documents at DB:
233
+
234
+ * active.expression
235
+ * active.entity_name
236
+ * active.reverse
237
+ * attributes.expression
238
+ * attributes.entity_name
239
+ * attributes.expression
240
+ * commands.expression
241
+ * endpoint
242
+ * entityNameExp
243
+ * explicitAttrs
244
+
245
+ ### Known issues
246
+
247
+ #### Execution with `expressionlanguage` set to `jexlall`
248
+
249
+ When executing the script with `expressionlanguage` set to `jexlall`, the script will look for all the documents
250
+ containing legacy expressions (in some of the [expression capable fields](#fields-in-which-expressions-may-be-used)) or the existence of the `expressionLanguage` field.
251
+ This would change the number of documents found, and the statistics will include extra documents.
252
+
253
+ Running the script with the option set to `jexl` would not include such extra documents in statistics.
254
+
255
+ #### Replacing expression without setting jexl at group or device level
256
+
257
+ When executing the script setting `--expressionlanguage` to `ignore` (or when `--expressionlanguage` is not used), the script will not
258
+ change the`expressionLanguage` field in the document. This means that the legacy expressions will be replaced, but the
259
+ `expressionLanguage` field will still be set to the default value or legacy. This would make expression evaluation to
260
+ fail, propagating the value of the attribute as the expression literal to the context broker.
261
+
262
+ To avoid this, it is recommended use always the `--expressionlangauge` parameter set to `jexl`, so doing it a value different from `ignore` will be used.