diff --git a/include/DiscoveryItem.h b/include/DiscoveryItem.h index 03d41e7..498a990 100644 --- a/include/DiscoveryItem.h +++ b/include/DiscoveryItem.h @@ -36,6 +36,29 @@ namespace discovery_server { typedef fastdds::rtps::GUID_t GUID_t; +struct TopicDescriptionItem +{ + TopicDescriptionItem() + { + name = "UNDEF"; + type_name = "UNDEF"; + } + + TopicDescriptionItem( + const std::string& name, + const std::string& type_name) + : name(name) + , type_name(type_name) + { + + } + + ~TopicDescriptionItem() = default; + + std::string name; + std::string type_name; +}; + //! common discovery info struct DiscoveryItem { diff --git a/include/DiscoveryServerManager.h b/include/DiscoveryServerManager.h index 6069ae2..1ade3df 100644 --- a/include/DiscoveryServerManager.h +++ b/include/DiscoveryServerManager.h @@ -128,6 +128,9 @@ class DiscoveryServerManager // Snapshops container snapshots_list snapshots; + // Topic description profiles + std::map topic_description_profiles_map; + volatile bool no_callbacks; // ongoing participant destruction bool auto_shutdown; // close when event processing is finished? bool enable_prefix_validation; // allow multiple servers share the same prefix? (only for testing purposes) @@ -315,7 +318,11 @@ class DiscoveryServerManager } // default topic - static TopicAttributes builtin_defaultTopic; + static TopicDescriptionItem default_topic_description; + + static bool fill_topic_description_profile( + tinyxml2::XMLElement* elem, + TopicDescriptionItem& topic_description); // parsing regex static const std::regex ipv4_regular_expression; diff --git a/include/LateJoiner.h b/include/LateJoiner.h index c0f3602..fcad843 100644 --- a/include/LateJoiner.h +++ b/include/LateJoiner.h @@ -376,11 +376,11 @@ void DelayedEndpointCreation::operator ()( if (type_name == "UNDEF") { topic = manager.getParticipantTopicByName(part, - DiscoveryServerManager::builtin_defaultTopic.getTopicName().to_string()); + DiscoveryServerManager::default_topic_description.name); if ( nullptr == topic) { - topic = part->create_topic(DiscoveryServerManager::builtin_defaultTopic.getTopicName().to_string(), - DiscoveryServerManager::builtin_defaultTopic.topicDataType.to_string(), + topic = part->create_topic(DiscoveryServerManager::default_topic_description.name, + DiscoveryServerManager::default_topic_description.type_name, part->get_default_topic_qos()); manager.setParticipantTopic(part, topic); } diff --git a/src/DiscoveryServerManager.cpp b/src/DiscoveryServerManager.cpp index 7e0168b..c244be4 100644 --- a/src/DiscoveryServerManager.cpp +++ b/src/DiscoveryServerManager.cpp @@ -38,6 +38,7 @@ using namespace eprosima::discovery_server; namespace eprosima { namespace fastdds { namespace DSxmlparser { +const char* DATA_TYPE = "dataType"; const char* PROFILES = "profiles"; const char* PROFILE_NAME = "profile_name"; const char* PREFIX = "prefix"; @@ -53,7 +54,7 @@ const char* TOPIC = "topic"; } // namespace eprosima /*static members*/ -TopicAttributes DiscoveryServerManager::builtin_defaultTopic("HelloWorldTopic", "HelloWorld"); +TopicDescriptionItem DiscoveryServerManager::default_topic_description("HelloWorldTopic", "HelloWorld"); const std::regex DiscoveryServerManager::ipv4_regular_expression("^((?:[0-9]{1,3}\\.){3}[0-9]{1,3})?:?(?:(\\d+))?$"); const std::chrono::seconds DiscoveryServerManager::last_snapshot_delay_ = std::chrono::seconds(1); @@ -122,6 +123,27 @@ DiscoveryServerManager::DiscoveryServerManager( { LOG_ERROR("Error parsing profiles!"); } + + // Store Topic Profiles + tinyxml2::XMLElement* topic_profile = profiles->FirstChildElement(s_sTopic.c_str()); + while (nullptr != topic_profile) + { + const char* topic_profile_name = topic_profile->Attribute(DSxmlparser::PROFILE_NAME); + if (topic_profile_name != nullptr) + { + auto topic_desc_it = topic_description_profiles_map.find(topic_profile_name); + if (topic_desc_it == topic_description_profiles_map.end()) + { + auto &topic_desc = topic_description_profiles_map[topic_profile_name]; + if (!fill_topic_description_profile(topic_profile, topic_desc)) + { + LOG_ERROR("Error parsing topic profiles"); + break; + } + } + } + topic_profile = topic_profile->NextSiblingElement(s_sTopic.c_str()); + } } // Server processing requires a two pass analysis @@ -681,6 +703,66 @@ Topic* DiscoveryServerManager::getParticipantTopicByName( return returnTopic; } +bool DiscoveryServerManager::fill_topic_description_profile( + tinyxml2::XMLElement* elem, + TopicDescriptionItem& topic_description) +{ + /* + + + + + + + */ + + bool ret = true; + tinyxml2::XMLElement* p_aux0 = elem->FirstChildElement(); + const char* name = nullptr; + for (; p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) + { + name = p_aux0->Name(); + + if (strcmp(name, DSxmlparser::NAME) == 0) + { + // name - stringType + const char* text = p_aux0->GetText(); + if (nullptr != text) + { + topic_description.name = text; + } + else + { + LOG_ERROR("<" << p_aux0->Value() << "> GetText XML_ERROR"); + ret = false; + break; + } + } + else if (strcmp(name, DSxmlparser::DATA_TYPE) == 0) + { + // dataType - stringType + const char* text = p_aux0->GetText(); + if (nullptr != text) + { + topic_description.type_name = text; + } + else + { + LOG_ERROR("<" << p_aux0->Value() << "> GetText XML_ERROR"); + ret = false; + break; + } + } + else + { + LOG_ERROR("Invalid element found into 'topicDescriptionType'. Name: " << name); + ret = false; + } + } + + return ret; +} + void DiscoveryServerManager::onTerminate() { { @@ -1302,14 +1384,19 @@ void DiscoveryServerManager::loadSubscriber( // see if topic is specified const char* topic_name = sub->Attribute(DSxmlparser::TOPIC); - TopicAttributes topicAttr; + TopicDescriptionItem topic_description; if (topic_name != nullptr) { - if (!eprosima::fastdds::rtps::RTPSDomain::get_topic_attributes_from_profile(std::string( - topic_name), topicAttr)) + if (topic_name != nullptr) { - LOG_ERROR("DiscoveryServerManager::loadSubscriber couldn't load topic profile "); - return; + try + { + topic_description = topic_description_profiles_map.at(topic_name); + } + catch (...) + { + LOG_ERROR("Topic " << topic_name << " not found in the topic description profiles"); + } } } @@ -1332,8 +1419,8 @@ void DiscoveryServerManager::loadSubscriber( endpoint_profile = std::string(profile_name); } - DelayedEndpointCreation event(creation_time, topicAttr.getTopicName().to_string(), - topicAttr.getTopicDataType().to_string(), topic_name, endpoint_profile, part_guid, pDE, + DelayedEndpointCreation event(creation_time, topic_description.name, + topic_description.type_name, topic_name, endpoint_profile, part_guid, pDE, participant_creation_event); if (creation_time == getTime()) @@ -1349,11 +1436,11 @@ void DiscoveryServerManager::loadSubscriber( void DiscoveryServerManager::loadPublisher( GUID_t& part_guid, - tinyxml2::XMLElement* sub, + tinyxml2::XMLElement* pub, DelayedParticipantCreation* participant_creation_event /*= nullptr*/, DelayedParticipantDestruction* participant_destruction_event /*= nullptr*/) { - assert(sub != nullptr); + assert(pub != nullptr); // check if we need to create an event std::chrono::steady_clock::time_point creation_time, removal_time; @@ -1382,7 +1469,7 @@ void DiscoveryServerManager::loadPublisher( } { - const char* creation_time_str = sub->Attribute(s_sCreationTime.c_str()); + const char* creation_time_str = pub->Attribute(s_sCreationTime.c_str()); if (creation_time_str != nullptr) { int aux; @@ -1390,7 +1477,7 @@ void DiscoveryServerManager::loadPublisher( creation_time = getTime() + std::chrono::seconds(aux); } - const char* removal_time_str = sub->Attribute(s_sRemovalTime.c_str()); + const char* removal_time_str = pub->Attribute(s_sRemovalTime.c_str()); if (removal_time_str != nullptr) { int aux; @@ -1401,22 +1488,24 @@ void DiscoveryServerManager::loadPublisher( // data_readers are created for debugging purposes // default topic is the static HelloWorld one - const char* profile_name = sub->Attribute(DSxmlparser::PROFILE_NAME); + const char* profile_name = pub->Attribute(DSxmlparser::PROFILE_NAME); // see if topic is specified - const char* topic_name = sub->Attribute(DSxmlparser::TOPIC); - TopicAttributes topicAttr; + const char* topic_name = pub->Attribute(DSxmlparser::TOPIC); + TopicDescriptionItem topic_description; if (topic_name != nullptr) { - if (!eprosima::fastdds::rtps::RTPSDomain::get_topic_attributes_from_profile(std::string( - topic_name), topicAttr)) + try { - LOG_ERROR("DiscoveryServerManager::loadPublisher couldn't load topic profile "); - return; + topic_description = topic_description_profiles_map.at(topic_name); + } + catch (...) + { + LOG_ERROR("Topic " << topic_name << " not found in the topic description profiles"); } } - DelayedEndpointDestruction* pDE = nullptr; // subscriber destruction event + DelayedEndpointDestruction* pDE = nullptr; // publisher destruction event if (removal_time != getTime()) { @@ -1436,8 +1525,8 @@ void DiscoveryServerManager::loadPublisher( endpoint_profile = std::string(profile_name); } - DelayedEndpointCreation event(creation_time, topicAttr.getTopicName().to_string(), - topicAttr.getTopicDataType().to_string(), topic_name, endpoint_profile, part_guid, pDE, + DelayedEndpointCreation event(creation_time, topic_description.name, + topic_description.type_name, topic_name, endpoint_profile, part_guid, pDE, participant_creation_event); if (creation_time == getTime())