From 2f5f3938483b50cceddffbc053d5c339351bc45d Mon Sep 17 00:00:00 2001 From: jparisu Date: Wed, 9 Jun 2021 09:01:08 +0200 Subject: [PATCH 01/10] Refs #11770: databroker PoC Signed-off-by: jparisu --- CMakeLists.txt | 1 + src/Participant.cpp | 305 +++++++++++++++++++++++++++++-------------- src/Participant.hpp | 34 ++--- src/SystemHandle.cpp | 16 +-- src/utils.cpp | 162 +++++++++++++++++++++++ src/utils.hpp | 59 +++++++++ 6 files changed, 448 insertions(+), 129 deletions(-) create mode 100644 src/utils.cpp create mode 100644 src/utils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f5fb7df..5a28bf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ if(BUILD_LIBRARY) src/Server.cpp src/Participant.cpp src/SystemHandle.cpp + src/utils.cpp ) endif() diff --git a/src/Participant.cpp b/src/Participant.cpp index a6fbc63..b32db53 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -18,7 +18,9 @@ #include "Participant.hpp" #include "DDSMiddlewareException.hpp" #include "Conversion.hpp" +#include "utils.hpp" +#include #include #include @@ -43,54 +45,7 @@ Participant::Participant( : dds_participant_(nullptr) , logger_("is::sh::FastDDS::Participant") { - using fastrtps::xmlparser::XMLP_ret; - using fastrtps::xmlparser::XMLProfileManager; - - if (!config.IsMap() || !config["file_path"] || !config["profile_name"]) - { - if (config["domain_id"]) - { - const ::fastdds::dds::DomainId_t domain_id = config["domain_id"].as(); - build_participant(domain_id); - } - else - { - std::ostringstream err; - err << "The node 'participant' in the YAML configuration of the 'fastdds' system " - << "must be a map containing two keys: 'file_path' and 'profile_name'"; - - throw DDSMiddlewareException(logger_, err.str()); - } - - } - else - { - const std::string file_path = config["file_path"].as(); - if (XMLP_ret::XML_OK != XMLProfileManager::loadXMLFile(file_path)) - { - throw DDSMiddlewareException( - logger_, "Loading provided XML file in 'file_path' field was not successful"); - } - - const std::string profile_name = config["profile_name"].as(); - - dds_participant_ = this->create_participant_with_profile(profile_name); - - if (dds_participant_) - { - logger_ << utils::Logger::Level::INFO - << "Created Fast DDS participant '" << dds_participant_->get_qos().name() - << "' from profile configuration '" << profile_name << "'" << std::endl; - } - else - { - std::ostringstream err; - err << "Fast DDS participant '" << dds_participant_->get_qos().name() - << "' from profile configuration '" << profile_name << "' creation failed"; - - throw DDSMiddlewareException(logger_, err.str()); - } - } + build_participant(config); } Participant::~Participant() @@ -108,33 +63,66 @@ Participant::~Participant() } } +void Participant::build_participant() +{ + // Call build participant with empty configuration + build_participant(YAML::Node()); +} + void Participant::build_participant( - const ::fastdds::dds::DomainId_t& domain_id) + const YAML::Node& config) { - ::fastdds::dds::DomainParticipantQos participant_qos = ::fastdds::dds::PARTICIPANT_QOS_DEFAULT; - participant_qos.name("default_IS-FastDDS-SH_participant"); + logger_ << utils::Logger::Level::DEBUG << "Creating new fastdds Participant" << std::endl; - // By default use UDPv4 due to communication failures between dockers sharing the network with the host - // When it is solved in Fast-DDS delete the following lines and use the default builtin transport. - participant_qos.transport().use_builtin_transports = false; - auto udp_transport = std::make_shared<::fastdds::rtps::UDPv4TransportDescriptor>(); - participant_qos.transport().user_transports.push_back(udp_transport); + // Check if domain_id exists in config + eprosima::fastdds::dds::DomainId_t domain_id(0); + + // Check if domain_id tag is under other tag + if (config["domain_id"]) + { + logger_ << utils::Logger::Level::DEBUG << "#! Get Domain from plain config" << std::endl; + domain_id = config["domain_id"].as(); + } + else if (config["participant"] && config["participant"]["domain_id"]) + { + logger_ << utils::Logger::Level::DEBUG << "#! Get Domain from participant" << std::endl; + domain_id = config["participant"]["domain_id"].as(); + } + else if (config["databroker"] && config["databroker"]["domain_id"]) + { + logger_ << utils::Logger::Level::DEBUG << "#! Get Domain from databroker" << std::endl; + domain_id = config["databroker"]["domain_id"].as(); + } + + logger_ << utils::Logger::Level::DEBUG << "Creating Participant QoS" << std::endl; + + ::fastdds::dds::DomainParticipantQos participant_qos; + + // Depending the SH type, use participant std qos or databroker qos + if (config["participant"]) + { + participant_qos = get_participant_qos(config["participant"]); + } + else if (config["databroker"]) + { + participant_qos = get_databroker_qos(config["databroker"]); + } dds_participant_ = ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant( - domain_id, participant_qos); + domain_id, + participant_qos); if (dds_participant_) { logger_ << utils::Logger::Level::INFO << "Created Fast DDS participant '" << participant_qos.name() - << "' with default QoS attributes and Domain ID: " - << domain_id << std::endl; + << "' with Domain ID: " << domain_id << std::endl; } else { std::ostringstream err; err << "Error while creating Fast DDS participant '" << participant_qos.name() - << "' with default QoS attributes and Domain ID: " << domain_id; + << "' with Domain ID: " << domain_id; throw DDSMiddlewareException(logger_, err.str()); } @@ -322,62 +310,179 @@ bool Participant::dissociate_topic_from_dds_entity( } } -static void set_qos_from_attributes( - ::fastdds::dds::DomainParticipantQos& qos, - const eprosima::fastrtps::rtps::RTPSParticipantAttributes& attr) +eprosima::fastdds::dds::DomainParticipantQos Participant::get_default_participant_qos() { - qos.user_data().setValue(attr.userData); - qos.allocation() = attr.allocation; - qos.properties() = attr.properties; - qos.wire_protocol().prefix = attr.prefix; - qos.wire_protocol().participant_id = attr.participantID; - qos.wire_protocol().builtin = attr.builtin; - qos.wire_protocol().port = attr.port; - qos.wire_protocol().throughput_controller = attr.throughputController; - qos.wire_protocol().default_unicast_locator_list = attr.defaultUnicastLocatorList; - qos.wire_protocol().default_multicast_locator_list = attr.defaultMulticastLocatorList; - - if (attr.useBuiltinTransports) + logger_ << utils::Logger::Level::DEBUG << "#! get_default_participant_qos" << std::endl; + + eprosima::fastdds::dds::DomainParticipantQos df_pqos; + df_pqos.name("default_IS-FastDDS-SH_participant"); + + // By default use UDPv4 due to communication failures between dockers sharing the network with the host + // When it is solved in Fast-DDS delete the following lines and use the default builtin transport. + df_pqos.transport().use_builtin_transports = false; + auto udp_transport = std::make_shared<::fastdds::rtps::UDPv4TransportDescriptor>(); + df_pqos.transport().user_transports.push_back(udp_transport); + + return df_pqos; +} + +eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( + const YAML::Node& config) +{ + logger_ << utils::Logger::Level::DEBUG << "#! get_participant_qos" << std::endl; + + // Load XML if set in config yaml + if (config["file_path"]) { - // By default use UDPv4 due to communication failures between dockers sharing the network with the host - // When it is solved in Fast-DDS delete the following lines and use the default builtin transport. - qos.transport().use_builtin_transports = false; - auto udp_transport = std::make_shared<::fastdds::rtps::UDPv4TransportDescriptor>(); - qos.transport().user_transports.push_back(udp_transport); + const std::string file_path = config["file_path"].as(); + if (fastrtps::xmlparser::XMLP_ret::XML_OK != + fastrtps::xmlparser::XMLProfileManager::loadXMLFile(file_path)) + { + std::ostringstream err; + err << "Loading provided XML file in 'file_path': " << file_path << " incorrect or unexisted file"; + throw DDSMiddlewareException( + logger_, err.str()); + } } - else + + // Variable to return + eprosima::fastdds::dds::DomainParticipantQos pqos = get_default_participant_qos(); + + // Load XML if set in config yaml + if (config["profile_name"]) { - qos.transport().user_transports = attr.userTransports; - qos.transport().use_builtin_transports = attr.useBuiltinTransports; + + const std::string profile_name = config["profile_name"].as(); + if (eprosima::fastrtps::types::ReturnCode_t::RETCODE_OK != + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->get_participant_qos_from_profile( + profile_name, + pqos)) + { + std::ostringstream err; + err << "Failed to fetch Fast DDS participant qos from XML " + << "for profile named '" << profile_name << "'"; + + throw DDSMiddlewareException(logger_, err.str()); + } } - - qos.transport().send_socket_buffer_size = attr.sendSocketBufferSize; - qos.transport().listen_socket_buffer_size = attr.listenSocketBufferSize; - qos.name() = attr.getName(); + + return pqos; } -::fastdds::dds::DomainParticipant* Participant::create_participant_with_profile( - const std::string& profile_name) +eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( + const YAML::Node& config) { - using namespace fastrtps::xmlparser; + logger_ << utils::Logger::Level::DEBUG << "#! get_databroker_qos" << std::endl; - fastrtps::ParticipantAttributes attr; - if (XMLP_ret::XML_OK == XMLProfileManager::fillParticipantAttributes(profile_name, attr)) + // Call first std participant qos to reuse std flags for fastdds SH + eprosima::fastdds::dds::DomainParticipantQos pqos = get_participant_qos(config); + + uint32_t server_id = 0; + std::string listening_addresses = ""; + std::string connection_addresses = ""; + + if (config["server_id"]) { - ::fastdds::dds::DomainParticipantQos qos = ::fastdds::dds::PARTICIPANT_QOS_DEFAULT; - set_qos_from_attributes(qos, attr.rtps); + // Conversion to int is needed so it is not treated as a char + server_id = config["server_id"].as() % std::numeric_limits::max(); + } + else + { + logger_ << utils::Logger::Level::INFO + << "Not Server ID set in configuration, use 0 as default" << std::endl; + } - return ::fastdds::dds::DomainParticipantFactory::get_instance()-> - create_participant(attr.domainId, qos); + if (config["listening_addresses"]) + { + listening_addresses = config["listening_addresses"].as(); } else { - std::ostringstream err; - err << "Failed to fetch Fast DDS participant attributes from XML " - << "for profile named '" << profile_name << "'"; + logger_ << utils::Logger::Level::WARN + << "Server has no listening address." + << "It will not discover or connect to other servers." + << std::endl; + } - throw DDSMiddlewareException(logger_, err.str()); + if (config["connection_addresses"]) + { + connection_addresses = config["connection_addresses"].as(); + } + else + { + logger_ << utils::Logger::Level::INFO + << "Server has no connection addresses, it will not try to connect to remote servers" + << std::endl; + } + + logger_ << utils::Logger::Level::DEBUG + << "Server id set by configuration to " << server_id << std::endl; + logger_ << utils::Logger::Level::DEBUG + << "Listening addresses set by configuration to " << listening_addresses << std::endl; + logger_ << utils::Logger::Level::DEBUG + << "Connection addresses set by configuration to " << connection_addresses << std::endl; + + pqos.name("DataBroker_IS-FastDDS-SH_participant"); + + pqos.wire_protocol().builtin.discovery_config.leaseDuration = fastrtps::c_TimeInfinite; + pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = + fastrtps::Duration_t(2, 0); + + pqos.wire_protocol().builtin.discovery_config.discoveryProtocol = + fastrtps::rtps::DiscoveryProtocol::SERVER; + + // Set guid manually depending on the id + pqos.wire_protocol().prefix = guid_server(server_id); + + // Listening configuration + for (auto address : split_locator(listening_addresses)) + { + // Create TCPv4 transport + std::shared_ptr descriptor = + std::make_shared(); + + descriptor->add_listener_port(std::get<1>(address)); + descriptor->set_WAN_address(std::get<0>(address)); + + descriptor->sendBufferSize = 0; + descriptor->receiveBufferSize = 0; + + pqos.transport().user_transports.push_back(descriptor); + + // Create Locator + eprosima::fastrtps::rtps::Locator_t tcp_locator; + tcp_locator.kind = LOCATOR_KIND_TCPv4; + + eprosima::fastrtps::rtps::IPLocator::setIPv4(tcp_locator, std::get<0>(address)); + eprosima::fastrtps::rtps::IPLocator::setWan(tcp_locator, std::get<0>(address)); + eprosima::fastrtps::rtps::IPLocator::setLogicalPort(tcp_locator, std::get<1>(address)); + eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(tcp_locator, std::get<1>(address)); + + pqos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(tcp_locator); } + + // Add every connection address as server + for (auto address : split_ds_locator(connection_addresses)) + { + // Set Server guid manually + eprosima::fastrtps::rtps::RemoteServerAttributes server_attr; + server_attr.guidPrefix = guid_server(std::get<2>(address)); + + // Discovery server locator configuration TCP + eprosima::fastrtps::rtps::Locator_t tcp_locator; + tcp_locator.kind = LOCATOR_KIND_TCPv4; + eprosima::fastrtps::rtps::IPLocator::setIPv4(tcp_locator, std::get<0>(address)); + eprosima::fastrtps::rtps::IPLocator::setLogicalPort(tcp_locator, std::get<1>(address)); + eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(tcp_locator, std::get<1>(address)); + server_attr.metatrafficUnicastLocatorList.push_back(tcp_locator); + + pqos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server_attr); + } + + logger_ << utils::Logger::Level::DEBUG + << "Databroker initialized with GUID " << pqos.wire_protocol().prefix << std::endl; + + return pqos; } } // namespace fastdds diff --git a/src/Participant.hpp b/src/Participant.hpp index 412422f..567035b 100644 --- a/src/Participant.hpp +++ b/src/Participant.hpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -98,7 +99,10 @@ class Participant * @throws DDSMiddlewareException If the *DomainParticipant* could not be created. */ void build_participant( - const ::fastdds::dds::DomainId_t& domain_id = 0); + const YAML::Node& config); + + //! Build participant with empty configuration + void build_participant(); /** * @brief Get the associate *FastDDS DomainParticipant* attribute. @@ -193,23 +197,21 @@ class Participant ::fastdds::dds::Topic* topic, ::fastdds::dds::DomainEntity* entity); -private: +protected: - /** - * @brief Create a *Fast DDS DomainParticipant* using a certain profile. - * - * @note This method is a workaround due to `v2.0.X` versions of *Fast DDS* not including - * this method inside the *DomainParticipantFactory* class. - * - * @param[in] profile_name The XML profile name for the participant. - * - * @returns A correctly initialized DomainParticipant. - * - * @throws DDSMiddlewareException if some error occurs during the creation process. - */ - ::fastdds::dds::DomainParticipant* create_participant_with_profile( - const std::string& profile_name); + //! Get Participant QoS using config file + eprosima::fastdds::dds::DomainParticipantQos get_participant_qos( + const YAML::Node& config); + + //! Get Integration Service Participant default Qos + eprosima::fastdds::dds::DomainParticipantQos get_default_participant_qos(); + //! Get Databroker DomainParticipantQos with TCP enable in WAN + //! It uses \c get_participant_qos to reuse std participant tags + eprosima::fastdds::dds::DomainParticipantQos get_databroker_qos( + const YAML::Node& config); + +private: /** * Class members. diff --git a/src/SystemHandle.cpp b/src/SystemHandle.cpp index 81f77b1..d7aac5b 100644 --- a/src/SystemHandle.cpp +++ b/src/SystemHandle.cpp @@ -69,22 +69,12 @@ class SystemHandle : public virtual FullSystem */ try { - if (configuration["participant"]) - { - participant_ = std::make_unique(configuration["participant"]); - } - else - { - logger_ << utils::Logger::Level::WARN - << "Participant not provided in configuration file. " - << "A participant using the default transport locators " - << "and Domain ID 0 will be created." << std::endl; - - participant_ = std::make_unique(); - } + // TODO Add a warning that was here in Participant build_participant creation + participant_ = std::make_unique(configuration); } catch (DDSMiddlewareException& e) { + logger_ << utils::Logger::Level::ERROR << "Error parsing configuration" << std::endl; e.from_logger << utils::Logger::Level::ERROR << e.what() << std::endl; return false; } diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..32963c0 --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,162 @@ +// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file utils.cpp + * + */ + +#include +#include + +#include "utils.hpp" + +namespace eprosima { +namespace is { +namespace sh { +namespace fastdds { + +std::vector> split_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) +{ + std::vector> result; + + size_t pos_ini = 0; + size_t pos = 0; + std::string token; + + if (addresses == "") + { + return result; + } + + if (addresses.find(address_delimiter) == std::string::npos) + { + // get address ip + std::string ip = addresses.substr(0, addresses.find(value_delimiter)); + + // get port + uint16_t port = std::stol(addresses.substr(ip.length()+1)); + + result.push_back(std::make_pair(ip, port)); + + return result; + } + + do + { + pos = addresses.find(address_delimiter, pos_ini); + + token = addresses.substr(pos_ini, pos - pos_ini); + + // get address ip + std::string ip = addresses.substr(pos_ini, token.find(value_delimiter)); + + // get port + uint16_t port = std::stol(token.substr(ip.length()+1)); + + result.push_back(std::make_pair(ip, port)); + pos_ini = pos + 1; + + }while (pos != std::string::npos); + + return result; +} + +std::vector> split_ds_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) +{ + std::vector> result; + + size_t pos_ini = 0; + size_t pos = 0; + std::string token; + + size_t first_delimiter_pos = 0; + size_t second_delimiter_pos = 0; + + if (addresses == "") + { + return result; + } + + if (addresses.find(address_delimiter) == std::string::npos) + { + first_delimiter_pos = addresses.find(value_delimiter); + second_delimiter_pos = addresses.find(value_delimiter, first_delimiter_pos+1); + + // get address ip + std::string ip = addresses.substr(0, first_delimiter_pos); + + // get port + uint16_t port = std::stol(addresses.substr(first_delimiter_pos+1, second_delimiter_pos)); + + // get id + uint16_t id = std::stol(addresses.substr(second_delimiter_pos+1)); + + result.push_back(std::make_tuple(ip, port, id)); + + return result; + } + + do + { + + pos = addresses.find(address_delimiter, pos_ini); + + token = addresses.substr(pos_ini, pos - pos_ini); + + first_delimiter_pos = token.find(value_delimiter); + second_delimiter_pos = token.find(value_delimiter, first_delimiter_pos+1); + + // get address ip + std::string ip = token.substr(0, first_delimiter_pos); + + // get port + uint16_t port = std::stol(token.substr(first_delimiter_pos+1, second_delimiter_pos)); + + // get id + uint16_t id = std::stol(token.substr(second_delimiter_pos+1)); + + result.push_back(std::make_tuple(ip, port, id)); + pos_ini = pos + 1; + + } while (pos != std::string::npos); + + return result; +} + +std::string print_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) +{ + std::stringstream result; + for (auto locator : split_locator(addresses, value_delimiter, address_delimiter)) + { + result << "IP: " << locator.first << " port: " << locator.second << std::endl; + } + return result.str(); +} + +std::string print_ds_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) +{ + std::stringstream result; + for (auto locator : split_ds_locator(addresses, value_delimiter, address_delimiter)) + { + result << "IP: " << std::get<0>(locator) << " port: " << std::get<1>(locator) + << " id: " << std::get<2>(locator) << std::endl; + } + return result.str(); +} + +} // namespace fastdds +} // namespace sh +} // namespace is +} // namespace eprosima diff --git a/src/utils.hpp b/src/utils.hpp new file mode 100644 index 0000000..26ef000 --- /dev/null +++ b/src/utils.hpp @@ -0,0 +1,59 @@ +// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file utils.hpp + * + */ + +#ifndef _IS_SH_FASTDDS__INTERNAL__UTILS_HPP_ +#define _IS_SH_FASTDDS__INTERNAL__UTILS_HPP_ + +#include +#include + +#include + +namespace eprosima { +namespace is { +namespace sh { +namespace fastdds { + +#define SERVER_DEFAULT_GUID "01.0f.00.44.41.54.95.42.52.4f.4b.45.52" +#define SERVER_DEFAULT_GUID_ID_INDEX 2 +#define DEFAULT_DOMAIN 11 + +inline eprosima::fastrtps::rtps::GuidPrefix_t guid_server( + uint8_t id) +{ + eprosima::fastrtps::rtps::GuidPrefix_t guid; + std::istringstream(SERVER_DEFAULT_GUID) >> guid; + guid.value[SERVER_DEFAULT_GUID_ID_INDEX] = static_cast(id); + return guid; +} + +std::vector> split_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); + +std::vector> split_ds_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); + +std::string print_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); + +std::string print_ds_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); + +} // namespace fastdds +} // namespace sh +} // namespace is +} // namespace eprosima + +#endif // _IS_SH_FASTDDS__INTERNAL__UTILS_HPP_ From c85cf2d0cdf76cc14e4e2889cbf955899c70a090 Mon Sep 17 00:00:00 2001 From: jparisu Date: Wed, 9 Jun 2021 12:36:41 +0200 Subject: [PATCH 02/10] Refs #11770: databroker as type and not tag Signed-off-by: jparisu --- src/Participant.cpp | 215 ++++++++++++++++++++++++++++++-------------- src/Participant.hpp | 1 + 2 files changed, 151 insertions(+), 65 deletions(-) diff --git a/src/Participant.cpp b/src/Participant.cpp index b32db53..25f7603 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -99,13 +99,13 @@ void Participant::build_participant( ::fastdds::dds::DomainParticipantQos participant_qos; // Depending the SH type, use participant std qos or databroker qos - if (config["participant"]) + if (config["type"] && config["type"].as() == "databroker") { - participant_qos = get_participant_qos(config["participant"]); + participant_qos = get_databroker_qos(config["participant"]); } - else if (config["databroker"]) + else { - participant_qos = get_databroker_qos(config["databroker"]); + participant_qos = get_participant_qos(config["participant"]); } dds_participant_ = ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant( @@ -377,14 +377,15 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( // Call first std participant qos to reuse std flags for fastdds SH eprosima::fastdds::dds::DomainParticipantQos pqos = get_participant_qos(config); + ////// + // Server id uint32_t server_id = 0; - std::string listening_addresses = ""; - std::string connection_addresses = ""; - if (config["server_id"]) { // Conversion to int is needed so it is not treated as a char server_id = config["server_id"].as() % std::numeric_limits::max(); + logger_ << utils::Logger::Level::DEBUG + << "Server id set by configuration to " << server_id << std::endl; } else { @@ -392,9 +393,77 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( << "Not Server ID set in configuration, use 0 as default" << std::endl; } + // Set guid manually depending on the id + pqos.wire_protocol().prefix = guid_server(server_id); + pqos.name("DataBroker_IS-FastDDS-SH_participant_" + std::to_string(server_id)); + + ////// + // Listening addresses if (config["listening_addresses"]) { - listening_addresses = config["listening_addresses"].as(); + YAML::Node listening_addresses = config["listening_addresses"]; + + // Configure listening address + for (auto address : listening_addresses) + { + std::string ip; + uint16_t port; + + // Get address values. If not present, send error + if (address["ip"]) + { + ip = address["ip"].as(); + } + else + { + std::ostringstream err; + err << "Address in must contain a field "; + + logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; + + continue; + } + + if (address["port"]) + { + port = address["port"].as(); + } + else + { + std::ostringstream err; + err << "Address in must contain a field "; + + logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; + + continue; + } + + // Create TCPv4 transport + std::shared_ptr descriptor = + std::make_shared(); + + descriptor->add_listener_port(port); + descriptor->set_WAN_address(ip); + + descriptor->sendBufferSize = 0; + descriptor->receiveBufferSize = 0; + + pqos.transport().user_transports.push_back(descriptor); + + // Create Locator + eprosima::fastrtps::rtps::Locator_t tcp_locator; + tcp_locator.kind = LOCATOR_KIND_TCPv4; + + eprosima::fastrtps::rtps::IPLocator::setIPv4(tcp_locator, ip); + eprosima::fastrtps::rtps::IPLocator::setWan(tcp_locator, ip); + eprosima::fastrtps::rtps::IPLocator::setLogicalPort(tcp_locator, port); + eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(tcp_locator, port); + + pqos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(tcp_locator); + + logger_ << utils::Logger::Level::DEBUG + << "Server listening in: " << ip << ":" << port << std::endl; + } } else { @@ -404,81 +473,97 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( << std::endl; } + ////// + // Connection addresses if (config["connection_addresses"]) { - connection_addresses = config["connection_addresses"].as(); - } - else - { - logger_ << utils::Logger::Level::INFO - << "Server has no connection addresses, it will not try to connect to remote servers" - << std::endl; - } + YAML::Node connection_addresses = config["connection_addresses"]; - logger_ << utils::Logger::Level::DEBUG - << "Server id set by configuration to " << server_id << std::endl; - logger_ << utils::Logger::Level::DEBUG - << "Listening addresses set by configuration to " << listening_addresses << std::endl; - logger_ << utils::Logger::Level::DEBUG - << "Connection addresses set by configuration to " << connection_addresses << std::endl; + // Configure listening address + for (auto address : connection_addresses) + { + std::string ip; + uint16_t port; + uint16_t server_id; - pqos.name("DataBroker_IS-FastDDS-SH_participant"); + // Get address values. If not present, send error + if (address["ip"]) + { + ip = address["ip"].as(); + } + else + { + std::ostringstream err; + err << "Address in must contain a field "; - pqos.wire_protocol().builtin.discovery_config.leaseDuration = fastrtps::c_TimeInfinite; - pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = - fastrtps::Duration_t(2, 0); + logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - pqos.wire_protocol().builtin.discovery_config.discoveryProtocol = - fastrtps::rtps::DiscoveryProtocol::SERVER; + continue; + } - // Set guid manually depending on the id - pqos.wire_protocol().prefix = guid_server(server_id); + if (address["port"]) + { + port = address["port"].as(); + } + else + { + std::ostringstream err; + err << "Address in must contain a field "; - // Listening configuration - for (auto address : split_locator(listening_addresses)) - { - // Create TCPv4 transport - std::shared_ptr descriptor = - std::make_shared(); + logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - descriptor->add_listener_port(std::get<1>(address)); - descriptor->set_WAN_address(std::get<0>(address)); + continue; + } - descriptor->sendBufferSize = 0; - descriptor->receiveBufferSize = 0; + if (address["server_id"]) + { + server_id = address["server_id"].as(); + } + else + { + std::ostringstream err; + err << "Address in must contain a field "; - pqos.transport().user_transports.push_back(descriptor); + logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - // Create Locator - eprosima::fastrtps::rtps::Locator_t tcp_locator; - tcp_locator.kind = LOCATOR_KIND_TCPv4; + continue; + } - eprosima::fastrtps::rtps::IPLocator::setIPv4(tcp_locator, std::get<0>(address)); - eprosima::fastrtps::rtps::IPLocator::setWan(tcp_locator, std::get<0>(address)); - eprosima::fastrtps::rtps::IPLocator::setLogicalPort(tcp_locator, std::get<1>(address)); - eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(tcp_locator, std::get<1>(address)); + // Set Server guid manually + eprosima::fastrtps::rtps::RemoteServerAttributes server_attr; + server_attr.guidPrefix = guid_server(server_id); - pqos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(tcp_locator); - } + // Discovery server locator configuration TCP + eprosima::fastrtps::rtps::Locator_t tcp_locator; + tcp_locator.kind = LOCATOR_KIND_TCPv4; + eprosima::fastrtps::rtps::IPLocator::setIPv4(tcp_locator, ip); + eprosima::fastrtps::rtps::IPLocator::setLogicalPort(tcp_locator, port); + eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(tcp_locator, port); + server_attr.metatrafficUnicastLocatorList.push_back(tcp_locator); - // Add every connection address as server - for (auto address : split_ds_locator(connection_addresses)) + pqos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server_attr); + + logger_ << utils::Logger::Level::DEBUG + << "Connecting to remote server with guid: " << server_attr.guidPrefix + << " in: " << ip << ":" << port << std::endl; + } + } + else { - // Set Server guid manually - eprosima::fastrtps::rtps::RemoteServerAttributes server_attr; - server_attr.guidPrefix = guid_server(std::get<2>(address)); - - // Discovery server locator configuration TCP - eprosima::fastrtps::rtps::Locator_t tcp_locator; - tcp_locator.kind = LOCATOR_KIND_TCPv4; - eprosima::fastrtps::rtps::IPLocator::setIPv4(tcp_locator, std::get<0>(address)); - eprosima::fastrtps::rtps::IPLocator::setLogicalPort(tcp_locator, std::get<1>(address)); - eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(tcp_locator, std::get<1>(address)); - server_attr.metatrafficUnicastLocatorList.push_back(tcp_locator); - - pqos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server_attr); + logger_ << utils::Logger::Level::INFO + << "Server has no connection addresses, it will not try to connect to remote servers" + << std::endl; } + // TODO decide the discovery server configuration + pqos.wire_protocol().builtin.discovery_config.leaseDuration = fastrtps::c_TimeInfinite; + pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = + fastrtps::Duration_t(2, 0); + + // Set this participant as a SERVER + pqos.wire_protocol().builtin.discovery_config.discoveryProtocol = + fastrtps::rtps::DiscoveryProtocol::SERVER; + logger_ << utils::Logger::Level::DEBUG << "Databroker initialized with GUID " << pqos.wire_protocol().prefix << std::endl; diff --git a/src/Participant.hpp b/src/Participant.hpp index 567035b..1fb93a5 100644 --- a/src/Participant.hpp +++ b/src/Participant.hpp @@ -208,6 +208,7 @@ class Participant //! Get Databroker DomainParticipantQos with TCP enable in WAN //! It uses \c get_participant_qos to reuse std participant tags + //! tags: server_id, listening_addresses, connection_addresses eprosima::fastdds::dds::DomainParticipantQos get_databroker_qos( const YAML::Node& config); From efe46ae34a401db85ff738066633e46f2a9323c6 Mon Sep 17 00:00:00 2001 From: jparisu Date: Wed, 9 Jun 2021 12:50:54 +0200 Subject: [PATCH 03/10] Refs #11770: remove unused functions Signed-off-by: jparisu --- CMakeLists.txt | 1 - src/utils.cpp | 162 ------------------------------------------------- src/utils.hpp | 9 --- 3 files changed, 172 deletions(-) delete mode 100644 src/utils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a28bf3..f5fb7df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,6 @@ if(BUILD_LIBRARY) src/Server.cpp src/Participant.cpp src/SystemHandle.cpp - src/utils.cpp ) endif() diff --git a/src/utils.cpp b/src/utils.cpp deleted file mode 100644 index 32963c0..0000000 --- a/src/utils.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @file utils.cpp - * - */ - -#include -#include - -#include "utils.hpp" - -namespace eprosima { -namespace is { -namespace sh { -namespace fastdds { - -std::vector> split_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) -{ - std::vector> result; - - size_t pos_ini = 0; - size_t pos = 0; - std::string token; - - if (addresses == "") - { - return result; - } - - if (addresses.find(address_delimiter) == std::string::npos) - { - // get address ip - std::string ip = addresses.substr(0, addresses.find(value_delimiter)); - - // get port - uint16_t port = std::stol(addresses.substr(ip.length()+1)); - - result.push_back(std::make_pair(ip, port)); - - return result; - } - - do - { - pos = addresses.find(address_delimiter, pos_ini); - - token = addresses.substr(pos_ini, pos - pos_ini); - - // get address ip - std::string ip = addresses.substr(pos_ini, token.find(value_delimiter)); - - // get port - uint16_t port = std::stol(token.substr(ip.length()+1)); - - result.push_back(std::make_pair(ip, port)); - pos_ini = pos + 1; - - }while (pos != std::string::npos); - - return result; -} - -std::vector> split_ds_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) -{ - std::vector> result; - - size_t pos_ini = 0; - size_t pos = 0; - std::string token; - - size_t first_delimiter_pos = 0; - size_t second_delimiter_pos = 0; - - if (addresses == "") - { - return result; - } - - if (addresses.find(address_delimiter) == std::string::npos) - { - first_delimiter_pos = addresses.find(value_delimiter); - second_delimiter_pos = addresses.find(value_delimiter, first_delimiter_pos+1); - - // get address ip - std::string ip = addresses.substr(0, first_delimiter_pos); - - // get port - uint16_t port = std::stol(addresses.substr(first_delimiter_pos+1, second_delimiter_pos)); - - // get id - uint16_t id = std::stol(addresses.substr(second_delimiter_pos+1)); - - result.push_back(std::make_tuple(ip, port, id)); - - return result; - } - - do - { - - pos = addresses.find(address_delimiter, pos_ini); - - token = addresses.substr(pos_ini, pos - pos_ini); - - first_delimiter_pos = token.find(value_delimiter); - second_delimiter_pos = token.find(value_delimiter, first_delimiter_pos+1); - - // get address ip - std::string ip = token.substr(0, first_delimiter_pos); - - // get port - uint16_t port = std::stol(token.substr(first_delimiter_pos+1, second_delimiter_pos)); - - // get id - uint16_t id = std::stol(token.substr(second_delimiter_pos+1)); - - result.push_back(std::make_tuple(ip, port, id)); - pos_ini = pos + 1; - - } while (pos != std::string::npos); - - return result; -} - -std::string print_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) -{ - std::stringstream result; - for (auto locator : split_locator(addresses, value_delimiter, address_delimiter)) - { - result << "IP: " << locator.first << " port: " << locator.second << std::endl; - } - return result.str(); -} - -std::string print_ds_locator(std::string addresses, std::string value_delimiter, std::string address_delimiter) -{ - std::stringstream result; - for (auto locator : split_ds_locator(addresses, value_delimiter, address_delimiter)) - { - result << "IP: " << std::get<0>(locator) << " port: " << std::get<1>(locator) - << " id: " << std::get<2>(locator) << std::endl; - } - return result.str(); -} - -} // namespace fastdds -} // namespace sh -} // namespace is -} // namespace eprosima diff --git a/src/utils.hpp b/src/utils.hpp index 26ef000..35a566f 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -32,7 +32,6 @@ namespace fastdds { #define SERVER_DEFAULT_GUID "01.0f.00.44.41.54.95.42.52.4f.4b.45.52" #define SERVER_DEFAULT_GUID_ID_INDEX 2 -#define DEFAULT_DOMAIN 11 inline eprosima::fastrtps::rtps::GuidPrefix_t guid_server( uint8_t id) @@ -43,14 +42,6 @@ inline eprosima::fastrtps::rtps::GuidPrefix_t guid_server( return guid; } -std::vector> split_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); - -std::vector> split_ds_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); - -std::string print_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); - -std::string print_ds_locator(std::string addresses, std::string value_delimiter=",", std::string address_delimiter=";"); - } // namespace fastdds } // namespace sh } // namespace is From ba9969c88bff9d5ac588aaf51cdb1beb9aebe2b0 Mon Sep 17 00:00:00 2001 From: jparisu Date: Wed, 9 Jun 2021 14:27:33 +0200 Subject: [PATCH 04/10] Refs #11770: fix yaml parse typo Signed-off-by: jparisu --- src/Participant.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Participant.cpp b/src/Participant.cpp index 25f7603..18bd3b6 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -72,29 +72,24 @@ void Participant::build_participant() void Participant::build_participant( const YAML::Node& config) { - logger_ << utils::Logger::Level::DEBUG << "Creating new fastdds Participant" << std::endl; - // Check if domain_id exists in config eprosima::fastdds::dds::DomainId_t domain_id(0); // Check if domain_id tag is under other tag if (config["domain_id"]) { - logger_ << utils::Logger::Level::DEBUG << "#! Get Domain from plain config" << std::endl; domain_id = config["domain_id"].as(); } else if (config["participant"] && config["participant"]["domain_id"]) { - logger_ << utils::Logger::Level::DEBUG << "#! Get Domain from participant" << std::endl; domain_id = config["participant"]["domain_id"].as(); } else if (config["databroker"] && config["databroker"]["domain_id"]) { - logger_ << utils::Logger::Level::DEBUG << "#! Get Domain from databroker" << std::endl; domain_id = config["databroker"]["domain_id"].as(); } - logger_ << utils::Logger::Level::DEBUG << "Creating Participant QoS" << std::endl; + logger_ << utils::Logger::Level::DEBUG << "Creating new fastdds Participant in domain " << domain_id << std::endl; ::fastdds::dds::DomainParticipantQos participant_qos; @@ -105,7 +100,15 @@ void Participant::build_participant( } else { - participant_qos = get_participant_qos(config["participant"]); + if (config["participant"]) + { + participant_qos = get_participant_qos(config["participant"]); + } + else + { + // Case there is not participant tag in config it sends an empty yaml + participant_qos = get_participant_qos(YAML::Node()); + } } dds_participant_ = ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant( @@ -312,8 +315,6 @@ bool Participant::dissociate_topic_from_dds_entity( eprosima::fastdds::dds::DomainParticipantQos Participant::get_default_participant_qos() { - logger_ << utils::Logger::Level::DEBUG << "#! get_default_participant_qos" << std::endl; - eprosima::fastdds::dds::DomainParticipantQos df_pqos; df_pqos.name("default_IS-FastDDS-SH_participant"); @@ -329,8 +330,6 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_default_participan eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( const YAML::Node& config) { - logger_ << utils::Logger::Level::DEBUG << "#! get_participant_qos" << std::endl; - // Load XML if set in config yaml if (config["file_path"]) { @@ -372,8 +371,6 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( const YAML::Node& config) { - logger_ << utils::Logger::Level::DEBUG << "#! get_databroker_qos" << std::endl; - // Call first std participant qos to reuse std flags for fastdds SH eprosima::fastdds::dds::DomainParticipantQos pqos = get_participant_qos(config); From 82670d75b2cf43f4588205e0335e215323f634ae Mon Sep 17 00:00:00 2001 From: jparisu Date: Fri, 16 Jul 2021 11:28:42 +0200 Subject: [PATCH 05/10] Refs #11770: Databroker implementation Signed-off-by: jparisu --- CMakeLists.txt | 7 ++++++ src/Participant.cpp | 10 +-------- src/Participant.hpp | 52 ++++++++++++++++++++++++++++++++++++++------ src/SystemHandle.cpp | 6 +++-- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5fb7df..a976582 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,11 @@ option(IS_FASTDDS_SH_USING_FASTDDS_EXTERNALPROJECT option(BUILD_LIBRARY "Compile the Fast DDS SystemHandle" ON) +################################################################################### +# Set Aliases for FastDDS SH +################################################################################### +set (ALIASES "databroker") + ################################################################################### # Load external CMake Modules. ################################################################################### @@ -224,6 +229,8 @@ if(BUILD_LIBRARY) fastdds TARGET is-fastdds + ALIAS + ${ALIASES} ) endif() diff --git a/src/Participant.cpp b/src/Participant.cpp index 18bd3b6..6c05ead 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -75,19 +75,11 @@ void Participant::build_participant( // Check if domain_id exists in config eprosima::fastdds::dds::DomainId_t domain_id(0); - // Check if domain_id tag is under other tag + // Check if domain_id tag is present inconfiguration, if not 0 as default if (config["domain_id"]) { domain_id = config["domain_id"].as(); } - else if (config["participant"] && config["participant"]["domain_id"]) - { - domain_id = config["participant"]["domain_id"].as(); - } - else if (config["databroker"] && config["databroker"]["domain_id"]) - { - domain_id = config["databroker"]["domain_id"].as(); - } logger_ << utils::Logger::Level::DEBUG << "Creating new fastdds Participant in domain " << domain_id << std::endl; diff --git a/src/Participant.hpp b/src/Participant.hpp index 1fb93a5..9c5ef93 100644 --- a/src/Participant.hpp +++ b/src/Participant.hpp @@ -69,7 +69,7 @@ class Participant * in the *YAML* configuration file. * * @param[in] config The configuration provided by the user. - * It must contain two keys in the *YAML* map: + * In case of fastdds type it can contain two keys in the *YAML* map: * * - `file_path`: Specifies the path to the XML profile that will be used to configure the * *DomainParticipant*. More information on how to write these XML profiles can be found @@ -80,6 +80,19 @@ class Participant * that corresponds to the configuration profile that we want this Participant * to be configured with. * + * In case of databroker type it can contain three keys in the *YAML* map: + * + * - `server_id`: Specifies the Discovery Server id in order to generate a GUID to it. + * + * - `listening_addresses`: Specifies a list of TCP listening addresses. + * - `ip`: Public IP where the Server will be listening. + * - `port`: Port where the Server will be listening. + * + * - `connection_addresses`: Specifies a list of TCP connection addresses. + * - `ip`: Public IP to the Server to connect with. + * - `port`: Port to the Server to connect with. + * - `server_id`: Id of the remote server to connect. + * * @throws DDSMiddlewareException If the XML profile was incorrect and, thus, the * *DomainParticipant* could not be created. */ @@ -94,7 +107,7 @@ class Participant /** * @brief Construct a *Fast DDS DomainParticipant*, given its DDS domain ID. * - * @param[in] domain_id The DDS domain ID for this participant. + * @param[in] config The configuration provided by the user. * * @throws DDSMiddlewareException If the *DomainParticipant* could not be created. */ @@ -199,16 +212,41 @@ class Participant protected: - //! Get Participant QoS using config file + /** + * @brief Get Participant QoS using config file. + * + * Set all default values to QoS and then use specific FastSH tags to configure the participant: + * Tags: file_path, profile_name + * + * @param[in] config The configuration provided by the user. + * + * @return Specific QoS by user configuration. + */ eprosima::fastdds::dds::DomainParticipantQos get_participant_qos( const YAML::Node& config); - //! Get Integration Service Participant default Qos + /** + * @brief Get Integration Service Participant default Qos + * + * @return Defult SystemHandler Participant QoS + */ eprosima::fastdds::dds::DomainParticipantQos get_default_participant_qos(); - //! Get Databroker DomainParticipantQos with TCP enable in WAN - //! It uses \c get_participant_qos to reuse std participant tags - //! tags: server_id, listening_addresses, connection_addresses + /** + * @brief Get Databroker DomainParticipantQos with TCP enable in WAN + * + * It uses \c get_participant_qos to reuse std participant tags and the uses specific databroker tags: + * Databroker tags: + * server_id : id of the Discovery Server [0:256) + * listening_addresses : Listening addresses (public) for Discovery Server to listen in TCP + * fields : ip, port + * connection_addresses : Connection addresses for Discovery Server to connect with other servers + * fields : ip, port, server_id + * + * @param config The configuration provided by the user. + * + * @return Specific QoS by user configuration. + */ eprosima::fastdds::dds::DomainParticipantQos get_databroker_qos( const YAML::Node& config); diff --git a/src/SystemHandle.cpp b/src/SystemHandle.cpp index d7aac5b..bcf2fd8 100644 --- a/src/SystemHandle.cpp +++ b/src/SystemHandle.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). + * Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,7 @@ class SystemHandle : public virtual FullSystem } catch (DDSMiddlewareException& e) { - logger_ << utils::Logger::Level::ERROR << "Error parsing configuration" << std::endl; + logger_ << utils::Logger::Level::ERROR << "Error creating participant" << std::endl; e.from_logger << utils::Logger::Level::ERROR << e.what() << std::endl; return false; } @@ -291,4 +291,6 @@ class SystemHandle : public virtual FullSystem } // namespace is } // namespace eprosima +// TODO aliases must come from CMAKE IS_REGISTER_SYSTEM("fastdds", eprosima::is::sh::fastdds::SystemHandle) +IS_REGISTER_SYSTEM("databroker", eprosima::is::sh::fastdds::SystemHandle) From 661fd64b32a5e29e66757966f91e7aace7a0d9bf Mon Sep 17 00:00:00 2001 From: jparisu Date: Mon, 19 Jul 2021 13:09:25 +0200 Subject: [PATCH 06/10] Refs #12151: apply suggestions Signed-off-by: jparisu --- src/Participant.cpp | 88 ++++++++++------------------ src/Participant.hpp | 42 ++++++------- src/SystemHandle.cpp | 2 +- src/{ => utils/databroker}/utils.hpp | 0 4 files changed, 53 insertions(+), 79 deletions(-) rename src/{ => utils/databroker}/utils.hpp (100%) diff --git a/src/Participant.cpp b/src/Participant.cpp index 6c05ead..9558f26 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -18,7 +18,7 @@ #include "Participant.hpp" #include "DDSMiddlewareException.hpp" #include "Conversion.hpp" -#include "utils.hpp" +#include "utils/databroker/utils.hpp" #include #include @@ -37,7 +37,7 @@ Participant::Participant() : dds_participant_(nullptr) , logger_("is::sh::FastDDS::Participant") { - build_participant(); + build_participant(YAML::Node()); } Participant::Participant( @@ -63,29 +63,24 @@ Participant::~Participant() } } -void Participant::build_participant() -{ - // Call build participant with empty configuration - build_participant(YAML::Node()); -} - void Participant::build_participant( const YAML::Node& config) { - // Check if domain_id exists in config + // Set 0 as default domain eprosima::fastdds::dds::DomainId_t domain_id(0); // Check if domain_id tag is present inconfiguration, if not 0 as default - if (config["domain_id"]) + if (config["participant"] && config["participant"]["domain_id"]) { - domain_id = config["domain_id"].as(); + domain_id = config["participant"]["domain_id"].as(); } - logger_ << utils::Logger::Level::DEBUG << "Creating new fastdds Participant in domain " << domain_id << std::endl; + logger_ << utils::Logger::Level::DEBUG + << "Creating Fast DDS Participant in domain " << domain_id << std::endl; ::fastdds::dds::DomainParticipantQos participant_qos; - // Depending the SH type, use participant std qos or databroker qos + // Depending the SH type, use participant qos or databroker qos if (config["type"] && config["type"].as() == "databroker") { participant_qos = get_databroker_qos(config["participant"]); @@ -330,7 +325,8 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( fastrtps::xmlparser::XMLProfileManager::loadXMLFile(file_path)) { std::ostringstream err; - err << "Loading provided XML file in 'file_path': " << file_path << " incorrect or unexisted file"; + err << "Failed to load XML file provided in 'file_path': " << file_path + << ". It cannot be found or is incorrect."; throw DDSMiddlewareException( logger_, err.str()); } @@ -350,7 +346,7 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( pqos)) { std::ostringstream err; - err << "Failed to fetch Fast DDS participant qos from XML " + err << "Failed to fetch Fast DDS Participant QoS from XML " << "for profile named '" << profile_name << "'"; throw DDSMiddlewareException(logger_, err.str()); @@ -363,10 +359,9 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( const YAML::Node& config) { - // Call first std participant qos to reuse std flags for fastdds SH + // Use the Participant QoS as base for the Databroker QoS eprosima::fastdds::dds::DomainParticipantQos pqos = get_participant_qos(config); - ////// // Server id uint32_t server_id = 0; if (config["server_id"]) @@ -374,26 +369,23 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( // Conversion to int is needed so it is not treated as a char server_id = config["server_id"].as() % std::numeric_limits::max(); logger_ << utils::Logger::Level::DEBUG - << "Server id set by configuration to " << server_id << std::endl; + << "Server ID set to " << server_id << std::endl; } else { logger_ << utils::Logger::Level::INFO - << "Not Server ID set in configuration, use 0 as default" << std::endl; + << "The Server ID is not set in the configuration file. It will be set to 0." << std::endl; } - // Set guid manually depending on the id + // Set GUID depending on the id pqos.wire_protocol().prefix = guid_server(server_id); pqos.name("DataBroker_IS-FastDDS-SH_participant_" + std::to_string(server_id)); - ////// // Listening addresses if (config["listening_addresses"]) { - YAML::Node listening_addresses = config["listening_addresses"]; - // Configure listening address - for (auto address : listening_addresses) + for (auto address : config["listening_addresses"]) { std::string ip; uint16_t port; @@ -405,11 +397,8 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - std::ostringstream err; - err << "Address in must contain a field "; - - logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - + logger_ << utils::Logger::Level::WARN + << "The addresses in 'listening_addresses' must contain a tag 'ip'." << std::endl; continue; } @@ -419,11 +408,8 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - std::ostringstream err; - err << "Address in must contain a field "; - - logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - + logger_ << utils::Logger::Level::WARN + << "The addresses in 'listening_addresses' must contain a tag 'port'. " << std::endl; continue; } @@ -462,14 +448,11 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( << std::endl; } - ////// // Connection addresses if (config["connection_addresses"]) { - YAML::Node connection_addresses = config["connection_addresses"]; - // Configure listening address - for (auto address : connection_addresses) + for (auto address : config["connection_addresses"]) { std::string ip; uint16_t port; @@ -482,11 +465,8 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - std::ostringstream err; - err << "Address in must contain a field "; - - logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - + logger_ << utils::Logger::Level::WARN + << "The addresses in 'connection_addresses' must contain a tag 'ip'." << std::endl; continue; } @@ -496,11 +476,8 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - std::ostringstream err; - err << "Address in must contain a field "; - - logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - + logger_ << utils::Logger::Level::WARN + << "The addresses in 'connection_addresses' must contain a tag 'port'." << std::endl; continue; } @@ -510,15 +487,12 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - std::ostringstream err; - err << "Address in must contain a field "; - - logger_ << utils::Logger::Level::ERROR << err.str() << std::endl; - + logger_ << utils::Logger::Level::WARN + << "The addresses in 'connection_addresses' must contain a tag 'server_id'." << std::endl; continue; } - // Set Server guid manually + // Set Server GUID eprosima::fastrtps::rtps::RemoteServerAttributes server_attr; server_attr.guidPrefix = guid_server(server_id); @@ -533,14 +507,14 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( pqos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server_attr); logger_ << utils::Logger::Level::DEBUG - << "Connecting to remote server with guid: " << server_attr.guidPrefix + << "Connecting to remote server with GUID: " << server_attr.guidPrefix << " in: " << ip << ":" << port << std::endl; } } else { logger_ << utils::Logger::Level::INFO - << "Server has no connection addresses, it will not try to connect to remote servers" + << "Server has no connection addresses. It will not try to connect to remote servers" << std::endl; } @@ -554,7 +528,7 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( fastrtps::rtps::DiscoveryProtocol::SERVER; logger_ << utils::Logger::Level::DEBUG - << "Databroker initialized with GUID " << pqos.wire_protocol().prefix << std::endl; + << "Databroker initialized with GUID: " << pqos.wire_protocol().prefix << std::endl; return pqos; } diff --git a/src/Participant.hpp b/src/Participant.hpp index 9c5ef93..09b9870 100644 --- a/src/Participant.hpp +++ b/src/Participant.hpp @@ -82,16 +82,16 @@ class Participant * * In case of databroker type it can contain three keys in the *YAML* map: * - * - `server_id`: Specifies the Discovery Server id in order to generate a GUID to it. + * - `server_id`: Specifies the Discovery Server ID in order to generate its GUID. * * - `listening_addresses`: Specifies a list of TCP listening addresses. - * - `ip`: Public IP where the Server will be listening. - * - `port`: Port where the Server will be listening. + * - `ip`: Provides the public IP where the Server will be listening. + * - `port`: Provides the port where the Server will be listening. * * - `connection_addresses`: Specifies a list of TCP connection addresses. - * - `ip`: Public IP to the Server to connect with. - * - `port`: Port to the Server to connect with. - * - `server_id`: Id of the remote server to connect. + * - `ip`: Provides the public IP of the Server to connect to. + * - `port`: Provides the port of the Server to connect to. + * - `server_id`: Provides the ID of the remote Server to connect to. * * @throws DDSMiddlewareException If the XML profile was incorrect and, thus, the * *DomainParticipant* could not be created. @@ -114,9 +114,6 @@ class Participant void build_participant( const YAML::Node& config); - //! Build participant with empty configuration - void build_participant(); - /** * @brief Get the associate *FastDDS DomainParticipant* attribute. * @@ -226,24 +223,27 @@ class Participant const YAML::Node& config); /** - * @brief Get Integration Service Participant default Qos + * @brief Get Fast DDS System Handle Participant default QoS * - * @return Defult SystemHandler Participant QoS + * @return Default Participant QoS */ eprosima::fastdds::dds::DomainParticipantQos get_default_participant_qos(); /** - * @brief Get Databroker DomainParticipantQos with TCP enable in WAN - * - * It uses \c get_participant_qos to reuse std participant tags and the uses specific databroker tags: - * Databroker tags: - * server_id : id of the Discovery Server [0:256) - * listening_addresses : Listening addresses (public) for Discovery Server to listen in TCP - * fields : ip, port - * connection_addresses : Connection addresses for Discovery Server to connect with other servers - * fields : ip, port, server_id + * @brief Get Databroker DomainParticipantQos. + * @details The transport used over WAN is TCP. + * It calls \c get_participant_qos to reuse Participant YAML tags and then applies the specific Databroker tags: + * Databroker tags: + * * server_id: ID of the Discovery Server. It must be within the valid range [0:256). + * * listening_addresses: Listening addresses (public) for Discovery Server to listen in TCP. + * * ip + * * port + * * connection_addresses: Connection addresses for Discovery Server to connect to other servers. + * * ip + * * port + * * server_id * - * @param config The configuration provided by the user. + * @param[in] config The configuration provided by the user. * * @return Specific QoS by user configuration. */ diff --git a/src/SystemHandle.cpp b/src/SystemHandle.cpp index bcf2fd8..052468d 100644 --- a/src/SystemHandle.cpp +++ b/src/SystemHandle.cpp @@ -74,7 +74,7 @@ class SystemHandle : public virtual FullSystem } catch (DDSMiddlewareException& e) { - logger_ << utils::Logger::Level::ERROR << "Error creating participant" << std::endl; + logger_ << utils::Logger::Level::ERROR << "Participant creation failed." << std::endl; e.from_logger << utils::Logger::Level::ERROR << e.what() << std::endl; return false; } diff --git a/src/utils.hpp b/src/utils/databroker/utils.hpp similarity index 100% rename from src/utils.hpp rename to src/utils/databroker/utils.hpp From 29e0d9ea6a7bfb15e58323653a34403212bb365b Mon Sep 17 00:00:00 2001 From: jparisu Date: Mon, 19 Jul 2021 14:51:30 +0200 Subject: [PATCH 07/10] Refs #12151: Fix compatibility with fast 2.0.x Signed-off-by: jparisu --- src/Client.cpp | 4 +- src/Participant.cpp | 102 +++++++++++++++++++------------------------- src/Participant.hpp | 13 ------ src/Server.cpp | 8 ++-- src/Subscriber.cpp | 8 ++-- 5 files changed, 54 insertions(+), 81 deletions(-) diff --git a/src/Client.cpp b/src/Client.cpp index 1d68d28..99624bf 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -27,9 +27,9 @@ #include #include #include -#if FASTRTPS_VERSION_MINOR >= 2 +#if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 #include -#endif // if FASTRTPS_VERSION_MINOR >= 2 +#endif // if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 #include diff --git a/src/Participant.cpp b/src/Participant.cpp index 9558f26..e537a16 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -78,40 +78,68 @@ void Participant::build_participant( logger_ << utils::Logger::Level::DEBUG << "Creating Fast DDS Participant in domain " << domain_id << std::endl; - ::fastdds::dds::DomainParticipantQos participant_qos; - - // Depending the SH type, use participant qos or databroker qos - if (config["type"] && config["type"].as() == "databroker") + // Loading XML if file_path is given + if (config["participant"] && config["participant"]["file_path"]) { - participant_qos = get_databroker_qos(config["participant"]); + const std::string file_path = config["file_path"].as(); + if (fastrtps::xmlparser::XMLP_ret::XML_OK != + fastrtps::xmlparser::XMLProfileManager::loadXMLFile(file_path)) + { + std::ostringstream err; + err << "Failed to load XML file provided in 'file_path': " << file_path + << ". It cannot be found or is incorrect."; + throw DDSMiddlewareException( + logger_, err.str()); + } } - else + + // Debug variable + std::string participant_name; + + // If profile_name is given in configuration, the other tags do not apply + if (!config["participant"] || !config["participant"]["profile_name"]) { - if (config["participant"]) + // Participant QoS + ::fastdds::dds::DomainParticipantQos participant_qos; + + // Depending the SH type, use participant qos or databroker qos + // TODO : change for databroker alias refactor + if (config["type"] && config["type"].as() == "databroker") { - participant_qos = get_participant_qos(config["participant"]); + participant_qos = get_databroker_qos(config["participant"]); } else { - // Case there is not participant tag in config it sends an empty yaml - participant_qos = get_participant_qos(YAML::Node()); + participant_qos = get_default_participant_qos(); } + + participant_name = participant_qos.name(); + + dds_participant_ = + ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant( + domain_id, + participant_qos); } + else + { + participant_name = config["participant"]["profile_name"].as(); - dds_participant_ = ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant( - domain_id, - participant_qos); + // Create Participant from profile name + dds_participant_ = + ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant_with_profile( + config["profile_name"].as()); + } if (dds_participant_) { logger_ << utils::Logger::Level::INFO - << "Created Fast DDS participant '" << participant_qos.name() + << "Created Fast DDS participant '" << participant_name << "' with Domain ID: " << domain_id << std::endl; } else { std::ostringstream err; - err << "Error while creating Fast DDS participant '" << participant_qos.name() + err << "Error while creating Fast DDS participant '" << participant_name << "' with Domain ID: " << domain_id; throw DDSMiddlewareException(logger_, err.str()); @@ -314,53 +342,11 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_default_participan return df_pqos; } -eprosima::fastdds::dds::DomainParticipantQos Participant::get_participant_qos( - const YAML::Node& config) -{ - // Load XML if set in config yaml - if (config["file_path"]) - { - const std::string file_path = config["file_path"].as(); - if (fastrtps::xmlparser::XMLP_ret::XML_OK != - fastrtps::xmlparser::XMLProfileManager::loadXMLFile(file_path)) - { - std::ostringstream err; - err << "Failed to load XML file provided in 'file_path': " << file_path - << ". It cannot be found or is incorrect."; - throw DDSMiddlewareException( - logger_, err.str()); - } - } - - // Variable to return - eprosima::fastdds::dds::DomainParticipantQos pqos = get_default_participant_qos(); - - // Load XML if set in config yaml - if (config["profile_name"]) - { - - const std::string profile_name = config["profile_name"].as(); - if (eprosima::fastrtps::types::ReturnCode_t::RETCODE_OK != - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->get_participant_qos_from_profile( - profile_name, - pqos)) - { - std::ostringstream err; - err << "Failed to fetch Fast DDS Participant QoS from XML " - << "for profile named '" << profile_name << "'"; - - throw DDSMiddlewareException(logger_, err.str()); - } - } - - return pqos; -} - eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( const YAML::Node& config) { // Use the Participant QoS as base for the Databroker QoS - eprosima::fastdds::dds::DomainParticipantQos pqos = get_participant_qos(config); + eprosima::fastdds::dds::DomainParticipantQos pqos = get_default_participant_qos(); // Server id uint32_t server_id = 0; diff --git a/src/Participant.hpp b/src/Participant.hpp index 09b9870..53d922c 100644 --- a/src/Participant.hpp +++ b/src/Participant.hpp @@ -209,19 +209,6 @@ class Participant protected: - /** - * @brief Get Participant QoS using config file. - * - * Set all default values to QoS and then use specific FastSH tags to configure the participant: - * Tags: file_path, profile_name - * - * @param[in] config The configuration provided by the user. - * - * @return Specific QoS by user configuration. - */ - eprosima::fastdds::dds::DomainParticipantQos get_participant_qos( - const YAML::Node& config); - /** * @brief Get Fast DDS System Handle Participant default QoS * diff --git a/src/Server.cpp b/src/Server.cpp index 823941b..9e9fb99 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -27,9 +27,9 @@ #include #include #include -#if FASTRTPS_VERSION_MINOR >= 2 +#if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 #include -#endif // if FASTRTPS_VERSION_MINOR >= 2 +#endif // if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 #include #include @@ -546,11 +546,11 @@ void Server::on_data_available( if (!stop_cleaner_ && fastrtps::types::ReturnCode_t::RETCODE_OK == reply_entities_.dds_datareader->take_next_sample(reply_entities_.dynamic_data, &info)) { -#if FASTRTPS_VERSION_MINOR < 2 +#if FASTRTPS_VERSION_MAJOR < 2 || FASTRTPS_VERSION_MINOR < 2 if (::fastdds::dds::InstanceStateKind::ALIVE == info.instance_state) #else if (::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == info.instance_state) -#endif // if FASTRTPS_VERSION_MINOR < 2 +#endif // if FASTRTPS_VERSION_MAJOR < 2 || FASTRTPS_VERSION_MINOR < 2 { logger_ << utils::Logger::Level::DEBUG << "Process incoming data available for service reply topic '" diff --git a/src/Subscriber.cpp b/src/Subscriber.cpp index 82aebae..f628734 100644 --- a/src/Subscriber.cpp +++ b/src/Subscriber.cpp @@ -23,9 +23,9 @@ #include #include #include -#if FASTRTPS_VERSION_MINOR >= 2 +#if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 #include -#endif // if FASTRTPS_VERSION_MINOR >= 2 +#endif // if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 #include #include @@ -214,11 +214,11 @@ void Subscriber::on_data_available( if (!stop_cleaner_ && fastrtps::types::ReturnCode_t::RETCODE_OK == dds_datareader_->take_next_sample(dynamic_data_, &info)) { -#if FASTRTPS_VERSION_MINOR < 2 +#if FASTRTPS_VERSION_MAJOR < 2 || FASTRTPS_VERSION_MINOR < 2 if (::fastdds::dds::InstanceStateKind::ALIVE == info.instance_state) #else if (::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == info.instance_state) -#endif // if FASTRTPS_VERSION_MINOR < 2 +#endif // if FASTRTPS_VERSION_MAJOR < 2 || FASTRTPS_VERSION_MINOR < 2 { logger_ << utils::Logger::Level::DEBUG << "Processing incoming data available for topic '" From 2ac1a15c315c826c9cd7e4bfae104dc54c82bb81 Mon Sep 17 00:00:00 2001 From: jparisu Date: Mon, 19 Jul 2021 15:23:32 +0200 Subject: [PATCH 08/10] Refs #12151: Eliminate databroker tag and add discovery-server tag Signed-off-by: jparisu --- src/Participant.cpp | 23 +++++++++++++---------- src/SystemHandle.cpp | 10 ++++++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Participant.cpp b/src/Participant.cpp index e537a16..cae7949 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -70,23 +70,25 @@ void Participant::build_participant( eprosima::fastdds::dds::DomainId_t domain_id(0); // Check if domain_id tag is present inconfiguration, if not 0 as default - if (config["participant"] && config["participant"]["domain_id"]) + if (config["domain_id"]) { - domain_id = config["participant"]["domain_id"].as(); + domain_id = config["domain_id"].as(); } logger_ << utils::Logger::Level::DEBUG << "Creating Fast DDS Participant in domain " << domain_id << std::endl; + // Load default XML files + fastrtps::xmlparser::XMLProfileManager::loadDefaultXMLFile(); + // Loading XML if file_path is given - if (config["participant"] && config["participant"]["file_path"]) + if (config["file_path"]) { - const std::string file_path = config["file_path"].as(); if (fastrtps::xmlparser::XMLP_ret::XML_OK != - fastrtps::xmlparser::XMLProfileManager::loadXMLFile(file_path)) + fastrtps::xmlparser::XMLProfileManager::loadXMLFile(config["file_path"].as())) { std::ostringstream err; - err << "Failed to load XML file provided in 'file_path': " << file_path + err << "Failed to load XML file provided in 'file_path': " << config["file_path"].as() << ". It cannot be found or is incorrect."; throw DDSMiddlewareException( logger_, err.str()); @@ -97,16 +99,16 @@ void Participant::build_participant( std::string participant_name; // If profile_name is given in configuration, the other tags do not apply - if (!config["participant"] || !config["participant"]["profile_name"]) + if (!config["profile_name"]) { // Participant QoS ::fastdds::dds::DomainParticipantQos participant_qos; // Depending the SH type, use participant qos or databroker qos // TODO : change for databroker alias refactor - if (config["type"] && config["type"].as() == "databroker") + if (config["discovery-server"]) { - participant_qos = get_databroker_qos(config["participant"]); + participant_qos = get_databroker_qos(config["discovery-server"]); } else { @@ -122,11 +124,12 @@ void Participant::build_participant( } else { - participant_name = config["participant"]["profile_name"].as(); + participant_name = config["profile_name"].as(); // Create Participant from profile name dds_participant_ = ::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant_with_profile( + domain_id, config["profile_name"].as()); } diff --git a/src/SystemHandle.cpp b/src/SystemHandle.cpp index 052468d..cb0206f 100644 --- a/src/SystemHandle.cpp +++ b/src/SystemHandle.cpp @@ -69,8 +69,14 @@ class SystemHandle : public virtual FullSystem */ try { - // TODO Add a warning that was here in Participant build_participant creation - participant_ = std::make_unique(configuration); + if (configuration["participant"]) + { + participant_ = std::make_unique(configuration["participant"]); + } + else + { + participant_ = std::make_unique(); + } } catch (DDSMiddlewareException& e) { From b992b635d21d80a67f8d4cb582b138b2d684a421 Mon Sep 17 00:00:00 2001 From: jparisu Date: Mon, 19 Jul 2021 16:55:12 +0200 Subject: [PATCH 09/10] Refs #12151: apply suggestions Signed-off-by: jparisu --- CMakeLists.txt | 7 ------- src/Participant.cpp | 2 +- src/SystemHandle.cpp | 6 +++++- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a976582..f5fb7df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,11 +33,6 @@ option(IS_FASTDDS_SH_USING_FASTDDS_EXTERNALPROJECT option(BUILD_LIBRARY "Compile the Fast DDS SystemHandle" ON) -################################################################################### -# Set Aliases for FastDDS SH -################################################################################### -set (ALIASES "databroker") - ################################################################################### # Load external CMake Modules. ################################################################################### @@ -229,8 +224,6 @@ if(BUILD_LIBRARY) fastdds TARGET is-fastdds - ALIAS - ${ALIASES} ) endif() diff --git a/src/Participant.cpp b/src/Participant.cpp index cae7949..8e626b9 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -69,7 +69,7 @@ void Participant::build_participant( // Set 0 as default domain eprosima::fastdds::dds::DomainId_t domain_id(0); - // Check if domain_id tag is present inconfiguration, if not 0 as default + // Check if domain_id tag is present in configuration, if not 0 as default if (config["domain_id"]) { domain_id = config["domain_id"].as(); diff --git a/src/SystemHandle.cpp b/src/SystemHandle.cpp index cb0206f..620e363 100644 --- a/src/SystemHandle.cpp +++ b/src/SystemHandle.cpp @@ -75,6 +75,11 @@ class SystemHandle : public virtual FullSystem } else { + logger_ << utils::Logger::Level::WARN + << "Participant not provided in configuration file. " + << "A participant using the default transport locators " + << "and Domain ID 0 will be created." << std::endl; + participant_ = std::make_unique(); } } @@ -299,4 +304,3 @@ class SystemHandle : public virtual FullSystem // TODO aliases must come from CMAKE IS_REGISTER_SYSTEM("fastdds", eprosima::is::sh::fastdds::SystemHandle) -IS_REGISTER_SYSTEM("databroker", eprosima::is::sh::fastdds::SystemHandle) From 743508624f1aad149edb661ed8e06945c413ad1f Mon Sep 17 00:00:00 2001 From: jparisu Date: Thu, 29 Jul 2021 10:01:37 +0200 Subject: [PATCH 10/10] Refs #12151: add guid option for databroker configuration Signed-off-by: jparisu --- src/Participant.cpp | 66 ++++++++++++--------------- src/Participant.hpp | 7 ++- src/utils/databroker/utils.cpp | 81 ++++++++++++++++++++++++++++++++++ src/utils/databroker/utils.hpp | 34 ++++++++++++++ test/unitary/qos.cpp | 57 ++++++++++++++++++++++++ 5 files changed, 207 insertions(+), 38 deletions(-) create mode 100644 src/utils/databroker/utils.cpp create mode 100644 test/unitary/qos.cpp diff --git a/src/Participant.cpp b/src/Participant.cpp index 8e626b9..50729f3 100644 --- a/src/Participant.cpp +++ b/src/Participant.cpp @@ -57,7 +57,7 @@ Participant::~Participant() if (fastrtps::types::ReturnCode_t::RETCODE_OK != ::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(dds_participant_)) { - logger_ << utils::Logger::Level::ERROR + logger_ << eprosima::is::utils::Logger::Level::ERROR << "Cannot delete Fast DDS participant yet: it has active entities" << std::endl; } } @@ -75,7 +75,7 @@ void Participant::build_participant( domain_id = config["domain_id"].as(); } - logger_ << utils::Logger::Level::DEBUG + logger_ << eprosima::is::utils::Logger::Level::DEBUG << "Creating Fast DDS Participant in domain " << domain_id << std::endl; // Load default XML files @@ -135,7 +135,7 @@ void Participant::build_participant( if (dds_participant_) { - logger_ << utils::Logger::Level::INFO + logger_ << eprosima::is::utils::Logger::Level::INFO << "Created Fast DDS participant '" << participant_name << "' with Domain ID: " << domain_id << std::endl; } @@ -171,7 +171,7 @@ void Participant::register_dynamic_type( // Type known, add the entry in the map topic->type topic_to_type_.emplace(topic_name, type_name); - logger_ << utils::Logger::Level::DEBUG + logger_ << eprosima::is::utils::Logger::Level::DEBUG << "Adding type '" << type_name << "' to topic '" << topic_name << "'" << std::endl; @@ -220,7 +220,7 @@ void Participant::register_dynamic_type( if (pair.second) { - logger_ << utils::Logger::Level::DEBUG + logger_ << eprosima::is::utils::Logger::Level::DEBUG << "Registered type '" << type_name << "' in topic '" << topic_name << "'" << std::endl; @@ -228,7 +228,7 @@ void Participant::register_dynamic_type( } else { - logger_ << utils::Logger::Level::WARN + logger_ << eprosima::is::utils::Logger::Level::WARN << "Failed registering type '" << type_name << "' in topic '" << topic_name << "'" << std::endl; } @@ -352,23 +352,17 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( eprosima::fastdds::dds::DomainParticipantQos pqos = get_default_participant_qos(); // Server id - uint32_t server_id = 0; - if (config["server_id"]) + // Show warning if both set + if (config["server_id"] && config["server_guid"]) { - // Conversion to int is needed so it is not treated as a char - server_id = config["server_id"].as() % std::numeric_limits::max(); - logger_ << utils::Logger::Level::DEBUG - << "Server ID set to " << server_id << std::endl; - } - else - { - logger_ << utils::Logger::Level::INFO - << "The Server ID is not set in the configuration file. It will be set to 0." << std::endl; + logger_ << eprosima::is::utils::Logger::Level::WARN + << "Server ID and Server GUID are both set. Only GUID will be used." << std::endl; } // Set GUID depending on the id - pqos.wire_protocol().prefix = guid_server(server_id); - pqos.name("DataBroker_IS-FastDDS-SH_participant_" + std::to_string(server_id)); + pqos.wire_protocol().prefix = eprosima::is::sh::fastdds::utils::guid_server(config["server_id"], config["server_guid"]); + pqos.name("DataBroker_IS-FastDDS-SH_participant_" + + eprosima::is::sh::fastdds::utils::guid_to_string(pqos.wire_protocol().prefix)); // Listening addresses if (config["listening_addresses"]) @@ -386,7 +380,7 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - logger_ << utils::Logger::Level::WARN + logger_ << eprosima::is::utils::Logger::Level::WARN << "The addresses in 'listening_addresses' must contain a tag 'ip'." << std::endl; continue; } @@ -397,7 +391,7 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - logger_ << utils::Logger::Level::WARN + logger_ << eprosima::is::utils::Logger::Level::WARN << "The addresses in 'listening_addresses' must contain a tag 'port'. " << std::endl; continue; } @@ -425,13 +419,13 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( pqos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(tcp_locator); - logger_ << utils::Logger::Level::DEBUG + logger_ << eprosima::is::utils::Logger::Level::DEBUG << "Server listening in: " << ip << ":" << port << std::endl; } } else { - logger_ << utils::Logger::Level::WARN + logger_ << eprosima::is::utils::Logger::Level::WARN << "Server has no listening address." << "It will not discover or connect to other servers." << std::endl; @@ -445,7 +439,6 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( { std::string ip; uint16_t port; - uint16_t server_id; // Get address values. If not present, send error if (address["ip"]) @@ -454,7 +447,7 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - logger_ << utils::Logger::Level::WARN + logger_ << eprosima::is::utils::Logger::Level::WARN << "The addresses in 'connection_addresses' must contain a tag 'ip'." << std::endl; continue; } @@ -465,25 +458,24 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( } else { - logger_ << utils::Logger::Level::WARN + logger_ << eprosima::is::utils::Logger::Level::WARN << "The addresses in 'connection_addresses' must contain a tag 'port'." << std::endl; continue; } - if (address["server_id"]) - { - server_id = address["server_id"].as(); - } - else + if (! (address["server_id"] || address["server_guid"])) { - logger_ << utils::Logger::Level::WARN - << "The addresses in 'connection_addresses' must contain a tag 'server_id'." << std::endl; + logger_ << eprosima::is::utils::Logger::Level::WARN + << "The addresses in 'connection_addresses' must contain a tag 'server_id' or 'server_guid'." + << std::endl; continue; } // Set Server GUID eprosima::fastrtps::rtps::RemoteServerAttributes server_attr; - server_attr.guidPrefix = guid_server(server_id); + server_attr.guidPrefix = eprosima::is::sh::fastdds::utils::guid_server( + address["server_id"], + address["server_guid"]); // Discovery server locator configuration TCP eprosima::fastrtps::rtps::Locator_t tcp_locator; @@ -495,14 +487,14 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( pqos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server_attr); - logger_ << utils::Logger::Level::DEBUG + logger_ << eprosima::is::utils::Logger::Level::DEBUG << "Connecting to remote server with GUID: " << server_attr.guidPrefix << " in: " << ip << ":" << port << std::endl; } } else { - logger_ << utils::Logger::Level::INFO + logger_ << eprosima::is::utils::Logger::Level::INFO << "Server has no connection addresses. It will not try to connect to remote servers" << std::endl; } @@ -516,7 +508,7 @@ eprosima::fastdds::dds::DomainParticipantQos Participant::get_databroker_qos( pqos.wire_protocol().builtin.discovery_config.discoveryProtocol = fastrtps::rtps::DiscoveryProtocol::SERVER; - logger_ << utils::Logger::Level::DEBUG + logger_ << eprosima::is::utils::Logger::Level::DEBUG << "Databroker initialized with GUID: " << pqos.wire_protocol().prefix << std::endl; return pqos; diff --git a/src/Participant.hpp b/src/Participant.hpp index 53d922c..f8d834c 100644 --- a/src/Participant.hpp +++ b/src/Participant.hpp @@ -83,6 +83,10 @@ class Participant * In case of databroker type it can contain three keys in the *YAML* map: * * - `server_id`: Specifies the Discovery Server ID in order to generate its GUID. + * It is incompatible with setting the GUID. + * + * - `server_guid`: Specifies the Discovery Server GUID. + * It is incompatible with setting the ID. * * - `listening_addresses`: Specifies a list of TCP listening addresses. * - `ip`: Provides the public IP where the Server will be listening. @@ -91,7 +95,8 @@ class Participant * - `connection_addresses`: Specifies a list of TCP connection addresses. * - `ip`: Provides the public IP of the Server to connect to. * - `port`: Provides the port of the Server to connect to. - * - `server_id`: Provides the ID of the remote Server to connect to. + * - `server_id`: Provides the ID of the remote Server to connect to [incompatible with GUID]. + * - `server_guid`: Provides the GUID of the remote Server to connect to [incompatible with ID]. * * @throws DDSMiddlewareException If the XML profile was incorrect and, thus, the * *DomainParticipant* could not be created. diff --git a/src/utils/databroker/utils.cpp b/src/utils/databroker/utils.cpp new file mode 100644 index 0000000..b6372e4 --- /dev/null +++ b/src/utils/databroker/utils.cpp @@ -0,0 +1,81 @@ +/* + * Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "Participant.hpp" +#include "DDSMiddlewareException.hpp" +#include "Conversion.hpp" +#include "utils/databroker/utils.hpp" + +#include +#include + +#include +#include + +#include + +namespace eprosima { +namespace is { +namespace sh { +namespace fastdds { +namespace utils { + +eprosima::fastrtps::rtps::GuidPrefix_t guid_server( + uint8_t id) +{ + eprosima::fastrtps::rtps::GuidPrefix_t guid; + std::istringstream(SERVER_DEFAULT_GUID) >> guid; + guid.value[SERVER_DEFAULT_GUID_ID_INDEX] = static_cast(id); + return guid; +} + +eprosima::fastrtps::rtps::GuidPrefix_t guid_server( + const YAML::Node& server_id, + const YAML::Node& server_guid) +{ + if (server_guid) + { + // Server GUID set and used + eprosima::fastrtps::rtps::GuidPrefix_t guid; + std::istringstream(server_guid.as()) >> guid; + return guid; // There is no easy wat to directly return the guid + } + else if (server_id && !server_guid) + { + // Server ID set without GUID set + return guid_server(server_id.as() % std::numeric_limits::max()); + } + else + { + // Server GUID by default with ID 0 + return guid_server(0); + } +} + +std::string guid_to_string( + const eprosima::fastrtps::rtps::GuidPrefix_t& guid) +{ + std::ostringstream guid_ostream; + guid_ostream << guid; + return guid_ostream.str(); +} + +} // namespace utils +} // namespace fastdds +} // namespace sh +} // namespace is +} // namespace eprosima diff --git a/src/utils/databroker/utils.hpp b/src/utils/databroker/utils.hpp index 35a566f..55a9746 100644 --- a/src/utils/databroker/utils.hpp +++ b/src/utils/databroker/utils.hpp @@ -30,6 +30,8 @@ namespace is { namespace sh { namespace fastdds { +namespace utils { + #define SERVER_DEFAULT_GUID "01.0f.00.44.41.54.95.42.52.4f.4b.45.52" #define SERVER_DEFAULT_GUID_ID_INDEX 2 @@ -42,6 +44,38 @@ inline eprosima::fastrtps::rtps::GuidPrefix_t guid_server( return guid; } +inline eprosima::fastrtps::rtps::GuidPrefix_t guid_server( + const YAML::Node& server_id, + const YAML::Node& server_guid) +{ + if (server_guid) + { + // Server GUID set and used + eprosima::fastrtps::rtps::GuidPrefix_t guid; + std::istringstream(server_guid.as()) >> guid; + return guid; // There is no easy wat to directly return the guid + } + else if (server_id) + { + // Server ID set without GUID set + return guid_server(server_id.as() % std::numeric_limits::max()); + } + else + { + // Server GUID by default with ID 0 + return guid_server(0); + } +} + +inline std::string guid_to_string( + const eprosima::fastrtps::rtps::GuidPrefix_t& guid) +{ + std::ostringstream guid_ostream; + guid_ostream << guid; + return guid_ostream.str(); +} + +} // namespace utils } // namespace fastdds } // namespace sh } // namespace is diff --git a/test/unitary/qos.cpp b/test/unitary/qos.cpp new file mode 100644 index 0000000..5947e52 --- /dev/null +++ b/test/unitary/qos.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2021 - present Proyectos y Sistemas de Mantenimiento SL (eProsima). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +namespace fastdds = eprosima::fastdds; + +namespace eprosima { +namespace is { +namespace sh { +namespace fastdds { +namespace test { + +TEST(FastDDS_set_qos, get_databroker_qos) +{ + +} + +TEST(FastDDS_set_qos, get_databroker_qos) +{ + +} + +TEST(FastDDS_set_qos, get_databroker_qos) +{ + +} + +} // namespace test +} // namespace fastdds +} // namespace sh +} // namespace is +} // namespace eprosima + +int main( + int argc, + char** argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}