Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server Recording and Replaying feature added! #143

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6e51b1e
Update .repos and docs links
rsanchez15 Mar 26, 2024
115498e
Added an installer script to build from sources
Ryan-Red May 2, 2024
c9b5e04
Discovery server seems to be in CommonParticipant rtps
Ryan-Red May 6, 2024
9dcc91e
Server recording and replaying now works! Added ddspipes and dev tool…
Ryan-Red May 8, 2024
f1af222
Removed print statements and leaned out the code
Ryan-Red May 8, 2024
4be3a2d
Removed DDS Pipe to add it back as a submodule
Ryan-Red May 8, 2024
fda7317
Added DDS-Pipe as a submodule
Ryan-Red May 8, 2024
0a51bd5
Removed Fast-DDS-Python and re-adding it as a submodule
Ryan-Red May 8, 2024
e8ff332
Added Fast-DDS-python as a submodule and selected the right version
Ryan-Red May 8, 2024
d9b2824
Removing Dev-utils and adding it back in as a submodule
Ryan-Red May 8, 2024
c35fc6a
Added dev-tools as a submodule
Ryan-Red May 8, 2024
d398904
Fixed installer
Ryan-Red May 8, 2024
b8c1743
Added in the dynamic type support stuff
Ryan-Red May 16, 2024
5eee05e
Fixed the limit of 5000 samples
Ryan-Red May 17, 2024
d4d1929
current working version
Ryan-Red Jun 21, 2024
1b07944
Using servers yaml file and now using command line args for domain se…
Ryan-Red Jun 25, 2024
e1630f1
Removed prints and cleaned up
Ryan-Red Jun 26, 2024
0b91164
Made the default domain 3 and added a print to indicate the domain cu…
Ryan-Red Jun 27, 2024
52a4085
README completed and updated and tested with latest MCAP release
Ryan-Red Jun 27, 2024
43d02c3
Merge branch 'main' into Server_Enabled
Ryan-Red Jun 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "DDS-Pipe"]
path = DDS-Pipe
url = https://github.com/Ryan-Red/DDS-Pipe.git
[submodule "Fast-DDS-python"]
path = Fast-DDS-python
url = https://github.com/eProsima/Fast-DDS-python.git
[submodule "dev-utils"]
path = dev-utils
url = https://github.com/eProsima/dev-utils.git
1 change: 1 addition & 0 deletions DDS-Pipe
Submodule DDS-Pipe added at 0cdc2a
1 change: 1 addition & 0 deletions Fast-DDS-python
Submodule Fast-DDS-python added at 4942c8
88 changes: 64 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,78 @@
# eProsima DDS Record & Replay
# eProsima DDS Record & Replay: Server Fork

<a href="http://www.eprosima.com"><img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSd0PDlVz1U_7MgdTe0FRIWD0Jc9_YH-gGi0ZpLkr-qgCI6ZEoJZ5GBqQ" align="left" hspace="8" vspace="2" width="100" height="100" ></a>
## Introduction

[![License](https://img.shields.io/github/license/eProsima/DDS-Recorder.svg)](https://opensource.org/licenses/Apache-2.0)
[![Issues](https://img.shields.io/github/issues/eProsima/DDS-Recorder.svg)](https://github.com/eProsima/DDS-Recorder/issues)
[![Forks](https://img.shields.io/github/forks/eProsima/DDS-Recorder.svg)](https://github.com/eProsima/DDS-Recorder/network/members)
[![Stars](https://img.shields.io/github/stars/eProsima/DDS-Recorder.svg)](https://github.com/eProsima/DDS-Recorder/stargazers)
[![test](https://github.com/eProsima/DDS-Recorder/actions/workflows/test.yml/badge.svg)](https://github.com/eProsima/DDS-Recorder/actions/workflows/test.yml)
This repo works similar to eProsima's DDS Record and Replay, the difference being that this fork is tailored to work with servers instead of simple discovery.

*eProsima DDS Record & Replay* is an end-user software application that efficiently saves DDS data published in a DDS environment into a MCAP format database.
Thus, the exact playback of the recorded network events is possible as the data is linked to the timestamp at which the original data was published.
## How It Works

*eProsima DDS Record & Replay* is easily configurable and installed with a default setup, so that DDS topics, data types and entities are automatically discovered without the need to specify the types of data recorded.
This is because the recording tool exploits the DynamicTypes functionality of [eProsima Fast DDS](https://fast-dds.docs.eprosima.com), the C++ implementation of the [DDS (Data Distribution Service) Specification](https://www.omg.org/spec/DDS/About-DDS/) defined by the [Object Management Group (OMG)](https://www.omg.org/).
With DDS Record and Replay, you can record any topic on a given domain.


## Documentation
## How to Install

You can access the documentation online, which is hosted on [Read the Docs](https://dds-recorder.readthedocs.io/).
To install this repo, simply run the following after cloning this repo:

* [Introduction](https://dds-recorder.readthedocs.io/en/latest/)
```
git clone https://github.com/Ryan-Red/DDS-Record-Replay.git
git submodule init
git submodule update --recursive
sudo ./install_mcap_amd64.sh
sudo ./install_dependencies.sh
```
All dependencies are installed in the install scripts.

**Recording application**

* [Getting Started](https://dds-recorder.readthedocs.io/en/latest/rst/recording/getting_started/getting_started.html)
* [Usage](https://dds-recorder.readthedocs.io/en/latest/rst/recording/usage/usage.html)
* [Configuration](https://dds-recorder.readthedocs.io/en/latest/rst/recording/usage/configuration.html)
**NOTE:** This MCAP install script uses the linux amd64 release, if using another architecture make sure to follow the same steps and find the right binary [here](https://github.com/foxglove/mcap/releases/)

**Replay application**
## Usage guide:

* [Getting Started](https://dds-recorder.readthedocs.io/en/latest/rst/replaying/getting_started/getting_started.html)
* [Usage](https://dds-recorder.readthedocs.io/en/latest/rst/replaying/usage/usage.html)
* [Configuration](https://dds-recorder.readthedocs.io/en/latest/rst/replaying/usage/configuration.html)
### DDSRecorder

## Getting Help
To record all topics on domain, simply run

If you need support you can reach us by mail at `[email protected]` or by phone at `+34 91 804 34 48`.
```
ddsrecord -d DOMAIN
```
Where DOMAIN is the domain we are recording over. It should just be a number. The recording will be saved as an MCAP file.

The program should print out the topics being recorded and the domain currently being used as a sanity check.

There is a maximum number of samples to record per topic of 50 000 000 samples. This means that when recording a topic publishing at 1000 Hz, you can record up to 50 000 seconds or 13 hours and 58 minutes.

#### Optional Configuration
If for some reason you need to ignore certain topics, follow [this guide](https://dds-recorder.readthedocs.io/en/latest/rst/recording/usage/configuration.html) to create your configuration file.

To run this configuration file while recording, run:

```
ddsrecord -d DOMAIN -c CONFIGURATION.yaml
```
Where DOMAIN is the domain we are recording on and CONFIGURATION.yaml is the configuration file.


### DDSReplayer

To replay a recording, **first make sure that the discovery servers are running!**

Next, to replay a file simply run:

```
ddsreplayer -i FILE.mcap -d DOMAIN

```
Where FILE.mcap is the MCAP file we want to replay (that we previously recorded) and DOMAIN is the domain we are replaying on.

**NOTE:** We can replay a topic on any domain, not just the one we recorded it on.

#### Optional Configuration

Just like the recorder, there are some extra configuration parameters. Follow [this guide](https://dds-recorder.readthedocs.io/en/latest/rst/replaying/usage/configuration.html) to learn how to create the configuration file.

To run this configuration:

```
ddsreplayer -i FILE.mcap -d DOMAIN -c CONFIGURATION.yaml
```

Where FILE.mcap is the MCAP file we want to replay, DOMAIN is the domain we are recording on and CONFIGURATION.yaml is the configuration file.
10 changes: 7 additions & 3 deletions ddsrecorder/src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

/**
* @file main.cpp
*

*/

#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -390,8 +390,12 @@ int main(
// NOTE: Changes to all (but controller specific) recorder configuration options are taken into account
configuration = eprosima::ddsrecorder::yaml::RecorderConfiguration(commandline_args.file_path);


// configuration.recorder_configuration->topic_qos.

// Create DDS Recorder
auto recorder = std::make_unique<DdsRecorder>(configuration, initial_state, close_handler);
auto recorder = std::make_unique<DdsRecorder>(configuration, initial_state, "", commandline_args.domain);


// Create File Watcher Handler
std::unique_ptr<eprosima::utils::event::FileWatcherHandler> file_watcher_handler;
Expand Down Expand Up @@ -524,7 +528,7 @@ int main(
else
{
// Start recording right away
auto recorder = std::make_unique<DdsRecorder>(configuration, DdsRecorderState::RUNNING, close_handler);
auto recorder = std::make_unique<DdsRecorder>(configuration, DdsRecorderState::RUNNING, "", commandline_args.domain);

// Create File Watcher Handler
std::unique_ptr<eprosima::utils::event::FileWatcherHandler> file_watcher_handler;
Expand Down
15 changes: 5 additions & 10 deletions ddsrecorder/src/cpp/tool/DdsRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,13 @@ using namespace eprosima::utils;
DdsRecorder::DdsRecorder(
const yaml::RecorderConfiguration& configuration,
const DdsRecorderStateCode& init_state,
const std::string& file_name)
: DdsRecorder(configuration, init_state, nullptr, file_name)
{
}
const std::string& file_name,
int domain)

DdsRecorder::DdsRecorder(
const yaml::RecorderConfiguration& configuration,
const DdsRecorderStateCode& init_state,
std::shared_ptr<eprosima::utils::event::MultipleEventHandler> event_handler,
const std::string& file_name)
: configuration_(configuration)
, event_handler_(event_handler)
{
load_internal_topics_(configuration_);

// Create Discovery Database
discovery_database_ = std::make_shared<DiscoveryDatabase>();

Expand Down Expand Up @@ -121,6 +113,9 @@ DdsRecorder::DdsRecorder(
mcap_handler_->set_on_disk_full_callback(std::bind(&DdsRecorder::on_disk_full, this));

// Create DynTypes Participant

configuration_.simple_configuration->domain = domain;
std::cout << "Recording on domain: " << domain << std::endl;
dyn_participant_ = std::make_shared<DynTypesParticipant>(
configuration_.simple_configuration,
payload_pool_,
Expand Down
5 changes: 4 additions & 1 deletion ddsrecorder/src/cpp/tool/DdsRecorder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@

#include <ddsrecorder_yaml/recorder/YamlReaderConfiguration.hpp>

#include <yaml-cpp/yaml.h>

namespace eprosima {
namespace ddsrecorder {
namespace recorder {
Expand Down Expand Up @@ -69,7 +71,8 @@ class DdsRecorder
DdsRecorder(
const yaml::RecorderConfiguration& configuration,
const DdsRecorderStateCode& init_state,
const std::string& file_name = "");
const std::string& file_name = "",
int domain = 0);

/**
* DdsRecorder constructor by required values and event handler reference.
Expand Down
17 changes: 17 additions & 0 deletions ddsrecorder/src/cpp/user_interface/arguments_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ const option::Descriptor usage[] = {
"Value 0 does not reload file. [Default: 0]."

},

{
optionIndex::DOMAIN,
0,
"d",
"reload-time",
Arg::Numeric,
" -d \t--domain\t \t" \
"Domain to target when recording or replaying "

},

{
optionIndex::TIMEOUT,
0,
Expand Down Expand Up @@ -249,6 +261,11 @@ ProcessReturnCode parse_arguments(
commandline_args.reload_time = std::stol(opt.arg) * 1000; // pass to milliseconds
break;

case optionIndex::DOMAIN:
commandline_args.domain = std::stoi(opt.arg);
break;


case optionIndex::ACTIVATE_DEBUG:
commandline_args.log_filter[utils::VerbosityKind::Error].set_value("");
commandline_args.log_filter[utils::VerbosityKind::Warning].set_value("DDSRECORDER");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ enum optionIndex
HELP,
CONFIGURATION_FILE,
RELOAD_TIME,
DOMAIN,
ACTIVATE_DEBUG,
VERSION,
TIMEOUT,
Expand Down
4 changes: 2 additions & 2 deletions ddsrecorder/test/blackbox/mcap/McapFileCreationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ void create_publisher(

TypeSupport type(new eprosima::fastrtps::types::DynamicPubSubType(test::dynamic_type_));
// Set type so introspection info is sent
type->auto_fill_type_information(true);
type->auto_fill_type_object(false);
type->auto_fill_type_information(false);
type->auto_fill_type_object(true);
// Register the type in the Participant
participant_->register_type(type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#pragma once

#include <ddspipe_participants/configuration/SimpleParticipantConfiguration.hpp>
#include <ddspipe_participants/participant/rtps/SimpleParticipant.hpp>
#include <ddspipe_participants/participant/dds/CommonParticipant.hpp>

#include <ddsrecorder_participants/library/library_dll.h>

Expand All @@ -27,7 +27,7 @@ namespace participants {
* Participant kind in charge of replaying messages read by a \c McapReaderParticipant.
* It is mostly equivalent to a \c rtps::SimpleParticipant without reader, only writer.
*/
class ReplayerParticipant : public ddspipe::participants::rtps::SimpleParticipant
class ReplayerParticipant : public ddspipe::participants::dds::CommonParticipant
{
public:

Expand Down
28 changes: 11 additions & 17 deletions ddsrecorder_participants/src/cpp/recorder/mcap/McapHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1166,13 +1166,9 @@ void McapHandler::store_dynamic_type_(
const std::string& type_name,
DynamicTypesCollection& dynamic_types) const
{
const eprosima::fastrtps::types::TypeIdentifier* type_identifier = nullptr;
const eprosima::fastrtps::types::TypeObject* type_object = nullptr;
const eprosima::fastrtps::types::TypeInformation* type_information = nullptr;

type_information =
eprosima::fastrtps::types::TypeObjectFactory::get_instance()->get_type_information(type_name);
if (type_information != nullptr)
auto type_names = utils::get_keys(schemas_);
DynamicTypesCollection dynamic_types;
for (auto& type_name: type_names)
{
auto dependencies = type_information->complete().dependent_typeids();
std::string dependency_name;
Expand All @@ -1192,16 +1188,14 @@ void McapHandler::store_dynamic_type_(
}
}

type_identifier = nullptr;
type_object = nullptr;

type_identifier = eprosima::fastrtps::types::TypeObjectFactory::get_instance()->get_type_identifier(type_name,
true);
if (type_identifier)
{
type_object =
eprosima::fastrtps::types::TypeObjectFactory::get_instance()->get_type_object(type_name, true);
}
type_identifier = eprosima::fastrtps::types::TypeObjectFactory::get_instance()->get_type_identifier(type_name,
true);
if (type_identifier)
{
type_object =
eprosima::fastrtps::types::TypeObjectFactory::get_instance()->get_type_object(type_name, true);

}

// If complete not found, try with minimal
if (!type_object)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ namespace participants {

using namespace eprosima::ddspipe::core;
using namespace eprosima::ddspipe::participants;
using namespace eprosima::ddspipe::participants::rtps;
using namespace eprosima::ddspipe::participants::dds;

ReplayerParticipant::ReplayerParticipant(
const std::shared_ptr<SimpleParticipantConfiguration>& participant_configuration,
const std::shared_ptr<PayloadPool>& payload_pool,
const std::shared_ptr<DiscoveryDatabase>& discovery_database)
: SimpleParticipant(
: CommonParticipant(
participant_configuration,
payload_pool,
discovery_database)
Expand Down
12 changes: 6 additions & 6 deletions ddsrecordreplay.repos
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ repositories:
foonathan_memory_vendor:
type: git
url: https://github.com/eProsima/foonathan_memory_vendor.git
version: master
version: v1.3.1
fastcdr:
type: git
url: https://github.com/eProsima/Fast-CDR.git
version: master
version: v2.2.0
fastdds:
type: git
url: https://github.com/eProsima/Fast-DDS.git
version: bugfix/complex-dynamic-types
version: v2.14.0
dev-utils:
type: git
url: https://github.com/eProsima/dev-utils.git
version: main
version: v0.6.0
ddspipe:
type: git
url: https://github.com/eProsima/DDS-Pipe.git
version: main
version: v0.4.0
ddsrecordreplay:
type: git
url: https://github.com/eProsima/DDS-Record-Replay.git
version: main
version: v0.4.0
2 changes: 1 addition & 1 deletion ddsreplayer/src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ int main(


// Create replayer instance
auto replayer = std::make_unique<DdsReplayer>(configuration, commandline_args.input_file);
auto replayer = std::make_unique<DdsReplayer>(configuration, commandline_args.input_file, commandline_args.domain);

// Create File Watcher Handler
std::unique_ptr<eprosima::utils::event::FileWatcherHandler> file_watcher_handler;
Expand Down
Loading