Describe the bug
A recording that rosbag2 split past snapshots.rosbag.max_bag_size_mb (default 50 MB) is a directory with several storage files and one metadata.yaml naming all of them. GET /api/v1/{entity}/bulk-data/rosbags/{recording_id} serves exactly one of those files. resolve_rosbag_file_path in src/ros2_medkit_gateway/src/http/handlers/bulkdata_handlers.cpp returns the first .db3 or .mcap a std::filesystem::directory_iterator yields and never reads metadata.yaml. On ext4 that order follows a hash of the file name, not the recording order.
Measured on main:
- The three-segment mcap recording from
RosbagCaptureIntegrationTest.ABoundaryRecordingSplitsAndReportsTheWholeBag (_0 1641630 bytes, _1 1642300, _2 823197) resolves to _0. 2465497 of 4107127 recorded bytes never leave the gateway.
- A three-segment sqlite3 bag with the same naming resolves to
_1, the middle segment.
- A two-segment bag (
split_0.db3 16384, split_1.db3 53248) resolves to split_1.db3. Creating the files in the opposite order, or replacing metadata.yaml with garbage, changes nothing.
Nothing in the response says the recording has more. Content-Disposition carries <recording_id>.<format> and never names the segment. The fault manager stores the directory total (RosbagCapture::calculate_bag_size), so the descriptor size and the nested size_bytes describe the whole recording while the transfer is one piece of it. That mismatch is the only signal a client gets. The descriptor's x-medkit block carries no storage-file count.
To reproduce
- Set
snapshots.rosbag.max_bag_size_mb low so a fault's recording splits, or use the integration test above.
GET /api/v1/apps/{app}/bulk-data/rosbags and note size.
GET /api/v1/apps/{app}/bulk-data/rosbags/{id} and compare Content-Length and the received bytes against the files metadata.yaml lists under relative_file_paths.
Expected behavior
Either the whole recording is downloadable through the bulk-data route, or each storage file is addressable on its own and the descriptor says how many there are.
Options
- Serve a split recording as one tar with its
metadata.yaml, so ros2 bag play works on what arrives.
- Expose one bulk-data item per storage file and put the count in
x-medkit. The route matches one path segment, so the index has to live inside the id.
- Interim: resolve the first entry of
relative_file_paths instead of directory order, and add the storage-file count to x-medkit.
Related
Environment
ROS 2 Jazzy, Ubuntu 24.04, ext4. Measured on main with a real split mcap recording and with sqlite3 storage files plus a rosbag2-shaped metadata.yaml.
Describe the bug
A recording that rosbag2 split past
snapshots.rosbag.max_bag_size_mb(default 50 MB) is a directory with several storage files and onemetadata.yamlnaming all of them.GET /api/v1/{entity}/bulk-data/rosbags/{recording_id}serves exactly one of those files.resolve_rosbag_file_pathinsrc/ros2_medkit_gateway/src/http/handlers/bulkdata_handlers.cppreturns the first.db3or.mcapastd::filesystem::directory_iteratoryields and never readsmetadata.yaml. On ext4 that order follows a hash of the file name, not the recording order.Measured on main:
RosbagCaptureIntegrationTest.ABoundaryRecordingSplitsAndReportsTheWholeBag(_01641630 bytes,_11642300,_2823197) resolves to_0. 2465497 of 4107127 recorded bytes never leave the gateway._1, the middle segment.split_0.db316384,split_1.db353248) resolves tosplit_1.db3. Creating the files in the opposite order, or replacingmetadata.yamlwith garbage, changes nothing.Nothing in the response says the recording has more.
Content-Dispositioncarries<recording_id>.<format>and never names the segment. The fault manager stores the directory total (RosbagCapture::calculate_bag_size), so the descriptorsizeand the nestedsize_bytesdescribe the whole recording while the transfer is one piece of it. That mismatch is the only signal a client gets. The descriptor'sx-medkitblock carries no storage-file count.To reproduce
snapshots.rosbag.max_bag_size_mblow so a fault's recording splits, or use the integration test above.GET /api/v1/apps/{app}/bulk-data/rosbagsand notesize.GET /api/v1/apps/{app}/bulk-data/rosbags/{id}and compareContent-Lengthand the received bytes against the filesmetadata.yamllists underrelative_file_paths.Expected behavior
Either the whole recording is downloadable through the bulk-data route, or each storage file is addressable on its own and the descriptor says how many there are.
Options
metadata.yaml, soros2 bag playworks on what arrives.x-medkit. The route matches one path segment, so the index has to live inside the id.relative_file_pathsinstead of directory order, and add the storage-file count tox-medkit.Related
file_paththe fault manager reports as-is, with no check that it lies under the rosbag storage directory. The path never comes from the request, so nothing new is reachable, but a containment check would stop trusting a path that arrives over a ROS service.sizefor single-file recordings: bulk-data rosbags: the descriptor size counts bytes the download does not serve, and the README documents removed snapshot routes #674.Environment
ROS 2 Jazzy, Ubuntu 24.04, ext4. Measured on main with a real split mcap recording and with sqlite3 storage files plus a rosbag2-shaped
metadata.yaml.