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

[19967] Define a super client by environment variable (backport #4047) #4105

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions include/fastdds/rtps/attributes/ServerAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,15 @@ const char* const DEFAULT_ROS2_SERVER_GUIDPREFIX = "44.53.00.5f.45.50.52.4f.53.4
*/
const char* const DEFAULT_ROS2_MASTER_URI = "ROS_DISCOVERY_SERVER";

/* Environment variable to transform a SIMPLE participant in a SUPER CLIENT.
* If the participant is not SIMPLE, the variable doesn't have any effects.
* The variable can assume the following values:
* - FALSE, false, False, 0
* - TRUE, true, True, 1
* If the variable is not set, the program will behave like the variable is set to false.
*/
const char* const ROS_SUPER_CLIENT = "ROS_SUPER_CLIENT";

/**
* Retrieves a semicolon-separated list of locators from a string, and
* populates a RemoteServerList_t mapping list position to default guid.
Expand Down Expand Up @@ -211,6 +220,12 @@ RTPS_DllAPI bool load_environment_server_info(
*/
RTPS_DllAPI const std::string& ros_discovery_server_env();

/**
* Get the value of environment variable ROS_SUPER_CLIENT
* @return The value of environment variable ROS_SUPER_CLIENT. False if the variable is not defined.
*/
RTPS_DllAPI bool ros_super_client_env();

/**
* Returns the guidPrefix associated to the given server id
* @param[in] id of the default server whose guidPrefix we want to retrieve
Expand All @@ -233,9 +248,11 @@ using fastdds::rtps::RemoteServerList_t;
using fastdds::rtps::DEFAULT_ROS2_SERVER_PORT;
using fastdds::rtps::DEFAULT_ROS2_SERVER_GUIDPREFIX;
using fastdds::rtps::DEFAULT_ROS2_MASTER_URI;
using fastdds::rtps::ROS_SUPER_CLIENT;
using fastdds::rtps::load_environment_server_info;
using fastdds::rtps::ros_discovery_server_env;
using fastdds::rtps::get_server_client_default_guidPrefix;
using fastdds::rtps::ros_super_client_env;

} // fastrtps
} // rtps
Expand Down
6 changes: 6 additions & 0 deletions src/cpp/rtps/RTPSDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,12 @@ RTPSParticipant* RTPSDomainImpl::clientServerEnvironmentCreationOverride(
client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol_t::CLIENT;
// RemoteServerAttributes already fill in above

// Check if the client must become a super client
if (ros_super_client_env())
{
client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol_t::SUPER_CLIENT;
}

RTPSParticipant* part = createParticipant(domain_id, enabled, client_att, listen);
if (nullptr != part)
{
Expand Down
27 changes: 27 additions & 0 deletions src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,33 @@ void PDPClient::match_pdp_reader_nts_(
}
}

bool ros_super_client_env()
{
std::string super_client_str;
bool super_client = false;
std::vector<std::string> true_vec = {"TRUE", "true", "True", "1"};
std::vector<std::string> false_vec = {"FALSE", "false", "False", "0"};

SystemInfo::get_env(ROS_SUPER_CLIENT, super_client_str);
if (super_client_str != "")
{
if (find(true_vec.begin(), true_vec.end(), super_client_str) != true_vec.end())
{
super_client = true;
}
else if (find(false_vec.begin(), false_vec.end(), super_client_str) != false_vec.end())
{
super_client = false;
}
else
{
EPROSIMA_LOG_ERROR(RTPS_PDP,
"Invalid value for ROS_SUPER_CLIENT environment variable : " << super_client_str);
}
}
return super_client;
}

const std::string& ros_discovery_server_env()
{
static std::string servers;
Expand Down
89 changes: 89 additions & 0 deletions test/unittest/dds/participant/ParticipantTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,95 @@ TEST(ParticipantTests, SimpleParticipantRemoteServerListConfiguration)
}


/**
* Test that a SIMPLE participant is transformed into a CLIENT if the variable ROS_SUPER_CLIENT is false and into a SUPERCLIENT if it's true.
* It also checks that the environment variable has priority over the coded QoS settings.
*/
TEST(ParticipantTests, TransformSimpleParticipantToSuperclientByEnvVariable)
{
set_environment_variable();

#ifdef _WIN32
ASSERT_EQ(0, _putenv_s(rtps::ROS_SUPER_CLIENT, "false"));
#else
ASSERT_EQ(0, setenv(rtps::ROS_SUPER_CLIENT, "false", 1));
#endif // _WIN32

rtps::RemoteServerList_t output;
rtps::RemoteServerList_t qos_output;
expected_remote_server_list_output(output);

DomainParticipantQos qos;
set_participant_qos(qos, qos_output);

DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(
(uint32_t)GET_PID() % 230, qos);
ASSERT_NE(nullptr, participant);

fastrtps::rtps::RTPSParticipantAttributes attributes;
get_rtps_attributes(participant, attributes);
EXPECT_EQ(attributes.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::CLIENT);
EXPECT_EQ(attributes.builtin.discovery_config.m_DiscoveryServers, output);

#ifdef _WIN32
ASSERT_EQ(0, _putenv_s(rtps::ROS_SUPER_CLIENT, "true"));
#else
ASSERT_EQ(0, setenv(rtps::ROS_SUPER_CLIENT, "true", 1));
#endif // _WIN32

DomainParticipant* participant_2 = DomainParticipantFactory::get_instance()->create_participant(
(uint32_t)GET_PID() % 230, qos);
ASSERT_NE(nullptr, participant_2);

fastrtps::rtps::RTPSParticipantAttributes attributes_2;
get_rtps_attributes(participant_2, attributes_2);
EXPECT_EQ(attributes_2.builtin.discovery_config.discoveryProtocol, fastrtps::rtps::DiscoveryProtocol::SUPER_CLIENT);
EXPECT_EQ(attributes_2.builtin.discovery_config.m_DiscoveryServers, output);

// check UDPv6 transport is there
auto udpv6_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes) -> bool
{
for (auto& transportDescriptor : attributes.userTransports)
{
if ( nullptr != dynamic_cast<fastdds::rtps::UDPv6TransportDescriptor*>(transportDescriptor.get()))
{
return true;
}
}

return false;
};
EXPECT_TRUE(udpv6_check(attributes));

DomainParticipantQos result_qos = participant->get_qos();
EXPECT_EQ(result_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers, qos_output);
EXPECT_EQ(ReturnCode_t::RETCODE_OK, participant->set_qos(result_qos));

// check UDPv6 transport is there
auto udpv6_check_2 = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_2) -> bool
{
for (auto& transportDescriptor : attributes_2.userTransports)
{
if ( nullptr != dynamic_cast<fastdds::rtps::UDPv6TransportDescriptor*>(transportDescriptor.get()))
{
return true;
}
}

return false;
};
EXPECT_TRUE(udpv6_check_2(attributes_2));

result_qos = participant_2->get_qos();
EXPECT_EQ(result_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers, qos_output);
EXPECT_EQ(ReturnCode_t::RETCODE_OK, participant_2->set_qos(result_qos));

EXPECT_EQ(ReturnCode_t::RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant));
EXPECT_EQ(ReturnCode_t::RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant_2));
}



/**
* Test that:
* + checks a SIMPLE participant is transformed into a CLIENT.
Expand Down
Loading