Skip to content

Conversation

@bburda
Copy link
Collaborator

@bburda bburda commented Jan 22, 2026

Pull Request

Summary

Implements SOVD API compliance with custom ros2_medkit extensions under the x-medkit field. It represents a significant architectural shift to align with industry standards while preserving ROS 2-specific functionality.

Changes:

  • Introduces SOVD-compliant error handling with standardized error codes and the GenericError schema
  • Implements the x-medkit extension pattern to separate SOVD-compliant fields from ros2_medkit-specific extensions
  • Adds comprehensive entity resource model with thread-safe caching, capabilities validation, and operation aggregation

Issue

Link the related issue (required):


Type

  • Bug fix
  • New feature or tests
  • Breaking change
  • Documentation only

Testing

How was this tested / how should reviewers verify it?


Checklist

  • Breaking changes are clearly described (and announced in docs / changelog if needed)
  • Tests were added or updated if needed
  • Docs were updated if behavior or public API changed

@bburda bburda self-assigned this Jan 22, 2026
@bburda bburda added documentation Improvements or additions to documentation enhancement New feature or request labels Jan 22, 2026
@bburda bburda marked this pull request as ready for review January 23, 2026 16:06
Copilot AI review requested due to automatic review settings January 23, 2026 16:06
bburda added 10 commits January 23, 2026 16:06
- Create error_codes.hpp with SOVD standard and x-medkit vendor error codes
- Update HandlerContext::send_error() to SOVD GenericError format
- Add global error handlers (set_error_handler, set_exception_handler)
- Update all handlers: fault, config, operation, discovery, auth
- Update unit tests and integration tests for new error format
- Vendor errors (x-medkit-*) include vendor_code field
- Add XMedkit fluent builder for clean SOVD/x-medkit separation
- Support ROS2 metadata: node, namespace, type, topic, service, action, kind
- Support discovery metadata: source, is_online, component_id, entity_id
- Support type introspection: type_info, type_schema (ROS2 IDL schemas)
- Support execution tracking: goal_id, goal_status, last_feedback
- Add 27 unit tests for all builder methods
- Faults:
  - Changed 'faults' array to 'items' in list responses
  - Changed 'fault' object to 'item' in single fault response
  - Moved entity_id, source_id, counts to x-medkit extension
  - DELETE /faults/{code} returns 204 No Content
  - Added DELETE /{entity}/faults endpoint for clearing all faults

- Operations:
  - Added SOVD fields: id, proximity_proof_required, asynchronous_execution
  - Moved path, type, kind, type_info to x-medkit extension
  - Added GET /{entity}/operations/{op-id} for operation details
  - Added SOVD executions endpoints:
    - POST /{entity}/operations/{op-id}/executions (202 + Location header)
    - GET /{entity}/operations/{op-id}/executions (list execution IDs)
    - GET /{entity}/operations/{op-id}/executions/{exec-id} (SOVD status)
    - DELETE /{entity}/operations/{op-id}/executions/{exec-id} (204)
  - Status values: running, completed, failed (SOVD ExecutionStatus enum)
Configurations Compliance:
- Updated handle_list_configurations() to return SOVD items array with
  ConfigurationMetaData objects (id, name, type: parameter)
- Updated handle_get_configuration() to return SOVD ReadValue format
  with id, data, and x-medkit extension
- Updated handle_set_configuration() to use SOVD 'data' field (with
  backward compatibility for 'value')
- Updated handle_delete_configuration() to return 204 No Content
- Updated handle_delete_all_configurations() to return 204/207

Data Compliance:
- Added http_utils.hpp utilities for topic ID normalization
  (normalize_topic_to_id, id_to_topic)
- Updated handle_get_app_data() for SOVD ValueMetadata format with
  items array containing id, name, category fields
- Updated handle_get_app_data_item() for SOVD ReadValue format
- Updated handle_component_data() for SOVD items array format
- Updated handle_component_topic_data() for SOVD ReadValue format
- Updated handle_component_topic_publish() for SOVD write response

All handlers now:
- Use 'items' array for collection responses
- Use 'id' and 'data' for single value responses
- Put ROS2-specific data in x-medkit extension
- Return proper HTTP status codes (204 for DELETE success)
…tension

Discovery Compliance:
- Updated all discovery handlers (component, app, area, function) to use
  SOVD-compliant response format with x-medkit vendor extension
- Moved ROS2-specific fields to x-medkit extension:
  - source, is_online, component_id → x-medkit root
  - namespace, topic, direction, type, node → x-medkit.ros2
  - capabilities, parameters → x-medkit (for detailed introspection)
- Added SOVD EntityReference format for list responses:
  - id, name, href (required)
  - description, tags (optional)
- Added SOVD capability URIs as flat fields (data, operations, etc.)
- Changed error responses to use x-medkit instead of parameters

Handler Updates:
- component_handlers.cpp: list/get with x-medkit, subcomponents, related-apps
- app_handlers.cpp: list/get with x-medkit, data items with direction
- area_handlers.cpp: list/get with x-medkit, subareas, components
- function_handlers.cpp: list/get with x-medkit, hosts endpoint
- handler_context.cpp: send_error uses x-medkit for extra params

Test Updates:
- Updated all integration tests to check x-medkit extension
- Updated discovery mode tests (manifest, hybrid, heuristic)
- Updated unit tests for error response format
- Fixed linter issues (flake8, pep257)
- Add /apps/{id}/depends-on endpoint (REQ_INTEROP_009)
- Verify href fields in all list endpoints (REQ_INTEROP_003)
- Verify capability URIs in entity details (REQ_INTEROP_010)
- Add x-medkit extensions with ROS2-specific fields
- Add _links with self href for HATEOAS navigation
- Add 14 integration tests for discovery compliance (test_70-83)
- Expand root endpoint with complete apps and functions endpoints list

Tests: All 33 unit tests pass, all integration tests pass
Add 10 integration tests verifying SOVD compliance for:
- GET /{entity}/operations/{op-id} - operation details (test_84-86, test_93)
- GET /{entity}/operations/{op-id}/executions - list executions (test_87)
- POST /{entity}/operations/{op-id}/executions - start execution (test_88)
- DELETE /{entity}/operations/{op-id}/executions/{exec-id} - cancel execution (test_89)
- DELETE /{entity}/faults - clear all faults (test_90-92)

@verifies REQ_INTEROP_014, REQ_INTEROP_034, REQ_INTEROP_035, REQ_INTEROP_036, REQ_INTEROP_039
- Fix is_internal_service() to use exact suffix matching (avoids false positives)
  e.g., /my_node/get_parameters_backup is now correctly NOT filtered
- Add RCLCPP_WARN_ONCE when synthetic_component_name_pattern missing {area}
- Improve code comments in DiscoveryManager explaining MANIFEST_ONLY mode
- Document synthetic component behavior in heuristic-apps.rst
…e helpers

Replace designated initializers (e.g., Area{.id = "x", .name = "y"}) with
helper functions (make_area, make_component, make_app, make_service, make_action)
to eliminate -Wc++20-extensions and -Wmissing-field-initializers warnings.

This ensures clean builds in C++17 mode without changing test behavior.
All 40 entity resource model tests pass.
Add integration tests with @verifies tags for:
- REQ_INTEROP_002 (docs), 015 (delete fault)
- REQ_INTEROP_016-017 (data categories/groups), 020 (write data)
- REQ_INTEROP_033 (list ops), 037-038 (execution status/update)
- REQ_INTEROP_048-052 (configuration endpoints)

Coverage: 32/32 requirements (100%)
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements SOVD (Service-Oriented Vehicle Diagnostics) API compliance with custom ros2_medkit extensions under the x-medkit field. It represents a significant architectural shift to align with industry standards while preserving ROS 2-specific functionality.

Changes:

  • Introduces SOVD-compliant error handling with standardized error codes and the GenericError schema
  • Implements the x-medkit extension pattern to separate SOVD-compliant fields from ros2_medkit-specific extensions
  • Adds comprehensive entity resource model with thread-safe caching, capabilities validation, and operation aggregation

Reviewed changes

Copilot reviewed 41 out of 41 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/error_codes.hpp New file defining SOVD standard and x-medkit vendor error codes
src/ros2_medkit_gateway/include/ros2_medkit_gateway/http/x_medkit.hpp Fluent builder for x-medkit extension JSON objects
src/ros2_medkit_gateway/include/ros2_medkit_gateway/models/*.hpp Entity types, capabilities, thread-safe cache, and aggregation service
src/ros2_medkit_gateway/src/http/handlers/*.cpp Updates all handlers to use new error format and x-medkit extensions
src/ros2_medkit_gateway/test/test_*.cpp Comprehensive unit and integration test coverage for new components
src/ros2_medkit_gateway/src/http/rest_server.cpp Adds SOVD-compliant execution endpoints and global error handlers

BREAKING CHANGE: Entity model JSON structure changed - all ROS2-specific
fields moved from top-level to x-medkit vendor extension object.

Summary:
Refactor all SOVD entity models (Area, Component, App, Function) to be
strictly compliant with ASAM SOVD V1.1.0 specification by moving non-SOVD
fields into the `x-medkit` vendor extension namespace.

Changes:
- Entity `to_json()` now places ROS2-specific fields in `x-medkit`:
  - entityType, namespace, fqn, source, area, isOnline, boundFqn
  - rosBinding, description, variant, parentAreaId, hosts, dependsOn
- EntityReference `to_entity_reference()` returns only SOVD fields:
  - id, name, href, translationId (optional), tags (optional)
  - Removed: type, self (renamed to href)
- Entity capabilities `to_capabilities()` uses SOVD flat URI format:
  - Top-level capability URIs: data, operations, configurations, faults
  - Removed: capabilities array with {name, href} objects
- Update unit tests to verify x-medkit extension structure
- Update integration tests for SOVD-compliant executions endpoints
@bburda bburda marked this pull request as draft January 23, 2026 21:09
Changes:
- Replace deprecated /areas/{id}/related-components with /contains
- Replace deprecated /components/{id}/related-apps with /hosts
- Update /version-info response format
- Add belongs-to field to Component/App capabilities
- Add hosts/contains fields to entity capability responses

Test fixes:
- Fix test_44_list_executions_endpoint (items is list of dicts)
- Fix test_101_update_execution (hyphen rejected in entity ID validation)
- Remove tests for deleted deprecated endpoints
- Update test_https_version_info_endpoint for new format

Documentation:
- Update README.md with new endpoints
- Update Postman collection with contains/hosts requests
- Remove deprecated endpoint references
…le expected status codes

Gateway changes:
- Add ERR_NOT_IMPLEMENTED error code for 501 responses
- Add PUT /apps/{id}/data/{data-id} endpoint for publishing to topics
- Add GET /apps/{id}/data-categories endpoint (returns 501 Not Implemented)
- Add GET /apps/{id}/data-groups endpoint (returns 501 Not Implemented)

Test improvements:

test_integration.test.py:
- Add _wait_for_fault() helper for deterministic fault testing
- Add _wait_for_operation() helper to wait for action discovery
- Change setUpClass to wait for specific required apps/areas by ID,
  not just minimum counts (fixes CI flakiness)
- Fix test_95: Use lidar_sensor with known LIDAR_RANGE_INVALID fault
- Fix test_96-97: Expect 501 Not Implemented for data-categories/groups
- Fix test_98: Use actuator with known subscribe topic for writes
- Fix test_100-101: Create real executions, wait for operation discovery
- Fix test_103: Dynamically find app with configurations
- Fix test_104-106: Use specific assertions instead of multi-status

test_discovery_manifest.test.py:
- Fix 8 tests using assertIn(status_code, [...]) pattern
- Apps/functions defined in manifest should always return 200
- Invalid ID with dots returns 400 (validation), not 404
- Configurations in manifest-only mode return 503 (no nodes)

test_auth.test.py:
- Fix test_05 and test_07 to use assertNotIn([401, 403])
  to verify auth passes without testing resource availability
@bburda bburda marked this pull request as ready for review January 24, 2026 18:10
@bburda bburda requested review from Copilot and mfaferek93 January 24, 2026 18:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 62 out of 63 changed files in this pull request and generated 2 comments.

- Remove deprecated EntityCache from models.hpp (file deleted)
- Update gateway_node.hpp to use only ThreadSafeEntityCache
- Update all handlers to use get_thread_safe_cache() with O(1) lookups
- Fix integration tests to use 'parameters' field for error responses
  instead of 'x-medkit' (SOVD error format compliance)
- Migrate handler_context.cpp, area_handlers.cpp, component_handlers.cpp,
  operation_handlers.cpp to efficient cache lookups
@mfaferek93 mfaferek93 self-requested a review January 25, 2026 15:51
@bburda bburda merged commit b37ab83 into main Jan 25, 2026
4 checks passed
@bburda bburda deleted the feat/compliance branch January 25, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SOVD-compatible API contract + ros2_medkit extensions (x-medkit)

3 participants