Skip to content

fix: c8y mapper panics on unexpected registration message#3134

Merged
didier-wenzek merged 2 commits intothin-edge:mainfrom
didier-wenzek:fix/panic-on-service-using-device-topic
Sep 25, 2024
Merged

fix: c8y mapper panics on unexpected registration message#3134
didier-wenzek merged 2 commits intothin-edge:mainfrom
didier-wenzek:fix/panic-on-service-using-device-topic

Conversation

@didier-wenzek
Copy link
Copy Markdown
Contributor

@didier-wenzek didier-wenzek commented Sep 24, 2024

The mapper panics when receiving a registration message such as 'te/device/child02//' '{"@type":"service"}'.

The issue is that:

  • the entity is seen as a child device i.e. matching device/+//
  • but its registration message pretends that this is a service.
  • the mapper tries then to register the entity as its own parent.

Proposed changes

When the type of entity is explicitly set to be a service, but the topic id is attached to a child device (according to the default scheme), then this entity must be considered as non-following the default scheme.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (general improvements like code refactoring that doesn't explicitly fix a bug or add any new functionality)
  • Documentation Update (if none of the other choices apply)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Paste Link to the issue

#2986

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA (in all commits with git commit -s)
  • I ran cargo fmt as mentioned in CODING_GUIDELINES
  • I used cargo clippy as mentioned in CODING_GUIDELINES
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Further comments

@codecov
Copy link
Copy Markdown

codecov bot commented Sep 24, 2024

Codecov Report

Attention: Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/core/tedge_api/src/mqtt_topics.rs 87.50% 1 Missing ⚠️
Additional details and impacted files

📢 Thoughts on this report? Let us know!

.parent
.clone()
.or_else(|| topic_id.default_parent_identifier())
.or_else(|| topic_id.default_service_parent_identifier())
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first attempt as been to rewrite TopicId::default_parent_identifier along the following lines:

    /// Returns the topic identifier of the parent of an entity
    pub fn default_parent_identifier(&self) -> Option<Self> {
        match self.0.split('/').collect::<Vec<&str>>()[..] {
            ["device", "main", "", ""] => None,
            ["device", _, "", ""] => Some("main"),
            ["device", parent_id, "service", _] => Some(parent_id),
            _ => None,
        }
        .map(|parent_id| EntityTopicId(format!("device/{parent_id}//")))
    }

Indeed the current behavior of this function is weird (the parent of a child device is the child itself) and doesn't match is doc comment.

However, my proposal matches the doc comment but makes fail 35 unit tests!

@albinsuresh any idea on why this is not the correct way to fix this issue?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the current impl of default_parent_identifier seems wrong as it implies that the parent of device/child1// is child1 which doesn't make any sense. That logic only applies to service entities following the default topic scheme. So, the new function that you've added is correct and named appropriately. I'd drop the old one in favour of the new one.

Copy link
Copy Markdown
Contributor

@albinsuresh albinsuresh Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the test failures (I looked at some, not all), it's coming from the auto-registration logic that tries to auto-register device/child1// entity when a message like te/device/child1///m/temp is received. That auto-registration logic relies on the same default_parent_identifier function to extract the source entity topic id from the incoming message topic. In this case, they're not looking for the "parent", but the "source" entity itself. So, the current default_parent_identifier function can be renamed to default_source_entity_identifier to better reflect that logic. The newly added function can be used to extract the "parent" of a "service" as done in this PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, they're not looking for the "parent", but the "source" entity itself.

That's really confusing but is aligned with the code (returning self for child devices and the parent for a service).

=> I will fix the name and the doc comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> I will fix the name and the doc comment.

Done: c24e633

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Sep 24, 2024

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
506 0 2 506 100 1h33m48.47128s

@didier-wenzek didier-wenzek added bug Something isn't working theme:registration Theme: Device registration and device certificate related topics labels Sep 25, 2024
Copy link
Copy Markdown
Member

@rina23q rina23q left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but test seems missing. I'm not sure which level of test is suitable for this though. Maybe adding a system test to registration_lifecycle?
I can add a test there if you like.


Done in 5b5147f


# Registered as child device
Execute Command tedge mqtt pub --retain 'te/device/child2/service/foo' '{"@type":"child-device"}'
Device Should Exist ${DEVICE_SN}:device:child2:service:foo
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I do think the test should fail ... but it doesn't.

Indeed, 'te/device/child2/service/foo' '{"@type":"child-device"}' registers a child device on a service topic.

@albinsuresh Is this expected or a side effect of auto-registration?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though shouldn't auto registration only kick in if you are not registration something...here it is explicitly registering a given type, so there is no need to try to auto detect anything.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this is what happens: no auto registration kicks in. That's a just bit confusing because applied on a topic matching auto registration requirements.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes @reubenmiller is right. Auto-registration kicks in only when the source entity for a message isn't explicitly registered up-front. But, since there is an explicit registration happening here, it just doesn't kick in. In fact we advise the users to disable auto-registration if they decide to use explicit registration for any entities.

We don't prevent the users from re-using the default topic scheme while doing explicit registrations either, but yeah it can result in such unexpected/uncommon usages as well. Not sure if we should completely prevent it, as the default topic scheme still provides a starting point/guidance.

Copy link
Copy Markdown
Contributor

@albinsuresh albinsuresh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

didier-wenzek and others added 2 commits September 25, 2024 16:46
When the type of entity is explicitly set to be a service,
but the topic id is attached to a child device (according to the default
scheme), then this entity must be considered as non-following the
default scheme.

Signed-off-by: Didier Wenzek <didier.wenzek@free.fr>
Signed-off-by: Rina Fujino <rina.fujino.23@gmail.com>
@didier-wenzek didier-wenzek force-pushed the fix/panic-on-service-using-device-topic branch from 515cb7b to c8e9c29 Compare September 25, 2024 14:48
@didier-wenzek didier-wenzek added this pull request to the merge queue Sep 25, 2024
Merged via the queue into thin-edge:main with commit 7465430 Sep 25, 2024
@didier-wenzek didier-wenzek deleted the fix/panic-on-service-using-device-topic branch September 25, 2024 15:46
@github-actions github-actions bot mentioned this pull request Dec 5, 2024
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working theme:registration Theme: Device registration and device certificate related topics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants