iotagent-node-lib 4.8.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +4 -1
- package/.nyc_output/e4b1fe20-197e-4221-9f8d-6db65ff234b2.json +1 -0
- package/.nyc_output/processinfo/e4b1fe20-197e-4221-9f8d-6db65ff234b2.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/Changelog +785 -0
- package/doc/admin.md +8 -4
- package/doc/api.md +1 -1
- package/lib/commonConfig.js +11 -2
- package/lib/services/common/domain.js +4 -3
- package/lib/services/devices/devices-NGSI-LD.js +1 -2
- package/lib/services/devices/devices-NGSI-v2.js +1 -2
- package/lib/services/ngsi/entities-NGSI-LD.js +69 -13
- package/lib/services/ngsi/ngsiService.js +3 -1
- package/lib/services/northBound/contextServer-NGSI-LD.js +5 -3
- package/lib/services/northBound/northboundServer.js +1 -1
- package/lib/services/northBound/restUtils.js +6 -2
- package/package.json +1 -1
- package/test/functional/config-test.js +1 -1
- package/test/unit/ngsi-ld/examples/contextRequests/createDatetimeProvisionedDevice.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDevice.json +3 -12
- package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceMultientity.json +3 -12
- package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceWithGroupAndStatic.json +6 -24
- package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceWithGroupAndStatic2.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContext1.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContext3WithStatic.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContext4.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContext5.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin6.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin7.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin8.json +4 -2
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin9.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandError.json +3 -9
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandExpired.json +13 -19
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandFinish.json +13 -19
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandStatus1.json +4 -9
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextCompressTimestamp1.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextCompressTimestamp2.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin4.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin4a.json +3 -12
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin6.json +3 -5
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin7.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin8a.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextJsonProperty.json +13 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextListProperty.json +14 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextListRelationship.json +14 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin2.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin3.json +3 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin1.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin3.json +1 -4
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin4.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextRelationship.json +11 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextValueType1.json +51 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextValueType2.json +65 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextVocabProperty.json +11 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateProvisionCommands1.json +2 -8
- package/test/unit/ngsi-ld/examples/contextRequests/updateProvisionDeviceStatic.json +1 -4
- package/test/unit/ngsi-ld/general/startup-test.js +3 -0
- package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +1 -1
- package/test/unit/ngsi-ld/lazyAndCommands/lazy-devices-test.js +71 -1
- package/test/unit/ngsi-ld/ngsiService/attributeTypes-test.js +293 -0
- package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +0 -10
- package/test/unit/ngsi-ld/ngsiService/value-types-test.js +221 -0
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast1.json +0 -11
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast10.json +0 -14
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast2.json +0 -11
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast3.json +0 -11
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast4.json +0 -11
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast5.json +0 -7
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast6.json +0 -17
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast7.json +0 -19
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast8.json +0 -14
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast9.json +0 -14
- package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +0 -109
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast1.json +0 -8
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast2.json +0 -8
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast3.json +0 -8
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast4.json +0 -8
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast5.json +0 -8
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast6.json +0 -8
- package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast7.json +0 -8
- /package/test/unit/ngsi-ld/examples/contextRequests/{updateContextLanguageProperties1.json → updateContextLanguageProperty.json} +0 -0
package/doc/admin.md
CHANGED
|
@@ -145,7 +145,8 @@ used by default. E.g.:
|
|
|
145
145
|
When connected to an **NGSI-LD** context broker, an IoT Agent is able to indicate whether it is willing to accept `null`
|
|
146
146
|
values and also whether it is able to process the **NGSI-LD** `datasetId` metadata element. Setting these values to
|
|
147
147
|
`false` will cause the IoT Agent to return a 400 **Bad Request** HTTP status code explaining that the IoT Agent does not
|
|
148
|
-
support nulls or multi-attribute requests if they are encountered.
|
|
148
|
+
support nulls or multi-attribute requests if they are encountered. It is also possible to pass on attribute datatypes
|
|
149
|
+
using `@type` or `valueType` if desired.
|
|
149
150
|
|
|
150
151
|
```javascript
|
|
151
152
|
{
|
|
@@ -153,7 +154,8 @@ support nulls or multi-attribute requests if they are encountered.
|
|
|
153
154
|
port: 4041,
|
|
154
155
|
ldSupport : {
|
|
155
156
|
null: true,
|
|
156
|
-
datasetId: true
|
|
157
|
+
datasetId: true,
|
|
158
|
+
datatype: 'valueType'
|
|
157
159
|
}
|
|
158
160
|
}
|
|
159
161
|
```
|
|
@@ -446,8 +448,9 @@ For example in a device document stored in MongoDB will be extended with a subdo
|
|
|
446
448
|
|
|
447
449
|
#### `useCBflowControl`
|
|
448
450
|
|
|
449
|
-
If this flag is activated, when iotAgent invokes Context Broker will use
|
|
450
|
-
|
|
451
|
+
If this flag is activated, when iotAgent invokes Context Broker will use
|
|
452
|
+
[flowControl option](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/admin/perf_tuning.md#updates-flow-control-mechanism).
|
|
453
|
+
This flag is overwritten by `useCBflowControl` flag in group or device. This flag is disabled by default.
|
|
451
454
|
|
|
452
455
|
### Configuration using environment variables
|
|
453
456
|
|
|
@@ -465,6 +468,7 @@ overrides.
|
|
|
465
468
|
| IOTA_CB_NGSI_VERSION | `contextBroker.ngsiVersion` |
|
|
466
469
|
| IOTA_NORTH_HOST | `server.host` |
|
|
467
470
|
| IOTA_NORTH_PORT | `server.port` |
|
|
471
|
+
| IOTA_LD_SUPPORT_DATA_TYPE | `server.ldSupport.datatype` |
|
|
468
472
|
| IOTA_LD_SUPPORT_NULL | `server.ldSupport.null` |
|
|
469
473
|
| IOTA_LD_SUPPORT_DATASET_ID | `server.ldSupport.datasetId` |
|
|
470
474
|
| IOTA_PROVIDER_URL | `providerUrl` |
|
package/doc/api.md
CHANGED
|
@@ -2463,4 +2463,4 @@ updateEntityRequestsError 5
|
|
|
2463
2463
|
[18]:
|
|
2464
2464
|
https://czosel.github.io/jexl-playground/#/?context=%7B%0A%20%20%22value%22%20%3A%206%2C%0A%20%20%22ts%22%3A%201637245214901%2C%0A%20%22name%22%3A%20%22DevId629%22%2C%0A%20%22object%22%3A%7Bname%3A%20%22John%22%2C%20surname%3A%20%22Doe%22%7D%2C%0A%20%20%22array%22%3A%5B1%2C3%5D%0A%7D&input=name%7Csubstr(0%2Cname%7CindexOf(%22e%22)%2B1)&transforms=%7B%0A%20%20%20%20jsonparse%3A%20(str)%20%3D%3E%20JSON.parse(str)%2C%0A%20%20%20%20jsonstringify%3A%20(obj)%20%3D%3E%20JSON.stringify(obj)%2C%0A%20%20%20%20indexOf%3A%20(val%2C%20char)%20%3D%3E%20String(val).indexOf(char)%2C%0A%20%20%20%20length%3A%20(val)%20%3D%3E%20String(val).length%2C%0A%20%20%20%20trim%3A%20(val)%20%3D%3E%20String(val).trim()%2C%0A%20%20%20%20substr%3A%20(val%2C%20int1%2C%20int2)%20%3D%3E%20String(val).substr(int1%2C%20int2)%2C%0A%20%20%20%20addreduce%3A%20(arr)%20%3D%3E%20arr.reduce((i%2C%20v)%20%3D%3E%20i%20%2B%20v)%2C%0A%20%20%20%20lengtharray%3A%20(arr)%20%3D%3E%20arr.length%2C%0A%20%20%20%20typeof%3A%20(val)%20%3D%3E%20typeof%20val%2C%0A%20%20%20%20isarray%3A%20(arr)%20%3D%3E%20Array.isArray(arr)%2C%0A%20%20%20%20isnan%3A%20(val)%20%3D%3E%20isNaN(val)%2C%0A%20%20%20%20parseint%3A%20(val)%20%3D%3E%20parseInt(val)%2C%0A%20%20%20%20parsefloat%3A%20(val)%20%3D%3E%20parseFloat(val)%2C%0A%20%20%20%20toisodate%3A%20(val)%20%3D%3E%20new%20Date(val).toISOString()%2C%0A%20%20%20%20timeoffset%3A%20(isostr)%20%3D%3E%20new%20Date(isostr).getTimezoneOffset()%2C%0A%20%20%20%20tostring%3A%20(val)%20%3D%3E%20val.toString()%2C%0A%20%20%20%20urlencode%3A%20(val)%20%3D%3E%20encodeURI(val)%2C%0A%20%20%20%20urldecode%3A%20(val)%20%3D%3E%20decodeURI(val)%2C%0A%20%20%20%20replacestr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replace(from%2C%20to)%2C%0A%20%20%20%20replaceregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg)%2C%20to)%2C%0A%20%20%20%20replaceallstr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replaceAll(from%2C%20to)%2C%0A%20%20%20%20replaceallregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replaceAll(new%20RegExp(reg%2C%20'g')%2C%20to)%2C%0A%20%20%20%20split%3A%20(str%2C%20ch)%20%3D%3E%20str.split(ch)%2C%0A%20%20%20%20mapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%20choices%5Bvalues.findIndex((target)%20%3D%3E%20target%20%3D%3D%3D%20val)%5D%2C%0A%20%20%20%20thmapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%0A%20%20%20%20%20%20%20%20choices%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20values.reduce((acc%2C%20curr%2C%20i)%20%3D%3E%20(acc%20%3D%3D%3D%200%20%7C%7C%20acc%20%3F%20acc%20%3A%20val%20%3C%3D%20curr%20%3F%20(acc%20%3D%20i)%20%3A%20(acc%20%3D%20null))%2C%20null)%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20bitwisemask%3A%20(i%2C%20mask%2C%20op%2C%20shf)%20%3D%3E%0A%20%20%20%20%20%20%20%20(op%20%3D%3D%3D%20'%26'%20%3F%20parseInt(i)%20%26%20mask%20%3A%20op%20%3D%3D%3D%20'%7C'%20%3F%20parseInt(i)%20%7C%20mask%20%3A%20op%20%3D%3D%3D%20'%5E'%20%3F%20parseInt(i)%20%5E%20mask%20%3A%20i)%20%3E%3E%0A%20%20%20%20%20%20%20%20shf%2C%0A%20%20%20%20slice%3A%20(arr%2C%20init%2C%20end)%20%3D%3E%20arr.slice(init%2C%20end)%0A%7D
|
|
2465
2465
|
[99]:
|
|
2466
|
-
https://czosel.github.io/jexl-playground/#/?context=%7B%0A%20%20%22text%22%20%3A%20%22%20%20foobar%7B%7D%20%20%22%0A%7D&input=text%20%7C%20replacestr(%22foo%22%2C%22FOO%22)%7Ctrim%7Curlencode&transforms=%7B%0A%20%20%20%20jsonparse%3A%20(str)%20%3D%3E%20JSON.parse(str)%2C%0A%20%20%20%20jsonstringify%3A%20(obj)%20%3D%3E%20JSON.stringify(obj)%2C%0A%20%20%20%20indexOf%3A%20(val%2C%20char)%20%3D%3E%20String(val).indexOf(char)%2C%0A%20%20%20%20length%3A%20(val)%20%3D%3E%20String(val).length%2C%0A%20%20%20%20trim%3A%20(val)%20%3D%3E%20String(val).trim()%2C%0A%20%20%20%20substr%3A%20(val%2C%20int1%2C%20int2)%20%3D%3E%20String(val).substr(int1%2C%20int2)%2C%0A%20%20%20%20addreduce%3A%20(arr)%20%3D%3E%20arr.reduce((i%2C%20v)%20%3D%3E%20i%20%2B%20v)%2C%0A%20%20%20%20lengtharray%3A%20(arr)%20%3D%3E%20arr.length%2C%0A%20%20%20%20typeof%3A%20(val)%20%3D%3E%20typeof%20val%2C%0A%20%20%20%20isarray%3A%20(arr)%20%3D%3E%20Array.isArray(arr)%2C%0A%20%20%20%20isnan%3A%20(val)%20%3D%3E%20isNaN(val)%2C%0A%20%20%20%20parseint%3A%20(val)%20%3D%3E%20parseInt(val)%2C%0A%20%20%20%20parsefloat%3A%20(val)%20%3D%3E%20parseFloat(val)%2C%0A%20%20%20%20toisodate%3A%20(val)%20%3D%3E%20new%20Date(val).toISOString()%2C%0A%20%20%20%20timeoffset%3A%20(isostr)%20%3D%3E%20new%20Date(isostr).getTimezoneOffset()%2C%0A%20%20%20%20tostring%3A%20(val)%20%3D%3E%20val.toString()%2C%0A%20%20%20%20urlencode%3A%20(val)%20%3D%3E%20encodeURI(val)%2C%0A%20%20%20%20urldecode%3A%20(val)%20%3D%3E%20decodeURI(val)%2C%0A%20%20%20%20replacestr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replace(from%2C%20to)%2C%0A%20%20%20%20replaceregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg)%2C%20to)%2C%0A%20%20%20%20replaceallstr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replaceAll(from%2C%20to)%2C%0A%20%20%20%20replaceallregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replaceAll(new%20RegExp(reg%2C%20'g')%2C%20to)%2C%0A%20%20%20%20split%3A%20(str%2C%20ch)%20%3D%3E%20str.split(ch)%2C%0A%20%20%20%20joinarrtostr%3A%20(arr%2C%20ch)%20%3D%3E%20arr.join(ch)%2C%0A%20%20%20%20concatarr%3A%20(arr%2C%20arr2)%20%3D%3E%20arr.concat(arr2)%2C%0A%20%20%20%20mapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%20choices%5Bvalues.findIndex((target)%20%3D%3E%20target%20%3D%3D%3D%20val)%5D%2C%0A%20%20%20%20thmapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%0A%20%20%20%20%20%20%20%20choices%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20values.reduce((acc%2C%20curr%2C%20i)%20%3D%3E%20(acc%20%3D%3D%3D%200%20%7C%7C%20acc%20%3F%20acc%20%3A%20val%20%3C%3D%20curr%20%3F%20(acc%20%3D%20i)%20%3A%20(acc%20%3D%20null))%2C%20null)%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20bitwisemask%3A%20(i%2C%20mask%2C%20op%2C%20shf)%20%3D%3E%0A%20%20%20%20%20%20%20%20(op%20%3D%3D%3D%20'%26'%20%3F%20parseInt(i)%20%26%20mask%20%3A%20op%20%3D%3D%3D%20'%7C'%20%3F%20parseInt(i)%20%7C%20mask%20%3A%20op%20%3D%3D%3D%20'%5E'%20%3F%20parseInt(i)%20%5E%20mask%20%3A%20i)%20%3E%3E%0A%20%20%20%20%20%20%20%20shf%2C%0A%20%20%20%20slice%3A%20(arr%2C%20init%2C%20end)%20%3D%3E%20arr.slice(init%2C%20end)%2C%0A%20%20%20%20addset%3A%20(arr%2C%20x)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20return%20Array.from(new%20Set(arr).add(x))%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20removeset%3A%20(arr%2C%20x)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20let%20s%20%3D%20new%20Set(arr)%3B%0A%20%20%20%20%20%20%20%20s.delete(x)%3B%0A%20%20%20%20%20%20%20%20return%20Array.from(s)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20touppercase%3A%20(val)%20%3D%3E%20String(val).toUpperCase()%2C%0A%20%20%20%20tolowercase%3A%20(val)%20%3D%3E%20String(val).toLowerCase()%2C%0A%20%20%20%20floor%3A%20(val)%20%3D%3E%20Math.floor(val)%2C%0A%20%20%20%20ceil%3A%20(val)%20%3D%3E%20Math.ceil(val)%2C%0A%20%20%20%20round%3A%20(val)%20%3D%3E%20Math.round(val)%2C%0A%20%20%20%20tofixed%3A%20(val%2C%20decimals)%20%3D%3E%20Number.parseFloat(val).toFixed(decimals)%2C%0A%20%20%20%20gettime%3A%20(d)%20%3D%3E%20new%20Date(d).getTime()%2C%0A%20%20%20%20toisostring%3A%20(d)%20%3D%3E%20new%20Date(d).toISOString()%2C%0A%20%20%20%20%2F%2F%20https%3A%2F%2Fdeveloper.mozilla.org%2Fes%2Fdocs%2FWeb%2FJavaScript%2FReference%2FGlobal_Objects%2FDate%2FtoLocaleString%0A%20%20%20%20localestring%3A%20(d%2C%20timezone%2C%20options)%20%3D%3E%20new%20Date(d).toLocaleString(timezone%2C%20options)%2C%0A%20%20%20%20now%3A%20()%20%3D%3E%20Date.now()%2C%0A%20%20%20%20hextostring%3A%20(val)%20%3D%3E%0A%20%20%20%20%20%20%20%20new%20TextDecoder().decode(new%20Uint8Array(val.match(%2F.%7B1%2C2%7D%2Fg).map((byte)%20%3D%3E%20parseInt(byte%2C%2016))))%2C%0A%20%20%20%20valuePicker%3A%20(val%2Cpick)%20%3D%3E%20Object.entries(val).filter((%5B%2C%20v%5D)%20%3D%3E%20v%20%3D%3D%3D%20pick).map((%5Bk%2C%5D)%20%3D%3E%20k)%2C%0A%20%20%20%20valuePickerMulti%3A%20(val%2Cpick)%20%3D%3E%20Object.entries(val).filter((%5B%2C%20v%5D)%20%3D%3E%20pick.includes(v)).map((%5Bk%2C%5D)%20%3D%3E%20k)%0A%7D
|
|
2466
|
+
https://czosel.github.io/jexl-playground/#/?context=%7B%0A%20%20%22text%22%20%3A%20%22%20%20foobar%7B%7D%20%20%22%0A%7D&input=text%20%7C%20replacestr(%22foo%22%2C%22FOO%22)%7Ctrim%7Curlencode&transforms=%20%7B%0A%20%20%20%20jsonparse%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation(JSON.parse)(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20jsonstringify%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation(JSON.stringify)(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20indexOf%3A%20(val%2C%20char)%20%3D%3E%20String(val).indexOf(char)%2C%0A%20%20%20%20length%3A%20(val)%20%3D%3E%20String(val).length%2C%0A%20%20%20%20trim%3A%20(val)%20%3D%3E%20String(val).trim()%2C%0A%20%20%20%20substr%3A%20(val%2C%20int1%2C%20int2)%20%3D%3E%20String(val).substr(int1%2C%20int2)%2C%0A%20%20%20%20addreduce%3A%20(arr)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation((arr)%20%3D%3E%20arr.reduce((i%2C%20v)%20%3D%3E%20i%20%2B%20v))(arr)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20lengtharray%3A%20(arr)%20%3D%3E%20arr.length%2C%0A%20%20%20%20typeof%3A%20(val)%20%3D%3E%20typeof%20val%2C%0A%20%20%20%20isarray%3A%20Array.isArray%2C%0A%20%20%20%20isnan%3A%20isNaN%2C%0A%20%20%20%20parseint%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeParseNumber%20%3D%20(fn)%20%3D%3E%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20%3D%20fn(val)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN(result)%20%3F%20null%20%3A%20result%3B%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeParseNumber((val)%20%3D%3E%20parseInt(val%2C%2010))(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20parsefloat%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeParseNumber%20%3D%20(fn)%20%3D%3E%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20result%20%3D%20fn(val)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN(result)%20%3F%20null%20%3A%20result%3B%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeParseNumber(parseFloat)(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20toisodate%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeDateOperation%20%3D%20(fn)%20%3D%3E%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20date%20%3D%20new%20Date(val)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN(date.getTime())%20%3F%20null%20%3A%20fn(date)%3B%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeDateOperation((date)%20%3D%3E%20date.toISOString())(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20timeoffset%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeDateOperation%20%3D%20(fn)%20%3D%3E%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20date%20%3D%20new%20Date(val)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN(date.getTime())%20%3F%20null%20%3A%20fn(date)%3B%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeDateOperation((date)%20%3D%3E%20date.getTimezoneOffset())(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20tostring%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation((val)%20%3D%3E%20val.toString())(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20urlencode%3A%20encodeURI%2C%0A%20%20%20%20urldecode%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation(decodeURI)(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20replacestr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replace(from%2C%20to)%2C%0A%20%20%20%20replaceregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation((str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg)%2C%20to))(str%2C%20reg%2C%20to)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20replaceallregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation((str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg%2C%20'g')%2C%20to))(str%2C%20reg%2C%20to)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20split%3A%20(str%2C%20ch)%20%3D%3E%20str.split(ch)%2C%0A%20%20%20%20joinarrtostr%3A%20(arr%2C%20ch)%20%3D%3E%20arr.join(ch)%2C%0A%20%20%20%20concatarr%3A%20(arr%2C%20arr2)%20%3D%3E%20arr.concat(arr2)%2C%0A%20%20%20%20mapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%20choices%5Bvalues.findIndex((target)%20%3D%3E%20target%20%3D%3D%3D%20val)%5D%2C%0A%20%20%20%20thmapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%0A%20%20%20%20%20%20%20%20choices%5Bvalues.reduce((acc%2C%20curr%2C%20i)%20%3D%3E%20(acc%20!%3D%3D%20null%20%3F%20acc%20%3A%20val%20%3C%3D%20curr%20%3F%20i%20%3A%20null)%2C%20null)%5D%2C%0A%20%20%20%20bitwisemask%3A%20(i%2C%20mask%2C%20op%2C%20shf)%20%3D%3E%0A%20%20%20%20%20%20%20%20(op%20%3D%3D%3D%20'%26'%20%3F%20parseInt(i)%20%26%20mask%20%3A%20op%20%3D%3D%3D%20'%7C'%20%3F%20parseInt(i)%20%7C%20mask%20%3A%20op%20%3D%3D%3D%20'%5E'%20%3F%20parseInt(i)%20%5E%20mask%20%3A%20i)%20%3E%3E%0A%20%20%20%20%20%20%20%20shf%2C%0A%20%20%20%20slice%3A%20(arr%2C%20init%2C%20end)%20%3D%3E%20arr.slice(init%2C%20end)%2C%0A%20%20%20%20addset%3A%20(arr%2C%20x)%20%3D%3E%20Array.from(new%20Set(arr).add(x))%2C%0A%20%20%20%20removeset%3A%20(arr%2C%20x)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20s%20%3D%20new%20Set(arr)%3B%0A%20%20%20%20%20%20%20%20s.delete(x)%3B%0A%20%20%20%20%20%20%20%20return%20Array.from(s)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20touppercase%3A%20(val)%20%3D%3E%20String(val).toUpperCase()%2C%0A%20%20%20%20tolowercase%3A%20(val)%20%3D%3E%20String(val).toLowerCase()%2C%0A%20%20%20%20floor%3A%20Math.floor%2C%0A%20%20%20%20ceil%3A%20Math.ceil%2C%0A%20%20%20%20round%3A%20Math.round%2C%0A%20%20%20%20tofixed%3A%20(val%2C%20decimals)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20num%20%3D%20Number.parseFloat(val)%3B%0A%20%20%20%20%20%20%20%20const%20dec%20%3D%20Number.parseInt(decimals)%3B%0A%20%20%20%20%20%20%20%20return%20isNaN(num)%20%7C%7C%20isNaN(dec)%20%3F%20null%20%3A%20num.toFixed(dec)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20gettime%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeDateOperation%20%3D%20(fn)%20%3D%3E%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20date%20%3D%20new%20Date(val)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN(date.getTime())%20%3F%20null%20%3A%20fn(date)%3B%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeDateOperation((date)%20%3D%3E%20date.getTime())(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20toisostring%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeDateOperation%20%3D%20(fn)%20%3D%3E%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20date%20%3D%20new%20Date(val)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20isNaN(date.getTime())%20%3F%20null%20%3A%20fn(date)%3B%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeDateOperation((date)%20%3D%3E%20date.toISOString())(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20localestring%3A%20(d%2C%20timezone%2C%20options)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation((d%2C%20timezone%2C%20options)%20%3D%3E%20new%20Date(d).toLocaleString(timezone%2C%20options))(d%2C%20timezone%2C%20options)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20now%3A%20Date.now%2C%0A%20%20%20%20hextostring%3A%20(val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20const%20safeOperation%20%3D%20(fn)%20%3D%3E%20(...args)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(...args)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20return%20safeOperation((val)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(typeof%20val%20!%3D%3D%20'string'%20%7C%7C%20!%2F%5E%5B0-9a-fA-F%5D%2B%24%2F.test(val)%20%7C%7C%20val.length%20%25%202%20!%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20TextDecoder().decode(new%20Uint8Array(val.match(%2F.%7B1%2C2%7D%2Fg).map((byte)%20%3D%3E%20parseInt(byte%2C%2016))))%3B%0A%20%20%20%20%20%20%20%20%7D)(val)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20valuePicker%3A%20(val%2C%20pick)%20%3D%3E%0A%20%20%20%20%20%20%20%20Object.entries(val)%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter((%5B%2C%20v%5D)%20%3D%3E%20v%20%3D%3D%3D%20pick)%0A%20%20%20%20%20%20%20%20%20%20%20%20.map((%5Bk%5D)%20%3D%3E%20k)%2C%0A%20%20%20%20valuePickerMulti%3A%20(val%2C%20pick)%20%3D%3E%0A%20%20%20%20%20%20%20%20Object.entries(val)%0A%20%20%20%20%20%20%20%20%20%20%20%20.filter((%5B%2C%20v%5D)%20%3D%3E%20pick.includes(v))%0A%20%20%20%20%20%20%20%20%20%20%20%20.map((%5Bk%5D)%20%3D%3E%20k)%0A%7D
|
package/lib/commonConfig.js
CHANGED
|
@@ -157,6 +157,7 @@ function processEnvironmentVariables() {
|
|
|
157
157
|
'IOTA_FALLBACK_PATH',
|
|
158
158
|
'IOTA_LD_SUPPORT_NULL',
|
|
159
159
|
'IOTA_LD_SUPPORT_DATASET_ID',
|
|
160
|
+
'IOTA_LD_SUPPORT_DATA_TYPE',
|
|
160
161
|
'IOTA_EXPRESS_LIMIT',
|
|
161
162
|
'IOTA_USE_CB_FLOW_CONTROL',
|
|
162
163
|
'IOTA_STORE_LAST_MEASURE'
|
|
@@ -264,7 +265,12 @@ function processEnvironmentVariables() {
|
|
|
264
265
|
config.server.port = process.env.IOTA_NORTH_PORT;
|
|
265
266
|
}
|
|
266
267
|
|
|
267
|
-
config.server.ldSupport = config.server.ldSupport || {
|
|
268
|
+
config.server.ldSupport = config.server.ldSupport || {
|
|
269
|
+
null: true,
|
|
270
|
+
datasetId: true,
|
|
271
|
+
merge: false,
|
|
272
|
+
dataType: 'none'
|
|
273
|
+
};
|
|
268
274
|
|
|
269
275
|
if (process.env.IOTA_LD_SUPPORT_NULL) {
|
|
270
276
|
config.server.ldSupport.null = process.env.IOTA_LD_SUPPORT_NULL === 'true';
|
|
@@ -275,6 +281,9 @@ function processEnvironmentVariables() {
|
|
|
275
281
|
if (process.env.IOTA_LD_SUPPORT_MERGE) {
|
|
276
282
|
config.server.ldSupport.datasetId = process.env.IOTA_LD_SUPPORT_MERGE === 'true';
|
|
277
283
|
}
|
|
284
|
+
if (process.env.IOTA_LD_SUPPORT_DATA_TYPE) {
|
|
285
|
+
config.server.ldSupport.dataType = process.env.IOTA_LD_SUPPORT_DATA_TYPE;
|
|
286
|
+
}
|
|
278
287
|
|
|
279
288
|
if (process.env.IOTA_PROVIDER_URL) {
|
|
280
289
|
config.providerUrl = process.env.IOTA_PROVIDER_URL;
|
|
@@ -511,7 +520,7 @@ function getConfig() {
|
|
|
511
520
|
function getConfigForTypeInformation() {
|
|
512
521
|
// Just return relevant configuration flags
|
|
513
522
|
// avoid to include server, authentication, mongodb, orion and iotamanger info
|
|
514
|
-
|
|
523
|
+
const conf = {
|
|
515
524
|
timestamp: config.timestamp,
|
|
516
525
|
defaultResource: config.defaultResource,
|
|
517
526
|
explicitAttrs: config.explicitAttrs,
|
|
@@ -68,7 +68,7 @@ function requestDomain(req, res, next) {
|
|
|
68
68
|
reqDomain.path = req.path;
|
|
69
69
|
reqDomain.op = req.url;
|
|
70
70
|
reqDomain.start = Date.now();
|
|
71
|
-
|
|
71
|
+
reqDomain.from = req.ip || req.connection.remoteAddress;
|
|
72
72
|
reqDomain.add(req);
|
|
73
73
|
reqDomain.add(res);
|
|
74
74
|
|
|
@@ -145,14 +145,15 @@ function ensureSouthboundTransaction(context, callback) {
|
|
|
145
145
|
if (context.op) {
|
|
146
146
|
reqDomain.op = context.op;
|
|
147
147
|
}
|
|
148
|
-
|
|
149
148
|
if (context.srv) {
|
|
150
149
|
reqDomain.service = context.srv;
|
|
151
150
|
}
|
|
152
|
-
|
|
153
151
|
if (context.subsrv) {
|
|
154
152
|
reqDomain.subservice = context.subsrv;
|
|
155
153
|
}
|
|
154
|
+
if (context.from) {
|
|
155
|
+
reqDomain.from = context.from;
|
|
156
|
+
}
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
return reqDomain.run(callback);
|
|
@@ -33,7 +33,6 @@ const logger = require('logops');
|
|
|
33
33
|
const config = require('../../commonConfig');
|
|
34
34
|
const ngsiLD = require('../ngsi/entities-NGSI-LD');
|
|
35
35
|
const utils = require('../northBound/restUtils');
|
|
36
|
-
const moment = require('moment');
|
|
37
36
|
const _ = require('underscore');
|
|
38
37
|
const registrationUtils = require('./registrationUtils');
|
|
39
38
|
const NGSIv2 = require('./devices-NGSI-v2');
|
|
@@ -153,7 +152,7 @@ function updateEntityNgsiLD(deviceData, updatedDevice, callback) {
|
|
|
153
152
|
) {
|
|
154
153
|
options.json[constants.TIMESTAMP_ATTRIBUTE] = {
|
|
155
154
|
type: constants.TIMESTAMP_TYPE_NGSI2,
|
|
156
|
-
value:
|
|
155
|
+
value: new Date().toISOString()
|
|
157
156
|
};
|
|
158
157
|
}
|
|
159
158
|
|
|
@@ -41,7 +41,6 @@ const registrationUtils = require('./registrationUtils');
|
|
|
41
41
|
const _ = require('underscore');
|
|
42
42
|
const utils = require('../northBound/restUtils');
|
|
43
43
|
const NGSIv2 = require('../ngsi/entities-NGSI-v2');
|
|
44
|
-
const moment = require('moment');
|
|
45
44
|
const context = {
|
|
46
45
|
op: 'IoTAgentNGSI.Devices-v2'
|
|
47
46
|
};
|
|
@@ -222,7 +221,7 @@ function updateEntityNgsi2(deviceData, updatedDevice, callback) {
|
|
|
222
221
|
) {
|
|
223
222
|
options.json[constants.TIMESTAMP_ATTRIBUTE] = {
|
|
224
223
|
type: constants.TIMESTAMP_TYPE_NGSI2,
|
|
225
|
-
value:
|
|
224
|
+
value: new Date().toISOString()
|
|
226
225
|
};
|
|
227
226
|
}
|
|
228
227
|
|
|
@@ -59,10 +59,13 @@ function convertAttrNGSILD(attr) {
|
|
|
59
59
|
return undefined;
|
|
60
60
|
}
|
|
61
61
|
let obj = { type: 'Property', value: attr.value };
|
|
62
|
+
let hasValueType = true;
|
|
62
63
|
|
|
63
64
|
switch (attr.type.toLowerCase()) {
|
|
64
65
|
// Properties
|
|
65
66
|
case 'property':
|
|
67
|
+
hasValueType = false;
|
|
68
|
+
break;
|
|
66
69
|
case 'string':
|
|
67
70
|
case 'text':
|
|
68
71
|
case 'textunrestricted':
|
|
@@ -96,24 +99,26 @@ function convertAttrNGSILD(attr) {
|
|
|
96
99
|
}
|
|
97
100
|
break;
|
|
98
101
|
|
|
102
|
+
case 'object':
|
|
103
|
+
case 'array':
|
|
104
|
+
try {
|
|
105
|
+
obj.value = JSON.parse(attr.value);
|
|
106
|
+
} catch (e) {
|
|
107
|
+
// Do nothing
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
|
|
99
111
|
// Temporal Properties
|
|
100
112
|
case 'datetime':
|
|
101
|
-
obj.value =
|
|
102
|
-
'@type': 'DateTime',
|
|
103
|
-
'@value': moment.tz(attr.value, 'Etc/UTC').toISOString()
|
|
104
|
-
};
|
|
113
|
+
obj.value = moment.tz(attr.value, 'Etc/UTC').toISOString();
|
|
105
114
|
break;
|
|
106
115
|
case 'date':
|
|
107
|
-
obj.value =
|
|
108
|
-
'@type': 'Date',
|
|
109
|
-
'@value': moment.tz(attr.value, 'Etc/UTC').format(moment.HTML5_FMT.DATE)
|
|
110
|
-
};
|
|
116
|
+
obj.value = moment.tz(attr.value, 'Etc/UTC').format(moment.HTML5_FMT.DATE);
|
|
111
117
|
break;
|
|
112
118
|
case 'time':
|
|
113
|
-
obj.value =
|
|
114
|
-
'
|
|
115
|
-
|
|
116
|
-
};
|
|
119
|
+
obj.value = moment
|
|
120
|
+
.tz(new Date('0000-01-01 ' + attr.value), 'Etc/UTC')
|
|
121
|
+
.format(moment.HTML5_FMT.TIME_SECONDS);
|
|
117
122
|
break;
|
|
118
123
|
|
|
119
124
|
// GeoProperties
|
|
@@ -121,37 +126,44 @@ function convertAttrNGSILD(attr) {
|
|
|
121
126
|
case 'point':
|
|
122
127
|
case 'geo:point':
|
|
123
128
|
case 'geo:json':
|
|
129
|
+
hasValueType = false;
|
|
124
130
|
obj.type = 'GeoProperty';
|
|
125
131
|
obj.value = NGSIUtils.getLngLats('Point', attr.value);
|
|
126
132
|
break;
|
|
127
133
|
case 'linestring':
|
|
128
134
|
case 'geo:linestring':
|
|
135
|
+
hasValueType = false;
|
|
129
136
|
obj.type = 'GeoProperty';
|
|
130
137
|
obj.value = NGSIUtils.getLngLats('LineString', attr.value);
|
|
131
138
|
break;
|
|
132
139
|
case 'polygon':
|
|
133
140
|
case 'geo:polygon':
|
|
141
|
+
hasValueType = false;
|
|
134
142
|
obj.type = 'GeoProperty';
|
|
135
143
|
obj.value = NGSIUtils.getLngLats('Polygon', attr.value);
|
|
136
144
|
break;
|
|
137
145
|
case 'multipoint':
|
|
138
146
|
case 'geo:multipoint':
|
|
147
|
+
hasValueType = false;
|
|
139
148
|
obj.type = 'GeoProperty';
|
|
140
149
|
obj.value = NGSIUtils.getLngLats('MultiPoint', attr.value);
|
|
141
150
|
break;
|
|
142
151
|
case 'multilinestring':
|
|
143
152
|
case 'geo:multilinestring':
|
|
153
|
+
hasValueType = false;
|
|
144
154
|
obj.type = 'GeoProperty';
|
|
145
155
|
obj.value = NGSIUtils.getLngLats('MultiLineString', attr.value);
|
|
146
156
|
break;
|
|
147
157
|
case 'multipolygon':
|
|
148
158
|
case 'geo:multipolygon':
|
|
159
|
+
hasValueType = false;
|
|
149
160
|
obj.type = 'GeoProperty';
|
|
150
161
|
obj.value = NGSIUtils.getLngLats('MultiPolygon', attr.value);
|
|
151
162
|
break;
|
|
152
163
|
|
|
153
164
|
// Relationships
|
|
154
165
|
case 'relationship':
|
|
166
|
+
hasValueType = false;
|
|
155
167
|
obj.type = 'Relationship';
|
|
156
168
|
obj.object = attr.value;
|
|
157
169
|
delete obj.value;
|
|
@@ -159,13 +171,57 @@ function convertAttrNGSILD(attr) {
|
|
|
159
171
|
|
|
160
172
|
// LanguageProperties
|
|
161
173
|
case 'languageproperty':
|
|
174
|
+
hasValueType = false;
|
|
162
175
|
obj.type = 'LanguageProperty';
|
|
163
176
|
obj.languageMap = attr.value;
|
|
164
177
|
delete obj.value;
|
|
165
178
|
break;
|
|
166
179
|
|
|
180
|
+
// VocabProperties
|
|
181
|
+
case 'vocabproperty':
|
|
182
|
+
hasValueType = false;
|
|
183
|
+
obj.type = 'VocabProperty';
|
|
184
|
+
obj.vocab = attr.value;
|
|
185
|
+
delete obj.value;
|
|
186
|
+
break;
|
|
187
|
+
// JsonProperties
|
|
188
|
+
case 'jsonproperty':
|
|
189
|
+
hasValueType = false;
|
|
190
|
+
obj.type = 'JsonProperty';
|
|
191
|
+
obj.json = attr.value;
|
|
192
|
+
delete obj.value;
|
|
193
|
+
break;
|
|
194
|
+
// ListProperties
|
|
195
|
+
case 'listproperty':
|
|
196
|
+
hasValueType = false;
|
|
197
|
+
obj.type = 'ListProperty';
|
|
198
|
+
obj.listValue = attr.value;
|
|
199
|
+
delete obj.value;
|
|
200
|
+
break;
|
|
201
|
+
// ListRelationship
|
|
202
|
+
case 'listrelationship':
|
|
203
|
+
hasValueType = false;
|
|
204
|
+
obj.type = 'ListRelationship';
|
|
205
|
+
obj.listObject = attr.value;
|
|
206
|
+
delete obj.value;
|
|
207
|
+
break;
|
|
208
|
+
|
|
167
209
|
default:
|
|
168
|
-
obj.value =
|
|
210
|
+
obj.value = attr.value;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (hasValueType) {
|
|
214
|
+
switch (config.getConfig().server.ldSupport.dataType) {
|
|
215
|
+
case '@type':
|
|
216
|
+
obj.value = {
|
|
217
|
+
'@type': attr.type,
|
|
218
|
+
'@value': obj.value
|
|
219
|
+
};
|
|
220
|
+
break;
|
|
221
|
+
case 'valueType':
|
|
222
|
+
obj.valueType = attr.type;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
169
225
|
}
|
|
170
226
|
|
|
171
227
|
if (!!obj && attr.metadata) {
|
|
@@ -95,7 +95,9 @@ function sendUpdateValue(entityName, attributes, typeInformation, token, callbac
|
|
|
95
95
|
// check config about store last measure
|
|
96
96
|
if (typeInformation.storeLastMeasure) {
|
|
97
97
|
logger.debug(context, 'StoreLastMeasure for %j', typeInformation);
|
|
98
|
-
|
|
98
|
+
let originalMeasure = typeInformation.originalMeasure ? typeInformation.originalMeasure : null;
|
|
99
|
+
deviceService.storeDeviceField('lastMeasure', originalMeasure, typeInformation, function () {
|
|
100
|
+
delete typeInformation.originalMeasure;
|
|
99
101
|
return entityHandler.sendUpdateValue(entityName, attributes, typeInformation, token, wrappedNewCallback);
|
|
100
102
|
});
|
|
101
103
|
} else {
|
|
@@ -46,7 +46,7 @@ const config = require('../../commonConfig');
|
|
|
46
46
|
|
|
47
47
|
const overwritePaths = ['/ngsi-ld/v1/entities/:entity/attrs', '/ngsi-ld/v1/entities/:entity/attrs/:attr'];
|
|
48
48
|
const updatePaths = ['/ngsi-ld/v1/entities/:entity/attrs', '/ngsi-ld/v1/entities/:entity/attrs/:attr'];
|
|
49
|
-
const queryPaths = ['/ngsi-ld/v1/entities/:entity'];
|
|
49
|
+
const queryPaths = ['/ngsi-ld/v1/entities/:entity', '/ngsi-ld/v1/entities'];
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Replacement of NGSI-LD Null placeholders with real null values
|
|
@@ -506,6 +506,9 @@ function handleMergePatchNgsiLD(req, res, next) {
|
|
|
506
506
|
* @param {Object} res Response that will be sent.
|
|
507
507
|
*/
|
|
508
508
|
function handleQueryNgsiLD(req, res, next) {
|
|
509
|
+
const returnAsArray = req.query.id;
|
|
510
|
+
req.params.entity = req.params.entity || req.query.id || '';
|
|
511
|
+
|
|
509
512
|
function getName(element) {
|
|
510
513
|
return element.name;
|
|
511
514
|
}
|
|
@@ -641,7 +644,7 @@ function handleQueryNgsiLD(req, res, next) {
|
|
|
641
644
|
next(error);
|
|
642
645
|
} else {
|
|
643
646
|
logger.debug(context, 'Query from [%s] handled successfully.', req.get('host'));
|
|
644
|
-
res.status(200).json(result);
|
|
647
|
+
res.status(200).json(returnAsArray ? [result] : result);
|
|
645
648
|
}
|
|
646
649
|
}
|
|
647
650
|
|
|
@@ -793,7 +796,6 @@ function loadUnsupportedEndpointsNGSILD(router) {
|
|
|
793
796
|
const unsupportedEndpoint = function (req, res) {
|
|
794
797
|
return res.status(501).send(new errors.MethodNotSupported(req.method, req.path));
|
|
795
798
|
};
|
|
796
|
-
router.get('/ngsi-ld/v1/entities', unsupportedEndpoint);
|
|
797
799
|
router.post('/ngsi-ld/v1/entities', unsupportedEndpoint);
|
|
798
800
|
router.delete('/ngsi-ld/v1/entities/:entity', unsupportedEndpoint);
|
|
799
801
|
router.delete('/ngsi-ld/v1/entities/:entity/attrs/:attr', unsupportedEndpoint);
|
|
@@ -59,7 +59,7 @@ function start(config, callback) {
|
|
|
59
59
|
northboundServer.app.use(domainUtils.requestDomain);
|
|
60
60
|
northboundServer.app.use(bodyParser.json({ limit: config.expressLimit }));
|
|
61
61
|
northboundServer.app.use(bodyParser.json({ type: 'application/*+json', limit: config.expressLimit }));
|
|
62
|
-
|
|
62
|
+
northboundServer.app.set('trust proxy', true); // populate req.ip
|
|
63
63
|
if (config.logLevel && config.logLevel === 'DEBUG') {
|
|
64
64
|
northboundServer.app.use(middlewares.traceRequest);
|
|
65
65
|
}
|
|
@@ -30,7 +30,6 @@ const errors = require('../../errors');
|
|
|
30
30
|
const constants = require('../../constants');
|
|
31
31
|
const intoTrans = require('../common/domain').intoTrans;
|
|
32
32
|
const revalidator = require('revalidator');
|
|
33
|
-
const moment = require('moment');
|
|
34
33
|
const context = {
|
|
35
34
|
op: 'IoTAgentNGSI.RestUtils'
|
|
36
35
|
};
|
|
@@ -121,6 +120,11 @@ function checkBody(template) {
|
|
|
121
120
|
};
|
|
122
121
|
}
|
|
123
122
|
|
|
123
|
+
function isISOString(val) {
|
|
124
|
+
const d = new Date(val);
|
|
125
|
+
return !Number.isNaN(d.valueOf()) && d.toISOString() === val;
|
|
126
|
+
}
|
|
127
|
+
|
|
124
128
|
/**
|
|
125
129
|
* Checks if the timestamp properties of NGSIv2 entities are valid ISO8601 dates.
|
|
126
130
|
*
|
|
@@ -131,7 +135,7 @@ function IsValidTimestampedNgsi2(payload) {
|
|
|
131
135
|
function isValidTimestampedNgsi2Entity(entity) {
|
|
132
136
|
for (const i in entity) {
|
|
133
137
|
if (entity.hasOwnProperty(i)) {
|
|
134
|
-
if (i === constants.TIMESTAMP_ATTRIBUTE && !
|
|
138
|
+
if (i === constants.TIMESTAMP_ATTRIBUTE && !isISOString(entity[i].value)) {
|
|
135
139
|
return false;
|
|
136
140
|
}
|
|
137
141
|
}
|
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
|
+
"version": "4.9.0",
|
|
6
6
|
"homepage": "https://github.com/telefonicaid/iotagent-node-lib",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"fiware",
|
|
@@ -3,24 +3,15 @@
|
|
|
3
3
|
"@context": "http://context.json-ld",
|
|
4
4
|
"commandAttr_info": {
|
|
5
5
|
"type": "Property",
|
|
6
|
-
"value":
|
|
7
|
-
"@type": "commandResult",
|
|
8
|
-
"@value": " "
|
|
9
|
-
}
|
|
6
|
+
"value": " "
|
|
10
7
|
},
|
|
11
8
|
"commandAttr_status": {
|
|
12
9
|
"type": "Property",
|
|
13
|
-
"value":
|
|
14
|
-
"@type": "commandStatus",
|
|
15
|
-
"@value": "UNKNOWN"
|
|
16
|
-
}
|
|
10
|
+
"value": "UNKNOWN"
|
|
17
11
|
},
|
|
18
12
|
"hardcodedAttr": {
|
|
19
13
|
"type": "Property",
|
|
20
|
-
"value":
|
|
21
|
-
"@type": "hardcodedType",
|
|
22
|
-
"@value": "hardcodedValue"
|
|
23
|
-
}
|
|
14
|
+
"value": "hardcodedValue"
|
|
24
15
|
},
|
|
25
16
|
"id": "urn:ngsi-ld:TheLightType:TheFirstLight",
|
|
26
17
|
"type": "TheLightType"
|
|
@@ -3,24 +3,15 @@
|
|
|
3
3
|
"@context": "http://context.json-ld",
|
|
4
4
|
"commandAttr_info": {
|
|
5
5
|
"type": "Property",
|
|
6
|
-
"value":
|
|
7
|
-
"@type": "commandResult",
|
|
8
|
-
"@value": " "
|
|
9
|
-
}
|
|
6
|
+
"value": " "
|
|
10
7
|
},
|
|
11
8
|
"commandAttr_status": {
|
|
12
9
|
"type": "Property",
|
|
13
|
-
"value":
|
|
14
|
-
"@type": "commandStatus",
|
|
15
|
-
"@value": "UNKNOWN"
|
|
16
|
-
}
|
|
10
|
+
"value": "UNKNOWN"
|
|
17
11
|
},
|
|
18
12
|
"hardcodedAttr": {
|
|
19
13
|
"type": "Property",
|
|
20
|
-
"value":
|
|
21
|
-
"@type": "hardcodedType",
|
|
22
|
-
"@value": "hardcodedValue"
|
|
23
|
-
}
|
|
14
|
+
"value": "hardcodedType"
|
|
24
15
|
},
|
|
25
16
|
"id": "urn:ngsi-ld:TheLightType:TheFirstLight",
|
|
26
17
|
"type": "TheLightType"
|
package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceWithGroupAndStatic.json
CHANGED
|
@@ -5,45 +5,27 @@
|
|
|
5
5
|
"type": "TheLightType",
|
|
6
6
|
"hardcodedAttr": {
|
|
7
7
|
"type": "Property",
|
|
8
|
-
"value":
|
|
9
|
-
"@type": "hardcodedType",
|
|
10
|
-
"@value": "hardcodedValue"
|
|
11
|
-
}
|
|
8
|
+
"value": "hardcodedType"
|
|
12
9
|
},
|
|
13
10
|
"bootstrapServer": {
|
|
14
11
|
"type": "Property",
|
|
15
|
-
"value":
|
|
16
|
-
"@type": "Address",
|
|
17
|
-
"@value": "127.0.0.1"
|
|
18
|
-
}
|
|
12
|
+
"value": "127.0.0.1"
|
|
19
13
|
},
|
|
20
14
|
"commandAttr_status": {
|
|
21
15
|
"type": "Property",
|
|
22
|
-
"value":
|
|
23
|
-
"@type": "commandStatus",
|
|
24
|
-
"@value": "UNKNOWN"
|
|
25
|
-
}
|
|
16
|
+
"value": "UNKNOWN"
|
|
26
17
|
},
|
|
27
18
|
"commandAttr_info": {
|
|
28
19
|
"type": "Property",
|
|
29
|
-
"value":
|
|
30
|
-
"@type": "commandResult",
|
|
31
|
-
"@value": " "
|
|
32
|
-
}
|
|
20
|
+
"value": "commandResult",
|
|
33
21
|
},
|
|
34
22
|
"wheel1_status": {
|
|
35
23
|
"type": "Property",
|
|
36
|
-
"value":
|
|
37
|
-
"@type": "commandStatus",
|
|
38
|
-
"@value": "UNKNOWN"
|
|
39
|
-
}
|
|
24
|
+
"value": "commandStatus"
|
|
40
25
|
},
|
|
41
26
|
"wheel1_info": {
|
|
42
27
|
"type": "Property",
|
|
43
|
-
"value":
|
|
44
|
-
"@type": "commandResult",
|
|
45
|
-
"@value": " "
|
|
46
|
-
}
|
|
28
|
+
"value": "commandResult"
|
|
47
29
|
}
|
|
48
30
|
}
|
|
49
31
|
]
|