Skip to content

Commit bae5ffd

Browse files
authored
[#109] Discovery: Add YAML Manifest as a static source of entity discovery (#118)
* refactor(discovery): reorganize module structure for manifest support Refactored discovery-related code into dedicated discovery/ subfolder. Changes: - Created discovery/ subfolder with modular structure - Implemented DiscoveryStrategy interface (Strategy Pattern) - Extracted RuntimeDiscoveryStrategy from DiscoveryManager - Split models.hpp into discovery/models/{area,component,app,function,common}.hpp - Added new fields to Area and Component models (name, description, tags, etc.) - Created stub App and Function models for future manifest support - Moved area_handlers and component_handlers to http/handlers/discovery/ - Created stub app_handlers and function_handlers - Updated CMakeLists.txt with new file paths - Maintained backward compatibility via include redirects The DiscoveryManager now acts as an orchestrator using the strategy pattern, delegating to RuntimeDiscoveryStrategy for ROS 2 graph-based discovery. Future strategies (ManifestDiscoveryStrategy, HybridDiscoveryStrategy) can be added without changing the interface. * feat(discovery): implement App and Function models - Add full App struct with RosBinding, runtime state, and resources - Add full Function struct with hosts and depends_on relationships - Implement to_json(), to_entity_reference(), to_capabilities() for all models - Add to_capabilities() method to Area model - Create app.cpp and function.cpp with serialization implementations - Add unit tests for discovery model serialization * feat(discovery): add manifest parser and validator - Add ManifestParser for loading YAML manifests into internal structures - Add ManifestValidator with validation rules R001-R011: - R001: Version must be '1.0' - R002-R005: Unique IDs for all entity types - R006: Valid area/parent references - R007: App must reference existing component - R008: depends_on references validation (warning) - R009: hosts references validation (warning) - R010: No duplicate ROS bindings - R011: Circular dependency detection - Add Manifest, ManifestConfig, ManifestMetadata structs - Add ValidationError and ValidationResult for error reporting - Add unit tests covering all validation rules * feat(gateway): implement ManifestManager for manifest lifecycle Add ManifestManager class for thread-safe manifest loading, validation, and entity access: - load_manifest(path, strict) / load_manifest_from_string(yaml, strict) - reload_manifest() / unload_manifest() for lifecycle management - Entity access: get_areas(), get_components(), get_apps(), get_functions() - O(1) lookup by ID via index maps - Relationship queries: get_components_for_area(), get_apps_for_component(), get_hosts_for_function(), get_subareas(), get_subcomponents() - get_status_json() for REST API integration - Thread-safe with std::mutex protection * feat(discovery): add RuntimeLinker for manifest-to-runtime binding Implement RuntimeLinker class that binds manifest-declared Apps to actual ROS 2 nodes discovered at runtime: - Exact match: node_name + namespace both match - Wildcard namespace: namespace='*' matches any namespace - Topic namespace: topic_namespace prefix matches node's topics - Enriches linked apps with runtime data (topics, services, actions) - Detects orphan nodes (runtime nodes not in manifest) - Applies orphan policy: ignore/warn/error/include_as_orphan - Provides lookup methods: is_app_online(), get_bound_node(), get_app_for_node() * feat(discovery): add HybridDiscoveryStrategy and multi-mode support Implement discovery mode configuration for DiscoveryManager: - DiscoveryMode enum: RUNTIME_ONLY, MANIFEST_ONLY, HYBRID - DiscoveryConfig struct for initialization parameters - initialize() method for deferred configuration - HybridDiscoveryStrategy combining manifest + runtime linking DiscoveryManager now supports: - Entity lookup by ID: get_area(), get_component(), get_app(), get_function() - Relationship queries: get_subareas(), get_subcomponents(), get_components_for_area(), get_apps_for_component(), get_hosts_for_function() - Manifest management: get_manifest_manager(), reload_manifest() - Mode switching with fallback to runtime on manifest load failure HybridDiscoveryStrategy features: - Uses manifest as source of truth for entity IDs - Links Apps to runtime nodes via RuntimeLinker - Enriches manifest components with runtime topics/services/actions - Handles orphan nodes per ManifestConfig policy Backward compatible: default RUNTIME_ONLY mode behaves identically to before. * feat(api): implement apps REST API endpoints - Add AppHandlers with 6 endpoint handlers: - GET /apps - list all apps - GET /apps/{id} - get app capabilities - GET /apps/{id}/data - list app topics - GET /apps/{id}/data/{data-id} - get specific data item - GET /apps/{id}/operations - list services and actions - GET /apps/{id}/configurations - list app parameters - Register app routes in RestServer - Include HATEOAS links and capabilities in responses * feat(api): implement functions REST API endpoints - Add FunctionHandlers with 5 endpoint handlers: - GET /functions - list all functions - GET /functions/{id} - get function capabilities - GET /functions/{id}/hosts - get apps that host this function - GET /functions/{id}/data - aggregated data from host apps - GET /functions/{id}/operations - aggregated operations from hosts - Register function routes in RestServer - Include HATEOAS links and capabilities in responses * feat(api): implement SOVD relationship endpoints - Add area relationship handlers: - GET /areas/{id}/subareas - list nested areas - GET /areas/{id}/related-components - list components in area - Add component relationship handlers: - GET /components/{id}/subcomponents - list nested components - GET /components/{id}/related-apps - list apps on component - Register 4 new routes in RestServer - Include HATEOAS links in all responses * feat(api): implement entity capabilities builder - Add CapabilityBuilder utility class with Capability enum - Add LinksBuilder fluent API for HATEOAS links - Implement GET /areas/{area_id} endpoint with capabilities - Implement GET /components/{component_id} endpoint with capabilities - Refactor app_handlers and function_handlers to use builders - Add unit tests for capability_builder utilities - All handlers now return SOVD-compliant capabilities arrays * docs: add manifest discovery documentation and examples Documentation: - Add user guide: docs/tutorials/manifest-discovery.rst - Add schema reference: docs/config/manifest-schema.rst - Add migration guide: docs/tutorials/migration-to-manifest.rst - Create new docs/config section for configuration references - Update docs/index.rst with Configuration section Example manifests: - turtlebot3_manifest.yaml - Nav2 navigation stack example - minimal_manifest.yaml - Simplest possible template - multi_robot_manifest.yaml - Fleet management with namespaces - demo_nodes_manifest.yaml - Integration testing manifest Also fixes copyright headers to 2026 bburda in new source files * fix: resolve doc references and compiler warnings - Fix :doc: references in manifest-schema.rst to use /tutorials/ prefix - Update broken external links in manifest-discovery.rst - Add missing field initializers for ServiceInfo and ActionInfo in tests * refactor: rename sovd_version to manifest_version in docs and examples - Update schema reference docs to use manifest_version - Update user guide and migration tutorial - Update all example manifest YAML files - Fix doc references and broken links - Fix compiler warnings in test_runtime_linker.cpp The C++ code already used manifest_version internally. This change removes direct SOVD naming from manifest schema. * feat(gateway): Add more integration tests and fix API issues API Changes: - Changed list endpoints to return SOVD-compliant format: {\"items\": [...], \"total_count\": N} instead of raw arrays - Updated /areas, /areas/{id}/components, /components endpoints Manifest Parser Fixes: - Added recursive subarea parsing with parent_area_id tracking - Fixed Function parsing: use 'hosted_by' field (was 'hosts') - Added Component 'type' field parsing from manifest YAML Manifest Manager Fixes: - get_components_for_area() now includes components from all subareas - Hierarchical lookup collects all descendant area IDs Entity ID Validation: - Allow hyphens in entity IDs (e.g., 'engine-ecu' from manifests) - Validation regex: alphanumeric, underscore, and hyphen Testing: - Added test_discovery_hybrid.test.py for hybrid mode tests - Added test_discovery_manifest.test.py for manifest-only mode tests - Updated all existing tests for new API response format - Made hybrid runtime tests defensive for flaky scenarios Documentation: - Fixed broken external links in tutorials - Removed non-working GitHub examples links * fix: documentation warnings and test fixes Documentation: - Fix title underline length in manifest-schema.rst Tests: - Rename duplicate test functions in test_discovery_hybrid.test.py to avoid verification.rst ID conflicts - Remove 'component-name' from invalid ID test since hyphens are now allowed in entity IDs (for manifest IDs like 'engine-ecu') Build: - Fix format string warning in fault_manager_node.cpp (%d -> %ld) * eat(gateway): implement app handlers and fix manifest parsing App Handlers: - Implement topic sampling for GET /apps/{id}/data/{data_id} - Implement parameter fetching for GET /apps/{id}/configurations when app has bound runtime node - Related apps endpoint already implemented in component_handlers Manifest Parser: - Fix app parsing: use 'is_located_on' field (was 'component') to match SOVD spec and manifest YAML format Tests: - Add test_app_data_item_endpoint for single data item sampling - Add test_component_related_apps for /components/{id}/related-apps - Add test_component_related_apps_empty and _not_found - Update YAML in unit tests: component -> is_located_on * fix: address PR review comments - Add explanatory comments to empty except clauses - Implement strict validation: ERRORs always fail, strict=false only skips WARNINGs - Fix parser to use 'is_located_on' field name for SOVD OpenAPI compliance - Fix parent_component_id field parsing * fix: correct test_app_component_relationship assertion Test now properly checks _links.is-located-on URL instead of non-existent component_id field in single app response.
1 parent 89d3c70 commit bae5ffd

File tree

69 files changed

+12074
-356
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+12074
-356
lines changed

docs/config/index.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Configuration Reference
2+
=======================
3+
4+
This section contains configuration references for ros2_medkit.
5+
6+
.. toctree::
7+
:maxdepth: 2
8+
9+
manifest-schema
10+
11+
Manifest Configuration
12+
----------------------
13+
14+
:doc:`manifest-schema`
15+
Complete YAML schema reference for SOVD system manifests.
16+
Defines areas, components, apps, and functions for your ROS 2 system.

0 commit comments

Comments
 (0)