Bug report
Steps to reproduce
- Launch the gateway with at least one runtime-discovered ROS 2 node grouped into a synthetic / runtime-discovered component (any node whose component is not declared in a manifest):
ros2 launch ros2_medkit_gateway gateway.launch.py
ros2 launch ros2_medkit_integration_tests demo_nodes.launch.py
- Identify the synthetic component that hosts a demo app:
curl -s localhost:8080/api/v1/components | jq '.items[].id'
COMP_ID=... # the one whose /hosts contains a demo app
curl -s localhost:8080/api/v1/components/$COMP_ID/hosts
- Query log entries for that component:
curl -s "localhost:8080/api/v1/components/$COMP_ID/logs?severity=debug" | jq
- Query bulk-data rosbag descriptors for the same component (after a fault triggers a capture):
curl -s "localhost:8080/api/v1/components/$COMP_ID/bulk-data/rosbags" | jq
Expected behavior
Both endpoints return entries aggregated from the apps hosted by the component, with x-medkit.aggregation_level=component and a non-empty items list (mirroring how /areas/{id}/logs and /functions/{id}/logs already aggregate).
Actual behavior
Both endpoints return {"items": []} even when the component groups N apps that have logs / rosbags. No error, no warning - just a quiet empty response.
Root cause is the same in both handlers: synthetic / runtime-discovered components have an empty fqn and an empty namespace_path, while manifest-defined components have non-empty values.
LogHandlers::handle_get_logs calls LogManager::get_logs({entity.fqn}, prefix_match=true, ...) for the COMPONENT branch. With an empty fqn, the prefix-match against per-node logger name buffers selects nothing and returns zero items. AREA and FUNCTION already aggregate via hosted apps' effective_fqn(), so they work correctly; COMPONENT is the only entity type still on the legacy path.
BulkDataHandlers::get_source_filters has a special case for FUNCTION (cache.get_apps_for_function() + effective_fqn()) but falls through to entity.fqn.empty() ? entity.namespace_path : entity.fqn for COMPONENT. Both fields empty → returns {} source filters, so handle_list_descriptors (rosbag listing) and the ownership check in handle_download get nothing to work with.
Environment
Additional information
Fix mirrors the AREA / FUNCTION pattern already in both handlers - resolve hosted apps via cache.get_apps_for_component(), build their effective_fqn() list, fall through to the namespace-prefix path only when the component has no hosted apps but declares a non-empty namespace (manifest deployments where a component groups topics rather than nodes).
A related but distinct symptom on the per-entity faults handler is tracked separately - see comment on #380 for details. That one is a scope-leak rather than an empty-result bug and needs a different fix (changing the GetFault service contract), so it is not in scope here.
Bug report
Steps to reproduce
Expected behavior
Both endpoints return entries aggregated from the apps hosted by the component, with
x-medkit.aggregation_level=componentand a non-emptyitemslist (mirroring how/areas/{id}/logsand/functions/{id}/logsalready aggregate).Actual behavior
Both endpoints return
{"items": []}even when the component groups N apps that have logs / rosbags. No error, no warning - just a quiet empty response.Root cause is the same in both handlers: synthetic / runtime-discovered components have an empty
fqnand an emptynamespace_path, while manifest-defined components have non-empty values.LogHandlers::handle_get_logscallsLogManager::get_logs({entity.fqn}, prefix_match=true, ...)for the COMPONENT branch. With an empty fqn, the prefix-match against per-node logger name buffers selects nothing and returns zero items. AREA and FUNCTION already aggregate via hosted apps'effective_fqn(), so they work correctly; COMPONENT is the only entity type still on the legacy path.BulkDataHandlers::get_source_filtershas a special case for FUNCTION (cache.get_apps_for_function()+effective_fqn()) but falls through toentity.fqn.empty() ? entity.namespace_path : entity.fqnfor COMPONENT. Both fields empty → returns{}source filters, sohandle_list_descriptors(rosbag listing) and the ownership check inhandle_downloadget nothing to work with.Environment
Additional information
Fix mirrors the AREA / FUNCTION pattern already in both handlers - resolve hosted apps via
cache.get_apps_for_component(), build theireffective_fqn()list, fall through to the namespace-prefix path only when the component has no hosted apps but declares a non-empty namespace (manifest deployments where a component groups topics rather than nodes).A related but distinct symptom on the per-entity faults handler is tracked separately - see comment on #380 for details. That one is a scope-leak rather than an empty-result bug and needs a different fix (changing the GetFault service contract), so it is not in scope here.