Support all SOVD resource collections in cyclic subscriptions#254
Merged
Support all SOVD resource collections in cyclic subscriptions#254
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds generalized cyclic subscription support across all SOVD resource collections (plus x-* vendor extensions) by introducing registries for resource samplers and transport providers, and refactoring SSE streaming into a dedicated transport provider.
Changes:
- Introduces
ResourceSamplerRegistry(thread-safe) andTransportRegistry(protocol-keyed) with plugin registration hooks. - Refactors cyclic subscription creation to accept
{collection, resource_path}from generalizedparse_resource_uri()(with traversal protection) and to start delivery via transport providers. - Adds unit + integration tests covering registries, URI parsing, on-removed lifecycle hook, and multi-collection subscription flows.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ros2_medkit_integration_tests/test/features/test_multi_collection_subscriptions.test.py | New integration tests validating create/error cases across multiple collections and protocols. |
| src/ros2_medkit_gateway/test/test_transport_registry.cpp | New unit tests for transport registry lookup and shutdown behavior. |
| src/ros2_medkit_gateway/test/test_subscription_manager.cpp | Updates tests for new create() signature; adds on_removed callback tests. |
| src/ros2_medkit_gateway/test/test_resource_sampler_registry.cpp | New unit tests for sampler registration rules and concurrency. |
| src/ros2_medkit_gateway/test/test_cyclic_subscription_handlers.cpp | Adds parse_resource_uri test coverage for multiple collections and traversal rejection. |
| src/ros2_medkit_gateway/src/subscription_transport.cpp | Implements basic transport registry and shutdown_all delegating to SubscriptionManager. |
| src/ros2_medkit_gateway/src/subscription_manager.cpp | Extends subscription info fields; adds on_removed hook; updates remove/expiry/shutdown lifecycle. |
| src/ros2_medkit_gateway/src/resource_sampler.cpp | Implements thread-safe sampler registry with builtin/plugin registration policies. |
| src/ros2_medkit_gateway/src/plugins/plugin_manager.cpp | Adds plugin APIs to register samplers/transports and wires registries into PluginManager. |
| src/ros2_medkit_gateway/src/http/rest_server.cpp | Injects sampler/transport registries into cyclic subscription handlers; uses node-provided SSE tracker. |
| src/ros2_medkit_gateway/src/http/handlers/sse_transport_provider.cpp | New SSE transport provider extracting former handler streaming logic and invoking samplers safely. |
| src/ros2_medkit_gateway/src/http/handlers/cyclic_subscription_handlers.cpp | Generalizes resource URI parsing; validates collection/protocol; starts delivery via transport provider. |
| src/ros2_medkit_gateway/src/gateway_node.cpp | Initializes registries, built-in samplers/transports, lifecycle wiring, and shutdown ordering. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/subscription_transport.hpp | New transport provider interface and registry. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/subscription_manager.hpp | Updates CyclicSubscriptionInfo; new create() signature; adds on_removed callback API. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/resource_sampler.hpp | New sampler function type + thread-safe sampler registry interface. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/plugins/plugin_manager.hpp | Exposes plugin APIs for sampler/transport registration + registry wiring. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/handlers/sse_transport_provider.hpp | Declares SSE transport provider implementation. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/handlers/cyclic_subscription_handlers.hpp | Adds ParsedResourceUri and parse_resource_uri() API; injects registries. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/error_codes.hpp | Adds vendor-specific error codes for URI/collection/protocol validation. |
| src/ros2_medkit_gateway/include/ros2_medkit_gateway/gateway_node.hpp | Exposes registries and shared SSE client tracker from GatewayNode. |
| src/ros2_medkit_gateway/CMakeLists.txt | Adds new sources and unit tests to build/test targets. |
src/ros2_medkit_gateway/src/http/handlers/cyclic_subscription_handlers.cpp
Outdated
Show resolved
Hide resolved
src/ros2_medkit_gateway/include/ros2_medkit_gateway/subscription_manager.hpp
Outdated
Show resolved
Hide resolved
src/ros2_medkit_gateway/include/ros2_medkit_gateway/subscription_manager.hpp
Show resolved
Hide resolved
src/ros2_medkit_gateway/src/http/handlers/cyclic_subscription_handlers.cpp
Outdated
Show resolved
Hide resolved
src/ros2_medkit_gateway/src/http/handlers/cyclic_subscription_handlers.cpp
Show resolved
Hide resolved
src/ros2_medkit_gateway/include/ros2_medkit_gateway/subscription_transport.hpp
Outdated
Show resolved
Hide resolved
07177d0 to
869d745
Compare
bburda
added a commit
that referenced
this pull request
Mar 6, 2026
- Guard substr(0,2) against empty collection strings (Copilot #1) - Use segment-based path traversal check instead of substring matching, allowing benign paths like '/..foo' while still rejecting '/..' segments (Copilot #2,#7) - Add thread-safety to TransportRegistry via shared_mutex (Copilot #10) - Reject duplicate transport protocol registration (Copilot #6) - Validate data collection requires resource_path (topic name) (Copilot #8) - Document set_on_removed() init-only constraint for thread safety (Copilot #3,#4) - Explain SSE stop() behavior in comments (Copilot #5) - Remove redundant subscription_mgr_->shutdown() call in destructor (Copilot #11) - Fix shutdown_all() docstring to match delegation pattern (Copilot #9) - Fix clang-tidy: use const ref for captured_sub_id (CI failure)
src/ros2_medkit_gateway/src/http/handlers/cyclic_subscription_handlers.cpp
Outdated
Show resolved
Hide resolved
...s2_medkit_gateway/include/ros2_medkit_gateway/http/handlers/cyclic_subscription_handlers.hpp
Outdated
Show resolved
Hide resolved
...s2_medkit_gateway/include/ros2_medkit_gateway/http/handlers/cyclic_subscription_handlers.hpp
Show resolved
Hide resolved
RuntimeLayer filtered areas and components by namespace blacklist but not apps - nodes in blacklisted namespaces still appeared as gap-fill apps. Extract namespace from bound_fqn and filter accordingly.
f781c62 to
be593c9
Compare
mfaferek93
reviewed
Mar 7, 2026
src/ros2_medkit_gateway/include/ros2_medkit_gateway/models/entity_types.hpp
Show resolved
Hide resolved
- Add null guard for native_sampler in data collection sampler - Add TOCTOU guard in fault sampler when entity vanishes between lookups - Add bounds validation for sse.max_duration_sec parameter - Clarify stop() contract in SubscriptionTransportProvider docstring to document shutdown ordering dependency for HTTP-based transports
mfaferek93
approved these changes
Mar 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make cyclic subscriptions work with any SOVD resource collection (data, faults, configurations, communication-logs) and vendor extensions (
x-*prefix), instead of being hard-coded to/data/only.Key changes:
x-prefixparse_resource_uri()- extracts entity type, entity ID, collection, and resource path from any valid SOVD resource URI with path traversal protectionCyclicSubscriptionInfo- replacedtopic_namewithcollection+resource_pathfieldson_removedcallback - SubscriptionManager lifecycle hook for transport cleanup on remove/expire/shutdownregister_resource_sampler()andregister_transport()for plugin-provided collections and transportsIssue
Type
Testing
test_resource_sampler_registry.cpp- 7 tests (register, lookup, builtin overwrite, plugin reject, concurrent access)test_transport_registry.cpp- 3 tests (register/lookup, missing transport, shutdown_all)test_cyclic_subscription_handlers.cpp- 11 new ParseResourceUri tests (all collections, vendor extensions, entity types, path traversal, invalid URIs)test_subscription_manager.cpp- 3 new on_removed callback tests (remove, expire, shutdown)test_multi_collection_subscriptions.test.py- 8 tests (data/faults/configurations create, unsupported collection, invalid URI, entity mismatch, unsupported protocol, path traversal)Checklist