fix: tedge flows cli loads mapper specific builtin transformers#4020
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
Robot Results
|
0d0d408 to
932fbea
Compare
ef26ec3 to
940b101
Compare
|
@didier-wenzek After trying out the new functionality, I'd be happy merging it as is as it satisfies the main requirements. Below shows what does and doesn't work. Main Requirements
Nice to haves (which currently don't work) The following doesn't work, but more due to the fact that the builtin functions like
If the above requirement could be made to work by providing some context on the command line, then that might be good enough. Otherwise, if it is too much effort then we can postpone this part. |
Yeah, this is why the system tests are a bit involved by an helper flow that feeds the context with entity metadata published over MQTT.
This should be straightforward. I will a |
| pub fn load_builtin_transformers(flows: &mut impl FlowRegistryExt) { | ||
| c8y_mapper_ext::load_builtin_transformers(flows); | ||
| az_mapper_ext::load_builtin_transformers(flows); | ||
| aws_mapper_ext::load_builtin_transformers(flows); |
There was a problem hiding this comment.
todo: as it is now, it breaks conditional compilation (e.g. cargo check -p tedge-mapper --no-default-features --features aws for only aws mapper), but should be easy to fix with #[cfg(...)] attributes. What's interesting though is we're not testing that configuration in CI, so all the tests pass.
| [package] | ||
| name = "az_mapper_ext" | ||
| description = "thin-edge aws extension adding support for azure data model" | ||
| description = "thin-edge extension adding support for azure data model" |
| Install Flow | ||
| [Arguments] ${directory} | ||
| ${start} Get Unix Timestamp | ||
| Execute Command sleep 0.1 | ||
| ThinEdgeIO.Transfer To Device ${CURDIR}/${directory}/* /etc/tedge/mappers/local/flows/${directory}/ | ||
| Execute Command ls -lh /etc/tedge/mappers/local/flows/${directory} | ||
| Should Have MQTT Messages | ||
| ... topic=te/device/main/service/tedge-mapper-local/status/flows | ||
| ... date_from=${start} | ||
| ... message_contains=${directory} |
There was a problem hiding this comment.
suggestion: very similar to Install Flow in main tedge_flows suite, we could extract it to a shared resource file
Added 9080896 |
| Test c8y specific transformers with tedge flows cli and initial context | ||
| Install Flow custom-measurements | ||
| ${transformed_msg} Execute Command | ||
| ... tedge flows test te/device/main///m/environment '{"temperature": 258}' --context '{ "device/main//": {"@id":"raspberry-007","@type":"device","@topic-id":"device/main//","@name":"raspberry-007","@type-name":"thin-edge"} }' |
There was a problem hiding this comment.
Just for clarity, which scope is the context added to on the JavaScript level? I was half expecting to see either a flow, script, or mapper in the keys
There was a problem hiding this comment.
The runtime can only inject values in the mapper context. So this is implied.
There was a problem hiding this comment.
I'm having a problem getting the test code to work for the c8y mapper and a child device.
I'm re-using the context.json you have in the test files.
# works
$ tedge flows test --mapper c8y te/device/main///m/environment '{"temperature": 42}' --context ./context.json
[c8y/measurement/measurements/create] {"temperature":{"temperature":{"value":42.0}},"time":"2026-03-19T15:44:53.991Z","type":"environment"}
# no output
$ tedge flows test --mapper c8y te/device/child-xyz///m/environment '{"temperature": 42}' --context ./context.json
I'm assuming something is just missing from the context object which is required when mapping data for a child device, but I'm not sure what.
This is the context.json that I'm using (copied from the test)
$ cat context.json
{
"device/main//": {
"@id":"raspberry-007",
"@type":"device",
"@topic-id":"device/main//",
"@name":"raspberry-007",
"@type-name":"thin-edge"
},
"device/child-xyz//": {
"@id":"raspberry-007-child-xyz",
"@type":"child-device",
"@topic-id":"device/child-xyz//",
"@name":"child-xyz",
"@type-name":"thin-edge"
}
}There was a problem hiding this comment.
After doing some more digging, it seems the cache-early-messages is the step which is causing the messages for child entities to be discarded (in this case probably cached).
There was a problem hiding this comment.
After doing some more digging, it seems the
cache-early-messagesis the step which is causing the messages for child entities to be discarded (in this case probably cached).
Oh yeah. The cache-early-messages awaits for a child birth message before releasing the measurements to the next step. => We really need to document all these builtin-transformers.
There was a problem hiding this comment.
The latest commit adds the example that I was after. Being able to replay multiple input messages is a very useful feature!
9080896 to
ca518d1
Compare
| - `{ builtin = "update-context", config.topics = "te/+/+/+/+/m/+/meta" }` | ||
| - If a message doesn't match the configured topic, this message is passed unchanged to the subsequent transformation steps. | ||
|
|
||
| ### `into-c8y-alarms` |
There was a problem hiding this comment.
Starting with alarms. I will add sections for measurements and events, after a first series of comments.
| - The default for the Cumulocity mapper is to publish birth messages on `te/device/main/service/tedge-mapper-c8y/status/entities` | ||
| - This is configurable. A custom mapper (which topic id is `a/b/c/d`) is expected to publish finalized entity registration | ||
| on `te/a/b/c/d/status/entities`. | ||
| - A birth message is composed of |
There was a problem hiding this comment.
Documenting the cache-early-messages transformer and birth messages highlights that something is wonky.
First the config parameter for cache-early-messages should be a topic not a topic-id from which is derived. Why a custom mapper should be forced to publish these messages on a specific topic?
Second and more importantly, the contract is difficult to explain because based on fragile assumptions including another component. This other component is either the c8y mapper or a user-provided flow which is responsible of populating the context before sending birth messages.
- The c8y mapper or a user-provided flow shares entity metadata in the
context.mapper.
And only then emits birth messages for these entities. cache-early-messagesreacts on birth messages releasing any message cached for these entities.
assuming blindly that the cache is actually properly populated for those.- The step downstream proceeds transforming the messages released by the birth messages;
but discarding them if step one has not be done properly.
I do think this must be fixed. I propose the following:
- Deprecate birth messages before release 1.8. This is a fragile mechanism aimed to signal the context is populated but not directly related to the context.
- Add an
onContextUpdatecallback to flow scripts and transformers. This will be called when thecontext.mapperis updated. - Re-implement
cache-early-messagesto leverageonContextUpdatecallbacks to release cached messages when the context is actually populated and not when a tier says it.
There was a problem hiding this comment.
Though we might need to talk about how the onContextUpdate handler would work, and if it would react from any changes in the context, or just a subset, and what order is the handler called etc....though it does sound interesting a slightly more fitting for what we are using it for (in this case at least)
reubenmiller
left a comment
There was a problem hiding this comment.
A very nice improvement to be able to run flows in other mappers and make it easier to run the tedge flows list and tedge flows test against any mappers (even though mappers like c8y require a bit more of a setup)
f28517b to
56a1f00
Compare
Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
…t value When shared by all clouds the cache-early-messages transformer can no more be configured with a mapper topic id when added to the transformer registry. This topic id must be configured by the flows. Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
The key point is to generate birth-messages for the entities which metadata have been stored in the flows mapper context. The `cache-early-messages` transformer push then downstream the measurements cached for these entities. Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
56a1f00 to
7a74894
Compare
Proposed changes
tedge flowsloads c8y specific builtin transformerstedge flows test --context <path-to-or-inlined-json>initializes the tests context with a JSON objectThis raises several questions:
tedgebinary size as this executable already includes all the daemons and mapper variants.Types of changes
Paste Link to the issue
#3992
Checklist
just prepare-devonce)just formatas mentioned in CODING_GUIDELINESjust checkas mentioned in CODING_GUIDELINESFurther comments