iotagent-node-lib 3.2.0 → 3.4.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 (184) 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/README.md +10 -11
  7. package/doc/README.md +16 -0
  8. package/doc/admin.md +565 -0
  9. package/doc/api.md +32 -85
  10. package/doc/deprecated.md +16 -10
  11. package/doc/{architecture.md → devel/architecture.md} +3 -3
  12. package/doc/{Contribution.md → devel/contribution-guidelines.md} +43 -35
  13. package/doc/devel/development.md +1879 -0
  14. package/doc/{northboundinteractions.md → devel/northboundinteractions.md} +18 -33
  15. package/doc/index.md +3 -5
  16. package/doc/requirements.txt +1 -1
  17. package/docker/Mosquitto/Dockerfile +1 -1
  18. package/docker/Mosquitto/README.md +1 -0
  19. package/lib/commonConfig.js +0 -5
  20. package/lib/fiware-iotagent-lib.js +1 -1
  21. package/lib/jexlTranformsMap.js +2 -1
  22. package/lib/model/Device.js +0 -1
  23. package/lib/model/Group.js +0 -1
  24. package/lib/model/dbConn.js +1 -7
  25. package/lib/plugins/jexlParser.js +1 -1
  26. package/lib/request-shim.js +2 -2
  27. package/lib/services/commands/commandService.js +1 -1
  28. package/lib/services/common/genericMiddleware.js +1 -1
  29. package/lib/services/common/iotManagerService.js +0 -1
  30. package/lib/services/devices/deviceRegistryMemory.js +2 -2
  31. package/lib/services/devices/deviceRegistryMongoDB.js +32 -19
  32. package/lib/services/devices/deviceService.js +44 -43
  33. package/lib/services/devices/devices-NGSI-LD.js +14 -2
  34. package/lib/services/devices/devices-NGSI-mixed.js +0 -2
  35. package/lib/services/devices/devices-NGSI-v2.js +23 -104
  36. package/lib/services/groups/groupService.js +1 -1
  37. package/lib/services/ngsi/entities-NGSI-LD.js +3 -3
  38. package/lib/services/ngsi/entities-NGSI-v2.js +28 -19
  39. package/lib/services/northBound/deviceProvisioningServer.js +14 -8
  40. package/lib/templates/createDevice.json +0 -4
  41. package/lib/templates/createDeviceLax.json +0 -4
  42. package/lib/templates/deviceGroup.json +1 -5
  43. package/lib/templates/updateDevice.json +4 -0
  44. package/lib/templates/updateDeviceLax.json +11 -0
  45. package/mkdocs.yml +6 -11
  46. package/package.json +3 -3
  47. package/scripts/legacy_expression_tool/README.md +280 -0
  48. package/scripts/legacy_expression_tool/legacy_expression_tool.py +423 -0
  49. package/scripts/legacy_expression_tool/requirements.txt +3 -0
  50. package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +0 -1
  51. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +5 -15
  52. package/test/unit/mongodb/mongodb-registry-test.js +1 -1
  53. package/test/unit/ngsi-ld/general/contextBrokerOAuthSecurityAccess-test.js +66 -65
  54. package/test/unit/ngsi-ld/general/https-support-test.js +1 -1
  55. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +8 -7
  56. package/test/unit/ngsi-ld/lazyAndCommands/merge-patch-test.js +31 -30
  57. package/test/unit/ngsi-ld/lazyAndCommands/polling-commands-test.js +12 -11
  58. package/test/unit/ngsi-ld/ngsiService/subscriptions-test.js +41 -39
  59. package/test/unit/ngsi-ld/provisioning/device-provisioning-api_test.js +122 -122
  60. package/test/unit/ngsi-ld/provisioning/device-registration_test.js +28 -28
  61. package/test/unit/ngsi-ld/provisioning/device-update-registration_test.js +18 -17
  62. package/test/unit/ngsi-ld/provisioning/singleConfigurationMode-test.js +7 -7
  63. package/test/unit/ngsi-ld/provisioning/updateProvisionedDevices-test.js +8 -7
  64. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +33 -37
  65. package/test/unit/ngsiv2/examples/contextRequests/updateContext.json +2 -0
  66. package/test/unit/ngsiv2/examples/contextRequests/updateContext1.json +3 -1
  67. package/test/unit/ngsiv2/examples/contextRequests/updateContext3WithStatic.json +2 -0
  68. package/test/unit/ngsiv2/examples/contextRequests/updateContext4.json +4 -1
  69. package/test/unit/ngsiv2/examples/contextRequests/updateContext5.json +12 -0
  70. package/test/unit/ngsiv2/examples/contextRequests/updateContext6.json +12 -0
  71. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin1.json +2 -0
  72. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin2.json +3 -1
  73. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin3.json +3 -1
  74. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin4.json +3 -1
  75. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin5.json +3 -1
  76. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin6.json +3 -1
  77. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin7.json +3 -1
  78. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin8.json +3 -1
  79. package/test/unit/ngsiv2/examples/contextRequests/updateContextAliasPlugin9.json +3 -1
  80. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast1.json +2 -0
  81. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast2.json +2 -0
  82. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast3.json +3 -1
  83. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast4.json +3 -1
  84. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast5.json +3 -1
  85. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast6.json +3 -1
  86. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast7.json +3 -1
  87. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandError.json +3 -1
  88. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandExpired.json +3 -1
  89. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandFinish.json +3 -1
  90. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus.json +2 -0
  91. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +2 -0
  92. package/test/unit/ngsiv2/examples/contextRequests/updateContextCompressTimestamp1.json +3 -1
  93. package/test/unit/ngsiv2/examples/contextRequests/updateContextCompressTimestamp2.json +3 -1
  94. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin1.json +2 -12
  95. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin11.json +2 -4
  96. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin12.json +2 -4
  97. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin13.json +3 -1
  98. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin2.json +2 -12
  99. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin29.json +2 -12
  100. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin3.json +2 -4
  101. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin30.json +2 -0
  102. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin31.json +2 -0
  103. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin32.json +2 -0
  104. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin33.json +2 -0
  105. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin34.json +2 -0
  106. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin35.json +2 -0
  107. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +1 -0
  108. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin4.json +2 -0
  109. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin40.json +1 -1
  110. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin41.json +1 -10
  111. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin5.json +2 -4
  112. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin6.json +2 -4
  113. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin7.json +2 -4
  114. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin8.json +2 -12
  115. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin9.json +2 -4
  116. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionSkip.json +12 -0
  117. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityJexlExpressionPlugin1.json +1 -1
  118. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin1.json +1 -1
  119. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin10.json +1 -1
  120. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin11.json +1 -1
  121. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin12.json +1 -1
  122. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin13.json +1 -1
  123. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin14.json +1 -1
  124. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin15.json +1 -1
  125. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin16.json +1 -1
  126. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +1 -1
  127. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin2.json +1 -1
  128. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin25.json +2 -6
  129. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin3.json +1 -1
  130. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin4.json +1 -1
  131. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin5.json +1 -1
  132. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin6.json +1 -1
  133. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin7.json +1 -1
  134. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin8.json +1 -1
  135. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin9.json +1 -1
  136. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin1.json +1 -1
  137. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +1 -1
  138. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin3.json +1 -1
  139. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityTimestampPlugin4.json +2 -0
  140. package/test/unit/ngsiv2/examples/contextRequests/updateContextProcessTimestamp.json +2 -0
  141. package/test/unit/ngsiv2/examples/contextRequests/updateContextStaticAttributes.json +2 -0
  142. package/test/unit/ngsiv2/examples/contextRequests/updateContextStaticAttributesMetadata.json +3 -1
  143. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestamp.json +3 -1
  144. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampFalse.json +12 -0
  145. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampFalseTimeInstant.json +12 -0
  146. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampOverride.json +2 -0
  147. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampOverrideWithoutMilis.json +2 -0
  148. package/test/unit/ngsiv2/examples/contextRequests/updateContextTimestampTimezone.json +3 -1
  149. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +144 -85
  150. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +20 -53
  151. package/test/unit/ngsiv2/general/https-support-test.js +2 -6
  152. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +4 -10
  153. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +8 -24
  154. package/test/unit/ngsiv2/ngsiService/active-devices-test.js +146 -65
  155. package/test/unit/ngsiv2/ngsiService/autocast-test.js +14 -21
  156. package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +3 -5
  157. package/test/unit/ngsiv2/ngsiService/subscriptions-test.js +11 -20
  158. package/test/unit/ngsiv2/plugins/alias-plugin_test.js +20 -30
  159. package/test/unit/ngsiv2/plugins/compress-timestamp-plugin_test.js +4 -6
  160. package/test/unit/ngsiv2/plugins/custom-plugin_test.js +1 -2
  161. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +3 -5
  162. package/test/unit/ngsiv2/plugins/timestamp-processing-plugin_test.js +2 -3
  163. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +2 -3
  164. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +13 -156
  165. package/test/unit/ngsiv2/provisioning/device-registration_test.js +9 -13
  166. package/test/unit/ngsiv2/provisioning/device-update-registration_test.js +4 -10
  167. package/test/unit/ngsiv2/provisioning/singleConfigurationMode-test.js +0 -11
  168. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +0 -8
  169. package/test/unit/plugins/capture-provision-inPlugins_test.js +0 -6
  170. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +0 -1
  171. package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +0 -1
  172. package/.nyc_output/processinfo/index.json +0 -1
  173. package/doc/config-basic-example.js +0 -20
  174. package/doc/development.md +0 -285
  175. package/doc/howto.md +0 -645
  176. package/doc/installationguide.md +0 -370
  177. package/doc/operations.md +0 -127
  178. package/doc/usermanual.md +0 -900
  179. package/lib/plugins/bidirectionalData.js +0 -356
  180. package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +0 -697
  181. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +0 -599
  182. /package/doc/{NorthboundInteractions.postman_collection → devel/NorthboundInteractions.postman_collection} +0 -0
  183. /package/doc/{echo.js → devel/echo.js} +0 -0
  184. /package/doc/{finalResult.js → devel/finalResult.js} +0 -0
@@ -145,7 +145,7 @@ This **NGSI-v2** payload is associated to an update operation (POST `/v2/op/upda
145
145
  }
146
146
  }
147
147
  ],
148
- "actionType": "update"
148
+ "actionType": "append"
149
149
  }
150
150
  ```
151
151
 
@@ -155,9 +155,8 @@ As it can be seen in the example, the payload is a JSON Object with the followin
155
155
  with the information needed to identify the target entity `id` and `type` attributes. The `entities` attribute is an
156
156
  array, so a single update context batch operation can be used to update multiple devices
157
157
 
158
- - An `actionType` indicating the type of update: if this attribute has the value `"append"` the appropriate entity and
159
- attributes will be created if the don't exist; if the value is `"update"`, an error will be thrown if the target
160
- resources don't exist.
158
+ - An `actionType` indicating the type of update. It has the value `"append"` the appropriate entity and attributes
159
+ will be created if the don't exist.
161
160
 
162
161
  The equivalent **NGSI-LD** payload is associated to an update operation (PATCH `/ngsi-ld/v1/entities/<entity>/attrs/`).
163
162
 
@@ -427,7 +426,7 @@ Be sure to understand how each scenario works (as shown in the theory section) b
427
426
  Along this document, IP addresses and passwords will be concealed. Substitute the concealed passwords by your own.
428
427
 
429
428
  A postman collection is available alongside this document to help in reproducing this examples. It can be found
430
- [here](./doc/NorthboundInteractions.postman_collection).
429
+ [here](NorthboundInteractions.postman_collection).
431
430
 
432
431
  ### Retrieving a token
433
432
 
@@ -507,8 +506,8 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
507
506
  }
508
507
  }
509
508
  ],
510
- "actionType": "update"
511
- } ' "https://<platform-ip>:10027/v2/op/update"
509
+ "actionType": "append"
510
+ } ' "https://<platform-ip>:1026/v2/op/update"
512
511
  ```
513
512
 
514
513
  If the request is correct, the Context Broker will reply with the following R1 response (200 OK):
@@ -554,7 +553,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
554
553
  }
555
554
  ],
556
555
  "attrs": ["temperature","pressure"]
557
- }' "https://<platform-ip>:10027/v2/op/query"
556
+ }' "https://<platform-ip>:1026/v2/op/query"
558
557
  ```
559
558
 
560
559
  The Context Broker will reply with the updated data values in R2 format (200 OK):
@@ -600,20 +599,6 @@ It is worth mentioning that the Context Broker will reply with a 200 OK status c
600
599
  refer to transport protocol level errors, while the status codes inside of a payload give information about the
601
600
  application level protocol.
602
601
 
603
- The example shows an error updating an non-existent attribute (due to the use of UPDATE instead of APPEND).
604
-
605
- The following error payload is also valid in standard NGSI:
606
-
607
- ```json
608
- {
609
- "error": "NotFound",
610
- "description": "The requested entity has not been found. Check type and id"
611
- }
612
- ```
613
-
614
- Different kinds of errors can return their information in different formats, so NGSI implementations should check for
615
- the existence of both.
616
-
617
602
  ### Scenario 2: lazy attributes (happy path)
618
603
 
619
604
  Scenario 2 relies on the Context Provider mechanism of the Context Broker. For this scenario to work, the IoTAgent must
@@ -639,7 +624,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
639
624
  }
640
625
  }
641
626
  }
642
- ' "https://<platform-ip>:10027/v2/registrations"
627
+ ' "https://<platform-ip>:1026/v2/registrations"
643
628
  ```
644
629
 
645
630
  If everything has gone OK, the Context Broker will return the following payload:
@@ -669,7 +654,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
669
654
  }
670
655
  ],
671
656
  "attrs": ["batteryLevel"]
672
- }' "https://<platform-ip>:10027/v2/op/query"
657
+ }' "https://<platform-ip>:1026/v2/op/query"
673
658
  ```
674
659
 
675
660
  The Context Broker receives this request and detects that it can be served by a Context Provider (the IoT Agent), so it
@@ -772,7 +757,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
772
757
  }
773
758
  ],
774
759
  "duration": "P1M"
775
- }' "https://<platform-ip>:10027/v2/registrations"
760
+ }' "https://<platform-ip>:1026/v2/registrations"
776
761
  ```
777
762
 
778
763
  If everything has gone OK, the Context Broker will return the following payload:
@@ -806,8 +791,8 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
806
791
  }
807
792
  }
808
793
  ],
809
- "updateAction": "update"
810
- } ' "https://<platform-ip>:10027/v2/op/update"
794
+ "updateAction": "append"
795
+ } ' "https://<platform-ip>:1026/v2/op/update"
811
796
  ```
812
797
 
813
798
  The Context Broker receives this command and detects that it can be served by a Context Provider (the IoT Agent), so it
@@ -836,7 +821,7 @@ Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab
836
821
  }
837
822
  }
838
823
  ],
839
- "updateAction" : "update"
824
+ "updateAction" : "append"
840
825
  }
841
826
  ```
842
827
 
@@ -900,8 +885,8 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
900
885
  }
901
886
  }
902
887
  ],
903
- "actionType": "update"
904
- } ' "https://<platform-ip>:10027/v2/op/update"
888
+ "actionType": "append"
889
+ } ' "https://<platform-ip>:1026/v2/op/update"
905
890
  ```
906
891
 
907
892
  This update does not modify the original command attribute, but two auxiliary attributes, that are not provided by the
@@ -948,7 +933,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
948
933
  "switch_info",
949
934
  "switch_status"
950
935
  ]
951
- }' "https://<platform-ip>:10027/v2/op/query"
936
+ }' "https://<platform-ip>:1026/v2/op/query"
952
937
  ```
953
938
 
954
939
  The Context Broker replies with all the desired data, in R2 format (200 OK):
@@ -994,8 +979,8 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
994
979
  }
995
980
  }
996
981
  ],
997
- "actionType": "update"
998
- } ' "https://<platform-ip>:10027/v2/op/update"
982
+ "actionType": "append"
983
+ } ' "https://<platform-ip>:1026/v2/op/update"
999
984
  ```
1000
985
 
1001
986
  In this case, the Context Broker reply with the following response (200 OK):
package/doc/index.md CHANGED
@@ -11,8 +11,8 @@ Broker using their own native protocols. IoT Agents should also be able to deal
11
11
  platform (authentication and authorization of the channel) and provide other common services to the device programmer.
12
12
 
13
13
  Github's [README.md](https://github.com/telefonicaid/iotagent-node-lib/blob/master/README.md) provides a good
14
- documentation summary. The [User Manual](usermanual.md) and the [Admin Guide](installationguide.md) cover more advanced
15
- topics.
14
+ documentation summary. The [API reference](doc/api.md) and the [Development documentation](devel/development.md) cover
15
+ more advanced topics.
16
16
 
17
17
  ## Background
18
18
 
@@ -26,8 +26,6 @@ functions.
26
26
  communications are left to the library.
27
27
  - Standardized OAuth2-based security is available to enable each IoT Agent to connect to several common Identity
28
28
  Managers (e.g. Keystone and Keyrock) so that communications can be restricted to trusted components.
29
- - A series of additional plugins are offered where necessary to allow for expression parsing, attribute aliasing and
30
- the processing of timestamp metadata.
31
29
 
32
30
  Each individual IoT Agent offers is driven by a `config.js` configuration file contains explicit custom settings based
33
31
  on the protocol and payload the IoT Agent is translating. It will also contain some common flags for common
@@ -51,5 +49,5 @@ IoT Agent
51
49
  In order to use the library within your own IoT Agent, you must first you require it before use:
52
50
 
53
51
  ```javascript
54
- const iotagentLib = require("iotagent-node-lib");
52
+ const iotagentLib = require('iotagent-node-lib');
55
53
  ```
@@ -1,4 +1,4 @@
1
1
  mkdocs==1.2.3
2
- Pygments==2.9.0
2
+ Pygments==2.15.0
3
3
  Markdown==3.3.4
4
4
  jinja2==3.0.0
@@ -1,4 +1,4 @@
1
- ARG IMAGE_TAG=11.3-slim
1
+ ARG IMAGE_TAG=12.1-slim
2
2
  FROM debian:${IMAGE_TAG}
3
3
 
4
4
  ARG CLEAN_DEV_TOOLS
@@ -2,6 +2,7 @@ Thi directory containts the Dockerfile (and associated files) for a container of
2
2
  This container is provide as a help for users to test with MQTT, but it is just an auxiliary material in this repository.
3
3
 
4
4
  The following releases matches with eclipse-mosquitto version:
5
+ - 2.1.0 uses mosquitto-2.0.11 from Debian 12
5
6
  - 2.0.0 uses mosquitto-2.0.11 from Debian 11
6
7
  - 1.6.0 uses mosquitto-1.6.10-1.el7.x86_64 (from Centos7)
7
8
  - 1.5.0 uses mosquitto-1.6.10-1.el7.x86_64 (from Centos7)
@@ -149,7 +149,6 @@ function processEnvironmentVariables() {
149
149
  'IOTA_MONGO_USER',
150
150
  'IOTA_MONGO_RETRY_TIME',
151
151
  'IOTA_SINGLE_MODE',
152
- 'IOTA_APPEND_MODE',
153
152
  'IOTA_POLLING_EXPIRATION',
154
153
  'IOTA_POLLING_DAEMON_FREQ',
155
154
  'IOTA_MULTI_CORE',
@@ -450,10 +449,6 @@ function processEnvironmentVariables() {
450
449
  config.singleConfigurationMode = process.env.IOTA_SINGLE_MODE === 'true';
451
450
  }
452
451
 
453
- if (process.env.IOTA_APPEND_MODE) {
454
- config.appendMode = process.env.IOTA_APPEND_MODE === 'true';
455
- }
456
-
457
452
  if (process.env.IOTA_POLLING_EXPIRATION) {
458
453
  config.pollingExpiration = process.env.IOTA_POLLING_EXPIRATION;
459
454
  }
@@ -302,6 +302,7 @@ exports.update = ngsi.update;
302
302
  exports.setCommandResult = ngsi.setCommandResult;
303
303
  exports.listDevices = deviceService.listDevices;
304
304
  exports.getDevice = deviceService.getDevice;
305
+ exports.updateDevice = deviceService.updateDevice;
305
306
  exports.getDeviceSilently = deviceService.getDeviceSilently;
306
307
  exports.getDeviceByName = deviceService.getDeviceByName;
307
308
  exports.getDeviceByNameAndType = deviceService.getDeviceByNameAndType;
@@ -349,7 +350,6 @@ exports.middlewares = middlewares;
349
350
 
350
351
  exports.dataPlugins = {
351
352
  expressionTransformation: require('./plugins/expressionPlugin'),
352
- bidirectionalData: require('./plugins/bidirectionalData'),
353
353
  utils: require('./plugins/pluginUtils')
354
354
  };
355
355
 
@@ -79,7 +79,8 @@ const map = {
79
79
  // https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString
80
80
  localestring: (d, timezone, options) => new Date(d).toLocaleString(timezone, options),
81
81
  now: () => Date.now(),
82
- hextostring: (val) => new TextDecoder().decode(new Uint8Array(val.match(/.{1,2}/g).map(byte => parseInt(byte, 16))))
82
+ hextostring: (val) =>
83
+ new TextDecoder().decode(new Uint8Array(val.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))))
83
84
  };
84
85
 
85
86
  exports.map = map;
@@ -51,7 +51,6 @@ const Device = new Schema({
51
51
  creationDate: { type: Date, default: Date.now },
52
52
  internalAttributes: Object,
53
53
  autoprovision: Boolean,
54
- expressionLanguage: String,
55
54
  explicitAttrs: Group.ExplicitAttrsType,
56
55
  ngsiVersion: String
57
56
  });
@@ -59,7 +59,6 @@ const Group = new Schema({
59
59
  attributes: Array,
60
60
  internalAttributes: Array,
61
61
  autoprovision: Boolean,
62
- expressionLanguage: String,
63
62
  explicitAttrs: ExplicitAttrsType,
64
63
  defaultEntityNameConjunction: String,
65
64
  ngsiVersion: String,
@@ -106,13 +106,7 @@ function init(host, db, port, options, callback) {
106
106
  }
107
107
 
108
108
  function connectionAttempt(url, options, callback) {
109
- logger.info(
110
- context,
111
- 'Attempting to connect to MongoDB instance with url %j and options %j. Attempt %d',
112
- url,
113
- options,
114
- retries
115
- );
109
+ logger.info(context, 'Attempting to connect to MongoDB instance with url %j. Attempt %d', url, retries);
116
110
  // FIXME: useNewUrlParser is no longer used in underlying mongodb driver 4.x
117
111
  // (see https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_4.0.0.md)
118
112
  // but not sure if current mongoose version is still using mongodb 3.x internally
@@ -77,7 +77,7 @@ function extractVariables(expression) {
77
77
  variables = tokens.filter(function (token, index, array) {
78
78
  return (
79
79
  (token.type === ' ' && array[index - 1].type !== 'dot') ||
80
- (token.type === 'identifier' && array[index + 1].type !== 'openParen')
80
+ (token.type === 'identifier' && array[index + 1] && array[index + 1].type !== 'openParen')
81
81
  );
82
82
  });
83
83
 
@@ -59,7 +59,7 @@ function getOptions(options) {
59
59
  // got library is not properly documented, so it is not clear which takes precedence
60
60
  // among body, json and form (see https://stackoverflow.com/q/70754880/1485926).
61
61
  // Thus, we are enforcing our own precedence with the "else if" chain below.
62
- // Behaviour is consistent with the one described at usermanual.md#iotagentlibrequest
62
+ // Behaviour is consistent with the one described at development.md#iotagentlibrequest
63
63
 
64
64
  if (options.method === 'GET' || options.method === 'HEAD' || options.method === 'OPTIONS') {
65
65
  // Do nothing - Never add a body
@@ -70,7 +70,7 @@ function getOptions(options) {
70
70
  // json takes precedence over form
71
71
  httpOptions.json = options.json;
72
72
  } else if (options.form) {
73
- // Note that we don't consider 'form' part of the function API (check usermanual.md#iotagentlibrequest)
73
+ // Note that we don't consider 'form' part of the function API (check development.md#iotagentlibrequest)
74
74
  // but we are preparing the code anyway as a safe measure
75
75
  httpOptions.form = options.form;
76
76
  }
@@ -120,7 +120,7 @@ function markAsExpired(command) {
120
120
 
121
121
  async.waterfall(
122
122
  [
123
- apply(deviceService.getDevice, command.deviceId, command.service, command.subservice),
123
+ apply(deviceService.getDevice, command.deviceId, null, command.service, command.subservice),
124
124
  getGroup,
125
125
  calculateTypeInformation,
126
126
  updateExpiredCommand
@@ -56,7 +56,7 @@ function handleError(error, req, res, next) {
56
56
  * Express middleware for tracing the complete request arriving to the IoTA in debug mode.
57
57
  */
58
58
  function traceRequest(req, res, next) {
59
- logger.debug(context, 'Request for path [%s] from [%s]', req.path, req.get('host'));
59
+ logger.debug(context, 'Request for path [%s] query [%j] from [%s]', req.path, req.query, req.get('host'));
60
60
 
61
61
  if (req.is('json') || req.is('application/ld+json')) {
62
62
  logger.debug(context, 'Body:\n\n%s\n\n', JSON.stringify(req.body, null, 4));
@@ -58,7 +58,6 @@ function register(callback) {
58
58
  timestamp: service.timestamp,
59
59
  autoprovision: service.autoprovision,
60
60
  explicitAttrs: service.explicitAttrs,
61
- expressionLanguage: service.expressionLanguage,
62
61
  defaultEntityNameConjunction: service.defaultEntityNameConjunction,
63
62
  ngsiVersion: service.ngsiVersion,
64
63
  entityNameExp: service.entityNameExp
@@ -71,7 +71,7 @@ function storeDevice(newDevice, callback) {
71
71
  * @param {String} service Service of the device to remove.
72
72
  * @param {String} subservice Subservice inside the service for the removed device.
73
73
  */
74
- function removeDevice(id, service, subservice, callback) {
74
+ function removeDevice(id, apikey, service, subservice, callback) {
75
75
  const services = Object.keys(registeredDevices);
76
76
 
77
77
  for (let i = 0; i < services.length; i++) {
@@ -141,7 +141,7 @@ function listDevices(type, service, subservice, limit, offset, callback) {
141
141
  });
142
142
  }
143
143
 
144
- function getDevice(id, service, subservice, callback) {
144
+ function getDevice(id, apikey, service, subservice, callback) {
145
145
  if (registeredDevices[service] && registeredDevices[service][id]) {
146
146
  callback(null, registeredDevices[service][id]);
147
147
  } else {
@@ -55,7 +55,6 @@ const attributeList = [
55
55
  'polling',
56
56
  'timestamp',
57
57
  'explicitAttrs',
58
- 'expressionLanguage',
59
58
  'ngsiVersion'
60
59
  ];
61
60
 
@@ -120,13 +119,15 @@ function storeDevice(newDevice, callback) {
120
119
  * @param {String} service Service of the device to remove.
121
120
  * @param {String} subservice Subservice inside the service for the removed device.
122
121
  */
123
- function removeDevice(id, service, subservice, callback) {
122
+ function removeDevice(id, apikey, service, subservice, callback) {
124
123
  const condition = {
125
124
  id,
126
125
  service,
127
126
  subservice
128
127
  };
129
-
128
+ if (apikey) {
129
+ condition.apikey = apikey;
130
+ }
130
131
  logger.debug(context, 'Removing device with id [%s]', id);
131
132
 
132
133
  Device.model.deleteOne(condition, function (error) {
@@ -176,15 +177,15 @@ function listDevices(type, service, subservice, limit, offset, callback) {
176
177
  query.skip(parseInt(offset, 10));
177
178
  }
178
179
 
179
- async.series([query.exec.bind(query), Device.model.countDocuments.bind(Device.model, condition)], function (
180
- error,
181
- results
182
- ) {
183
- callback(error, {
184
- count: results[1],
185
- devices: results[0]
186
- });
187
- });
180
+ async.series(
181
+ [query.exec.bind(query), Device.model.countDocuments.bind(Device.model, condition)],
182
+ function (error, results) {
183
+ callback(error, {
184
+ count: results[1],
185
+ devices: results[0]
186
+ });
187
+ }
188
+ );
188
189
  }
189
190
 
190
191
  function findOneInMongoDB(queryParams, id, callback) {
@@ -212,17 +213,21 @@ function findOneInMongoDB(queryParams, id, callback) {
212
213
  * Internal function used to find a device in the DB.
213
214
  *
214
215
  * @param {String} id ID of the Device to find.
216
+ * @param {String} Apikey Apikey of the Device to find.
215
217
  * @param {String} service Service the device belongs to (optional).
216
218
  * @param {String} subservice Division inside the service (optional).
217
219
  */
218
- function getDeviceById(id, service, subservice, callback) {
219
- const queryParams = {
220
+ function getDeviceById(id, apikey, service, subservice, callback) {
221
+ let queryParams = {
220
222
  id,
221
223
  service,
222
224
  subservice
223
225
  };
226
+ if (apikey) {
227
+ queryParams.apikey = apikey;
228
+ }
224
229
  context = fillService(context, queryParams);
225
- logger.debug(context, 'Looking for device with id [%s].', id);
230
+ logger.debug(context, 'Looking for device with id [%s] and queryParams [%j].', id, queryParams);
226
231
  findOneInMongoDB(queryParams, id, callback);
227
232
  }
228
233
 
@@ -233,10 +238,17 @@ function getDeviceById(id, service, subservice, callback) {
233
238
  * @param {String} service Service the device belongs to.
234
239
  * @param {String} subservice Division inside the service.
235
240
  */
236
- function getDevice(id, service, subservice, callback) {
237
- getDeviceById(id, service, subservice, function (error, data) {
241
+ function getDevice(id, apikey, service, subservice, callback) {
242
+ getDeviceById(id, apikey, service, subservice, function (error, data) {
238
243
  if (error) {
239
- callback(error);
244
+ // Try without apikey: apikey will be added to device later
245
+ getDeviceById(id, null, service, subservice, function (error, data) {
246
+ if (error) {
247
+ callback(error);
248
+ } else {
249
+ callback(null, data);
250
+ }
251
+ });
240
252
  } else {
241
253
  callback(null, data);
242
254
  }
@@ -285,7 +297,7 @@ function getByName(name, service, servicepath, callback) {
285
297
  */
286
298
  function update(device, callback) {
287
299
  logger.debug(context, 'Storing updated values for device [%s]:\n%s', device.id, JSON.stringify(device, null, 4));
288
- getDeviceById(device.id, device.service, device.subservice, function (error, data) {
300
+ getDevice(device.id, device.apikey, device.service, device.subservice, function (error, data) {
289
301
  if (error) {
290
302
  callback(error);
291
303
  } else {
@@ -303,6 +315,7 @@ function update(device, callback) {
303
315
  data.registrationId = device.registrationId;
304
316
  data.explicitAttrs = device.explicitAttrs;
305
317
  data.ngsiVersion = device.ngsiVersion;
318
+ data.timestamp = device.timestamp;
306
319
 
307
320
  /* eslint-disable-next-line new-cap */
308
321
  const deviceObj = new Device.model(data);