Skip to content

[BUG] Synthetic components return empty results from /logs and /bulk-data resource collections #393

@bburda

Description

@bburda

Bug report

Steps to reproduce

  1. 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
    
  2. 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
    
  3. Query log entries for that component:
    curl -s "localhost:8080/api/v1/components/$COMP_ID/logs?severity=debug" | jq
    
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions