Skip to content

SOVD service interface: aggregate peer faults#419

Open
bburda wants to merge 2 commits into
mainfrom
feat/sovd-service-interface-aggregation
Open

SOVD service interface: aggregate peer faults#419
bburda wants to merge 2 commits into
mainfrom
feat/sovd-service-interface-aggregation

Conversation

@bburda

@bburda bburda commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

The ROS 2 SOVD service interface returned only local fault-manager faults, while the HTTP API already fans out to aggregation peers. This wires GatewayPluginContext::list_entity_faults and list_all_faults to the aggregation manager (fan_out_get), mirroring the HTTP fault handler, so a gateway with aggregation.enabled exposes peer faults over the ROS 2 service path too - consistent with the HTTP /api/v1/faults and /api/v1/<entity>/faults endpoints.

  • per-entity: list_entity_faults fans out /api/v1/<type>/<id>/faults to peers and merges.
  • all-faults: list_all_faults fans out /api/v1/faults and merges.
  • Aggregation is gated on get_aggregation_manager() != nullptr (no behavior change when aggregation is disabled).

Aggregated faults can carry status as a SOVD DTC object (e.g. {"aggregatedStatus": "active", ...}) rather than a plain string. handle_list_entity_faults previously called value("status", string{}), which throws json::type_error.302 on an object. It now checks the JSON type first: strings pass through unchanged, objects use the aggregatedStatus field when present. Without this, a fanned-out service call over a peer with object-typed status would fail.


Issue


Type

  • Bug fix

Testing

  • New test_plugin_context_aggregation (mock peer server): per-entity and all-faults paths surface a peer fault when aggregation is enabled; local-only behavior unchanged when disabled.
  • Gateway aggregation suite: test_plugin_context_aggregation, test_aggregation_manager, test_aggregation_classification - all pass.
  • SOVD service interface package suite: 17 tests, 0 failures.
  • Full gateway unit suite: colcon test --packages-select ros2_medkit_gateway - 0 failures.
  • Clean build (-Wall -Wextra -Wpedantic -Wshadow -Wconversion), zero warnings; clang-tidy clean on the changed lines.

Copilot AI review requested due to automatic review settings June 15, 2026 15:28

Copilot AI left a comment

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.

Pull request overview

This PR aligns the ROS 2 SOVD service interface fault listing behavior with the HTTP API by fanning out fault queries to aggregation peers (when aggregation.enabled is on), so peer faults become visible via the ROS 2 service path as well.

Changes:

  • Updated GatewayPluginContext::list_entity_faults() to optionally fan out /api/v1/<type>/<id>/faults to peers and merge results.
  • Updated GatewayPluginContext::list_all_faults() to optionally fan out /api/v1/faults to peers and merge results.
  • Added a new GTest (test_plugin_context_aggregation) plus CMake wiring.

Reviewed changes

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

File Description
src/ros2_medkit_gateway/src/plugins/plugin_context.cpp Adds aggregation-manager fan-out + merge behavior for plugin-context fault listing APIs.
src/ros2_medkit_gateway/test/test_plugin_context_aggregation.cpp New unit test covering peer fan-out behavior for per-entity and global faults.
src/ros2_medkit_gateway/CMakeLists.txt Registers the new test target and includes it in coverage configuration.

Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp
Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp
Comment thread src/ros2_medkit_gateway/test/test_plugin_context_aggregation.cpp
Comment thread src/ros2_medkit_gateway/test/test_plugin_context_aggregation.cpp
Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp Outdated
Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp
Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp
Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp Outdated
Comment thread src/ros2_medkit_gateway/src/plugins/plugin_context.cpp
Comment thread src/ros2_medkit_gateway/test/test_plugin_context_aggregation.cpp
Comment thread src/ros2_medkit_gateway/test/test_plugin_context_aggregation.cpp
@bburda bburda self-assigned this Jun 15, 2026
@bburda bburda force-pushed the feat/sovd-service-interface-aggregation branch from 8e96cff to 638d040 Compare June 15, 2026 18:15
The ROS 2 SOVD service interface (plugin context) returned only local
fault-manager faults, while the HTTP API already fans out to aggregation
peers. Wire list_entity_faults and list_all_faults to the aggregation
manager (fan_out_get) so a gateway with aggregation.enabled exposes peer
faults over the ROS 2 service path too, consistent with the HTTP
/api/v1/faults and /api/v1/<entity>/faults endpoints.

- list_entity_faults: fans out /api/v1/<type>/<id>/faults to peers and merges.
- list_all_faults: fans out /api/v1/faults and merges.
- Aggregation is gated on get_aggregation_manager() != nullptr (no behavior
  change when aggregation is disabled).

Extract entity -> source-FQN resolution and fault scoping into a shared
neutral helper (core/faults/fault_scope) used by both the HTTP fault handlers
and the plugin-context fault path. list_entity_faults now scopes its local
faults to the entity's resolved App-FQN set (APP, COMPONENT, AREA, FUNCTION)
exactly as the HTTP per-entity handler does, instead of returning a bare
fault-manager envelope.

Log partial peer fan-out and document that the ROS 2 service path queries
peers without an Authorization header. Recompute list_all_faults "count"
after merging peer faults so it does not undercount.

Add test_plugin_context_aggregation: no-aggregation baseline, live-mock-peer
fan-out, and local-fault-path coverage with a fake fault transport (scoped
local fault, component/area/function resolution, local+peer merge, and a
peer that fails the fan-out while local faults survive).

Closes #418
@bburda bburda force-pushed the feat/sovd-service-interface-aggregation branch from 638d040 to 86b69da Compare June 15, 2026 18:58
…aults

When the gateway aggregates faults from a peer (rtmaps_medkit), the
aggregated fault carries status as a SOVD DTC object:
  {"aggregatedStatus": "active", "confirmedDTC": "1", ...}

list_entity_faults previously called fault_json.value("status", string{})
which throws json::type_error.302 when status is an object.

Fix: check the type before extracting. Strings are passed through as-is.
Objects use the "aggregatedStatus" field if present.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SOVD service interface returns only local faults, not aggregated peer faults

3 participants