thin-edge / thin-edge.io

The open edge framework for lightweight IoT devices
https://thin-edge.io
Apache License 2.0
223 stars 55 forks source link

c8y-configuration-plugin: should not send anything to c8y if configuration is requested locally #1923

Closed toewsar closed 1 year ago

toewsar commented 1 year ago

Describe the bug If the confiiguration is requested from anywhere else than from c8y the c8y-configuration-plugin still sends the operation status to c8y.

To Reproduce Send a dummy response: mosquitto_pub -t tedge/{child-id}/commands/res/config_snapshot -m '{"type": "myconfig"}'

The c8y-configuration-plugin will then send

c8y/s/us/{child-id} 501,c8y_UploadConfigFile
c8y/s/us/{child-id} 502,c8y_UploadConfigFile,"Failed to parse response from child device with: missing field `path` at line 1 column 21"

to cumulocity whether the request comes from cumulocity or not.

Expected behavior c8y-configuration-plugin does nothing if no request from cumulocity is pending or if the payload does not match the expected one.

Environment (please complete the following information):

reubenmiller commented 1 year ago

@toewsar Technically the c8y-configuration-plugin is only for Cumulocity based configuration file operations, hence why it is also sending some c8y related commands (as that is part of the Cumulocity interface when handling such operations).

However I believe what you're asking for is that the c8y-configuration-plugin should be changed to tedge-configuration-plugin and use a generic operation model which is then translated into cloud messages by the cloud mapper (rather than then configuration plugin directly(similar to thetedge/measurement` format, but for operations). This is indeed our goal, however we need a more detailed design into just a topic, and to see how feasible it would be for cloud mappers to adjust to different mechanisms which might or might not exist on each cloud interface (e.g. one mechanism that comes to mind is the file uploaded, some cloud providers might not even support this out of the box).

toewsar commented 1 year ago

@reubenmiller No, sry, you missunderstand me. What I'm reporting is, that the c8y-configuration-plugin listens on tedge/+/commands/res/config_snapshot and sends a SR c8y/s/us/{child-id} 501 to cumulocity even if I request the configuration from comandline.

Maybe some more details of my use case: I'm running thin-edge also as websocket server and want to configure my thin-edge childs via MQTT. My childs implement the tedge/{child-id}/commands interface and I wanted to use the same interface with mit WebUI, but as soon as my child responds the c8y-configuration-plugin feels responsible for this response.

My Workaround is to implement a second interface on {child-id}/commands instead of tedge/{child-id}/commands.

reubenmiller commented 1 year ago

@toewsar ah ok. Technically sending the operation update commands to c8y (e.g. 501, 502, 503) will not cause any harm if you don't have any pending operations on the cloud side...however semantically it does seem strange updating a non-existent cloud operation.

Though we're looking at transitioning from the id-less operation handling to using operation id (https://github.com/thin-edge/thin-edge.io/issues/1718), which would then enable this use-case very easily...For example, we could only send the operation status updates back to the cloud if there is in-fact an operation id, otherwise we could add a new fragment which indicates that the operation should not send status updates to the cloud.

toewsar commented 1 year ago

@reubenmiller or you skip updating the operation, if the res does not match

{
    "status": "executing",
    "type": "{config-type}",
    "path": "/child/local/fs/path" 
}

or just misses the path or status fragment.

reubenmiller commented 1 year ago

@toewsar, this is now possible in thin-edge.io 0.13.0 using the new more generic components (e.g. tedge-configuration-plugin) and the utilization of the new MQTT v1 api.

You can read about the new command api to better understand the mechanics.

However here is a short example how to locally request a config_snapshot using the command line:

  1. In console 1, subscribe to the local command requests

    tedge mqtt sub 'te/device/main///cmd/config_snapshot/+'
  2. In console 2, request the snapshot using the new thin-edge.io te/ topics using a retained message

    tedge mqtt pub -r \
        te/device/main///cmd/config_snapshot/local-1 \
        '{"status":"init","tedgeUrl":"http://127.0.0.1:8000/tedge/file-transfer/main/config_snapshot/local-1111","type":"tedge-configuration-plugin"}'

    The last part local-1 can be anything unique for the topic. Convention is to use a known prefix to distinguish it from other mappers. The prefix is also used to indicate if the appropriate mapper should send operation transitions or not...so as long as you don't use c8y-xxxxx, you should be fine.

  3. View the mqtt messages received in console 1

    [te/device/main///cmd/config_snapshot/local-1] {"status":"init","tedgeUrl":"http://127.0.0.1:8000/tedge/file-transfer/main/config_snapshot/local-1111","type":"tedge-configuration-plugin"}
    [te/device/main///cmd/config_snapshot/local-1] {"status":"executing","tedgeUrl":"http://127.0.0.1:8000/tedge/file-transfer/main/config_snapshot/local-1111","type":"tedge-configuration-plugin"}
    [te/device/main///cmd/config_snapshot/local-1] {"status":"successful","tedgeUrl":"http://127.0.0.1:8000/tedge/file-transfer/main/config_snapshot/local-1111","type":"tedge-configuration-plugin","path":"/etc/tedge/plugins/tedge-configuration-plugin.toml"}
  4. In console 1, read the message where the status is successful and request the file contents of the file from the tedgeUrl

    curl http://127.0.0.1:8000/tedge/file-transfer/main/config_snapshot/local-1111
  5. Acknowledge the response of the command by publishing an empty retained message to the same topic. It should only be done by the requestor

    tedge mqtt pub -r 'te/device/main///cmd/config_snapshot/local-1' ''