From ee86d89c4ed5e443188de73b1c794b5be8094a52 Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:23:09 +0200 Subject: [PATCH 1/7] descgate API changed to use separate GetEntityIDs() + GetEntityInfo(id) functions instead of single GetEntities() variants --- ecal/core/include/ecal/ecal_registration.h | 16 ++ ecal/core/include/ecal/ecal_types.h | 45 +++++ ecal/core/src/ecal_descgate.cpp | 168 ++++++++++++------ ecal/core/src/ecal_descgate.h | 69 +++---- .../src/registration/ecal_registration.cpp | 115 ++++++++++-- .../ecal_struct_sample_registration.h | 19 -- ecal/tests/CMakeLists.txt | 2 +- ecal/tests/cpp/descgate_test/CMakeLists.txt | 2 +- ...publisher.cpp => descgate_getentities.cpp} | 114 +++++------- .../CMakeLists.txt | 4 +- .../src/registration_getclients.cpp | 51 +++++- .../src/registration_getservices.cpp | 58 +++++- .../src/registration_gettopics.cpp | 74 +++++++- 13 files changed, 518 insertions(+), 219 deletions(-) rename ecal/tests/cpp/descgate_test/src/{getpublisher.cpp => descgate_getentities.cpp} (76%) rename ecal/tests/cpp/{registration_test_2 => registration_test_public}/CMakeLists.txt (93%) rename ecal/tests/cpp/{registration_test_2 => registration_test_public}/src/registration_getclients.cpp (85%) rename ecal/tests/cpp/{registration_test_2 => registration_test_public}/src/registration_getservices.cpp (81%) rename ecal/tests/cpp/{registration_test_2 => registration_test_public}/src/registration_gettopics.cpp (73%) diff --git a/ecal/core/include/ecal/ecal_registration.h b/ecal/core/include/ecal/ecal_registration.h index 5de5289aab..f72ef1578d 100644 --- a/ecal/core/include/ecal/ecal_registration.h +++ b/ecal/core/include/ecal/ecal_registration.h @@ -96,6 +96,22 @@ namespace eCAL using QualityServiceInfoMultimap = std::multimap; using SQualityServiceInfoSet = std::set; + // get publisher information + ECAL_API std::set GetPublisherIDs(); + ECAL_API bool GetPublisherInfo(const STopicId& id_, SQualityTopicInfo& topic_info_); + + // get subscriber information + ECAL_API std::set GetSubscriberIDs(); + ECAL_API bool GetSubscriberInfo(const STopicId& id_, SQualityTopicInfo& topic_info_); + + // get service information + ECAL_API std::set GetServiceIDs(); + ECAL_API bool GetServiceInfo(const SServiceId& id_, SQualityServiceInfo& service_info_); + + // get client information + ECAL_API std::set GetClientIDs(); + ECAL_API bool GetClientInfo(const SServiceId& id_, SQualityServiceInfo& service_info_); + /** * @brief Get complete snapshot of data type information with quality and topic id for all known publisher. * diff --git a/ecal/core/include/ecal/ecal_types.h b/ecal/core/include/ecal/ecal_types.h index 5e32297c9e..9759f69a18 100644 --- a/ecal/core/include/ecal/ecal_types.h +++ b/ecal/core/include/ecal/ecal_types.h @@ -82,4 +82,49 @@ namespace eCAL } //!< @endcond }; + + namespace Registration + { + struct SampleIdentifier + { + std::string entity_id; // unique id within that process + int32_t process_id = 0; // process id which produced the sample + std::string host_name; // host which produced the sample + + bool operator==(const SampleIdentifier& other) const { + return entity_id == other.entity_id && + process_id == other.process_id && + host_name == other.host_name; + } + + bool operator<(const SampleIdentifier& other) const + { + return std::tie(process_id, entity_id, host_name) + < std::tie(other.process_id, other.entity_id, other.host_name); + } + }; + + struct STopicId + { + Registration::SampleIdentifier topic_id; + std::string topic_name; + + bool operator<(const STopicId& other) const + { + return std::tie(topic_id, topic_name) < std::tie(other.topic_id, other.topic_name); + } + }; + + struct SServiceId + { + Registration::SampleIdentifier service_id; + std::string service_name; + std::string method_name; + + bool operator<(const SServiceId& other) const + { + return std::tie(service_id, service_name, method_name) < std::tie(other.service_id, other.service_name, other.method_name); + } + }; + } } diff --git a/ecal/core/src/ecal_descgate.cpp b/ecal/core/src/ecal_descgate.cpp index f64de14fad..93c0aee247 100644 --- a/ecal/core/src/ecal_descgate.cpp +++ b/ecal/core/src/ecal_descgate.cpp @@ -46,54 +46,98 @@ namespace eCAL CDescGate::CDescGate() = default; CDescGate::~CDescGate() = default; - Registration::QualityTopicInfoMultiMap CDescGate::GetPublishers() + std::set CDescGate::GetPublisherIDs() const { - return GetTopics(m_publisher_info_map); + return GetTopicIDs(m_publisher_info_map); } - Registration::QualityTopicInfoMultiMap CDescGate::GetSubscribers() + bool CDescGate::GetPublisherInfo(const Registration::STopicId& id_, Registration::SQualityTopicInfo& topic_info_) const { - return GetTopics(m_subscriber_info_map); + return GetTopic(id_, m_publisher_info_map, topic_info_); } - Registration::QualityServiceInfoMultimap CDescGate::GetServices() + std::set CDescGate::GetSubscriberIDs() const { - return GetServices(m_service_info_map); + return GetTopicIDs(m_subscriber_info_map); } - Registration::QualityServiceInfoMultimap CDescGate::GetClients() + bool CDescGate::GetSubscriberInfo(const Registration::STopicId& id_, Registration::SQualityTopicInfo& topic_info_) const { - return GetServices(m_client_info_map); + return GetTopic(id_, m_subscriber_info_map, topic_info_); } - Registration::QualityTopicInfoMultiMap CDescGate::GetTopics(SQualityTopicIdMap& topic_info_map_) + std::set CDescGate::GetServiceIDs() const { - Registration::QualityTopicInfoMultiMap multi_map; + return GetServiceIDs(m_service_info_map); + } - const std::lock_guard lock(topic_info_map_.mtx); + bool CDescGate::GetServiceInfo(const Registration::SServiceId& id_, Registration::SQualityServiceInfo& service_info_) const + { + return GetService(id_, m_service_info_map, service_info_); + } + std::set CDescGate::GetClientIDs() const + { + return GetServiceIDs(m_client_info_map); + } + + bool CDescGate::GetClientInfo(const Registration::SServiceId& id_, Registration::SQualityServiceInfo& service_info_) const + { + return GetService(id_, m_client_info_map, service_info_); + } + + std::set CDescGate::GetTopicIDs(const SQualityTopicIdMap& topic_info_map_) + { + std::set topic_id_set; + + const std::lock_guard lock(topic_info_map_.mtx); for (const auto& topic_map_it : topic_info_map_.map) { - multi_map.insert(std::pair(topic_map_it.first.topic_name, topic_map_it.second)); + topic_id_set.insert(topic_map_it.first); } + return topic_id_set; + } - return multi_map; + bool CDescGate::GetTopic(const Registration::STopicId& id_, const SQualityTopicIdMap& topic_info_map_, Registration::SQualityTopicInfo& topic_info_) + { + const std::lock_guard lock(topic_info_map_.mtx); + auto iter = topic_info_map_.map.find(id_); + if (iter == topic_info_map_.map.end()) + { + return false; + } + else + { + topic_info_ = iter->second; + return true; + } } - Registration::QualityServiceInfoMultimap CDescGate::GetServices(SQualityServiceIdMap& service_method_info_map_) + std::set CDescGate::GetServiceIDs(const SQualityServiceIdMap& service_method_info_map_) { - Registration::QualityServiceInfoMultimap multi_map; + std::set service_id_set; const std::lock_guard lock(service_method_info_map_.mtx); - for (const auto& service_method_info_map_it : service_method_info_map_.map) { - Registration::SServiceMethod key; - key.service_name = service_method_info_map_it.first.service_name; - key.method_name = service_method_info_map_it.first.method_name; - multi_map.insert(std::pair(key, service_method_info_map_it.second)); + service_id_set.insert(service_method_info_map_it.first); + } + return service_id_set; + } + + bool CDescGate::GetService(const Registration::SServiceId& id_, const SQualityServiceIdMap& service_method_info_map_, Registration::SQualityServiceInfo& service_method_info_) + { + const std::lock_guard lock(service_method_info_map_.mtx); + auto iter = service_method_info_map_.map.find(id_); + if (iter == service_method_info_map_.map.end()) + { + return false; + } + else + { + service_method_info_ = iter->second; + return true; } - return multi_map; } void CDescGate::ApplySample(const Registration::Sample& sample_, eTLayerType /*layer_*/) @@ -117,12 +161,12 @@ namespace eCAL response_type.name = method.resp_type; response_type.descriptor = method.resp_desc; - ApplyServiceDescription(m_service_info_map, sample_.service.sname, method.mname, std::stoull(sample_.identifier.entity_id), request_type, response_type, GetDataTypeInfoQuality(request_type, true), GetDataTypeInfoQuality(response_type, true)); + ApplyServiceDescription(m_service_info_map, sample_.identifier, sample_.service.sname, method.mname, request_type, response_type, GetDataTypeInfoQuality(request_type, true), GetDataTypeInfoQuality(response_type, true)); } } break; case bct_unreg_service: - RemServiceDescription(m_service_info_map, sample_.service.sname, std::stoull(sample_.identifier.entity_id)); + RemServiceDescription(m_service_info_map, sample_.identifier, sample_.service.sname); break; case bct_reg_client: for (const auto& method : sample_.client.methods) @@ -135,23 +179,23 @@ namespace eCAL response_type.name = method.resp_type; response_type.descriptor = method.resp_desc; - ApplyServiceDescription(m_client_info_map, sample_.client.sname, method.mname, std::stoull(sample_.identifier.entity_id), request_type, response_type, GetDataTypeInfoQuality(request_type, false), GetDataTypeInfoQuality(response_type, false)); + ApplyServiceDescription(m_client_info_map, sample_.identifier, sample_.client.sname, method.mname, request_type, response_type, GetDataTypeInfoQuality(request_type, false), GetDataTypeInfoQuality(response_type, false)); } break; case bct_unreg_client: - RemServiceDescription(m_client_info_map, sample_.client.sname, std::stoull(sample_.identifier.entity_id)); + RemServiceDescription(m_client_info_map, sample_.identifier, sample_.client.sname); break; case bct_reg_publisher: - ApplyTopicDescription(m_publisher_info_map, sample_.topic.tname, std::stoull(sample_.identifier.entity_id), sample_.topic.tdatatype, GetDataTypeInfoQuality(sample_.topic.tdatatype, true)); + ApplyTopicDescription(m_publisher_info_map, sample_.identifier, sample_.topic.tname, sample_.topic.tdatatype, GetDataTypeInfoQuality(sample_.topic.tdatatype, true)); break; case bct_unreg_publisher: - RemTopicDescription(m_publisher_info_map, sample_.topic.tname, std::stoull(sample_.identifier.entity_id)); + RemTopicDescription(m_publisher_info_map, sample_.identifier, sample_.topic.tname); break; case bct_reg_subscriber: - ApplyTopicDescription(m_subscriber_info_map, sample_.topic.tname, std::stoull(sample_.identifier.entity_id), sample_.topic.tdatatype, GetDataTypeInfoQuality(sample_.topic.tdatatype, false)); + ApplyTopicDescription(m_subscriber_info_map, sample_.identifier, sample_.topic.tname, sample_.topic.tdatatype, GetDataTypeInfoQuality(sample_.topic.tdatatype, false)); break; case bct_unreg_subscriber: - RemTopicDescription(m_subscriber_info_map, sample_.topic.tname, std::stoull(sample_.identifier.entity_id)); + RemTopicDescription(m_subscriber_info_map, sample_.identifier, sample_.topic.tname); break; default: { @@ -162,69 +206,81 @@ namespace eCAL } void CDescGate::ApplyTopicDescription(SQualityTopicIdMap& topic_info_map_, - const std::string& topic_name_, - const Registration::TopicId& topic_id_, - const SDataTypeInformation& topic_info_, - const Registration::DescQualityFlags topic_quality_) + const Registration::SampleIdentifier& topic_id_, + const std::string& topic_name_, + const SDataTypeInformation& topic_info_, + const Registration::DescQualityFlags topic_quality_) { - const auto topic_info_key = STopicIdKey{ topic_name_, topic_id_ }; + const auto topic_info_key = Registration::STopicId{ topic_id_, topic_name_ }; Registration::SQualityTopicInfo topic_quality_info; - topic_quality_info.id = topic_id_; + topic_quality_info.id = std::stoull(topic_id_.entity_id); topic_quality_info.info = topic_info_; topic_quality_info.quality = topic_quality_; const std::unique_lock lock(topic_info_map_.mtx); - topic_info_map_.map[topic_info_key] = topic_quality_info; + auto iter = topic_info_map_.map.find(topic_info_key); + if (iter == topic_info_map_.map.end()) + { + topic_info_map_.map[topic_info_key] = topic_quality_info; + } } - void CDescGate::RemTopicDescription(SQualityTopicIdMap& topic_info_map_, const std::string& topic_name_, const Registration::TopicId& topic_id_) + void CDescGate::RemTopicDescription(SQualityTopicIdMap& topic_info_map_, + const Registration::SampleIdentifier& topic_id_, + const std::string& topic_name_) { const std::unique_lock lock(topic_info_map_.mtx); - topic_info_map_.map.erase(STopicIdKey{ topic_name_, topic_id_ }); + topic_info_map_.map.erase(Registration::STopicId{ topic_id_ , topic_name_}); } void CDescGate::ApplyServiceDescription(SQualityServiceIdMap& service_method_info_map_, - const std::string& service_name_, - const std::string& method_name_, - const Registration::ServiceId& service_id_, - const SDataTypeInformation& request_type_information_, - const SDataTypeInformation& response_type_information_, - const Registration::DescQualityFlags request_type_quality_, - const Registration::DescQualityFlags response_type_quality_) + const Registration::SampleIdentifier& service_id_, + const std::string& service_name_, + const std::string& method_name_, + const SDataTypeInformation& request_type_information_, + const SDataTypeInformation& response_type_information_, + const Registration::DescQualityFlags request_type_quality_, + const Registration::DescQualityFlags response_type_quality_) { - const auto service_method_info_key = SServiceIdKey{ service_name_, method_name_, service_id_}; + const auto service_method_info_key = Registration::SServiceId{ service_id_, service_name_, method_name_}; Registration::SQualityServiceInfo service_quality_info; - service_quality_info.id = service_id_; + service_quality_info.id = std::stoull(service_id_.entity_id); service_quality_info.info.request_type = request_type_information_; service_quality_info.info.response_type = response_type_information_; service_quality_info.request_quality = request_type_quality_; service_quality_info.response_quality = response_type_quality_; const std::lock_guard lock(service_method_info_map_.mtx); - service_method_info_map_.map[service_method_info_key] = service_quality_info; + auto iter = service_method_info_map_.map.find(service_method_info_key); + if (iter == service_method_info_map_.map.end()) + { + service_method_info_map_.map[service_method_info_key] = service_quality_info; + } } - void CDescGate::RemServiceDescription(SQualityServiceIdMap& service_method_info_map_, const std::string& service_name_, const Registration::ServiceId& service_id_) + void CDescGate::RemServiceDescription(SQualityServiceIdMap& service_method_info_map_, + const Registration::SampleIdentifier& service_id_, + const std::string& service_name_) { - std::list service_method_infos_to_remove; + std::list service_method_info_keys_to_remove; const std::lock_guard lock(service_method_info_map_.mtx); for (auto&& service_it : service_method_info_map_.map) { - const auto service_method_info = service_it.first; - if ((service_method_info.service_name == service_name_) - && (service_method_info.service_id == service_id_)) + const auto service_method_info_key = service_it.first; + if ((service_method_info_key.service_name == service_name_) + && (service_method_info_key.service_id == service_id_)) { - service_method_infos_to_remove.push_back(service_method_info); + service_method_info_keys_to_remove.push_back(service_method_info_key); } } - for (const auto& service_method_info : service_method_infos_to_remove) + for (const auto& service_method_info_key : service_method_info_keys_to_remove) { - service_method_info_map_.map.erase(service_method_info); + service_method_info_map_.map.erase(service_method_info_key); } } } diff --git a/ecal/core/src/ecal_descgate.h b/ecal/core/src/ecal_descgate.h index bc844b99bd..6224e4940d 100644 --- a/ecal/core/src/ecal_descgate.h +++ b/ecal/core/src/ecal_descgate.h @@ -37,32 +37,6 @@ namespace eCAL { - struct STopicIdKey - { - std::string topic_name; - Registration::TopicId topic_id; - - bool operator<(const STopicIdKey& other) const - { - return std::tie(topic_name, topic_id) < std::tie(other.topic_name, other.topic_id); - } - }; - - struct SServiceIdKey - { - std::string service_name; - std::string method_name; - Registration::ServiceId service_id; - - bool operator<(const SServiceIdKey& other) const - { - return std::tie(service_name, method_name, service_id) < std::tie(other.service_name, other.method_name, other.service_id); - } - }; - - using QualityTopicIdMap = std::map; - using QualityServiceIdMap = std::map; - class CDescGate { public: @@ -72,13 +46,21 @@ namespace eCAL // apply samples to description gate void ApplySample(const Registration::Sample& sample_, eTLayerType layer_); - // get publisher/subscriber maps - Registration::QualityTopicInfoMultiMap GetPublishers(); - Registration::QualityTopicInfoMultiMap GetSubscribers(); + // get publisher information + std::set GetPublisherIDs() const; + bool GetPublisherInfo(const Registration::STopicId& id_, Registration::SQualityTopicInfo& topic_info_) const; - // get service/clients maps - Registration::QualityServiceInfoMultimap GetServices(); - Registration::QualityServiceInfoMultimap GetClients(); + // get subscriber information + std::set GetSubscriberIDs() const; + bool GetSubscriberInfo(const Registration::STopicId& id_, Registration::SQualityTopicInfo& topic_info_) const; + + // get service information + std::set GetServiceIDs() const; + bool GetServiceInfo(const Registration::SServiceId& id_, Registration::SQualityServiceInfo& service_info_) const; + + // get client information + std::set GetClientIDs() const; + bool GetClientInfo(const Registration::SServiceId& id_, Registration::SQualityServiceInfo& service_info_) const; // delete copy constructor and copy assignment operator CDescGate(const CDescGate&) = delete; @@ -89,45 +71,48 @@ namespace eCAL CDescGate& operator=(CDescGate&&) = delete; protected: - using QualityTopicIdMap = std::map; + using QualityTopicIdMap = std::map; struct SQualityTopicIdMap { mutable std::mutex mtx; QualityTopicIdMap map; }; - using QualityServiceIdMap = std::map; + using QualityServiceIdMap = std::map; struct SQualityServiceIdMap { mutable std::mutex mtx; QualityServiceIdMap map; }; - static Registration::QualityTopicInfoMultiMap GetTopics (SQualityTopicIdMap& topic_info_map_); - static Registration::QualityServiceInfoMultimap GetServices(SQualityServiceIdMap& service_method_info_map_); + static std::set GetTopicIDs(const SQualityTopicIdMap& topic_info_map_); + static bool GetTopic (const Registration::STopicId& id_, const SQualityTopicIdMap& topic_info_map_, Registration::SQualityTopicInfo& topic_info_); + + static std::set GetServiceIDs(const SQualityServiceIdMap& service_method_info_map_); + static bool GetService (const Registration::SServiceId& id_, const SQualityServiceIdMap& service_method_info_map_, Registration::SQualityServiceInfo& service_method_info_); static void ApplyTopicDescription(SQualityTopicIdMap& topic_info_map_, + const Registration::SampleIdentifier& topic_id_, const std::string& topic_name_, - const Registration::TopicId& topic_id_, const SDataTypeInformation& topic_info_, Registration::DescQualityFlags topic_quality_); static void RemTopicDescription(SQualityTopicIdMap& topic_info_map_, - const std::string& topic_name_, - const Registration::TopicId& topic_id_); + const Registration::SampleIdentifier& topic_id_, + const std::string& topic_name_); static void ApplyServiceDescription(SQualityServiceIdMap& service_method_info_map_, + const Registration::SampleIdentifier& service_id_, const std::string& service_name_, const std::string& method_name_, - const Registration::ServiceId& service_id_, const SDataTypeInformation& request_type_information_, const SDataTypeInformation& response_type_information_, Registration::DescQualityFlags request_type_quality_, Registration::DescQualityFlags response_type_quality_); static void RemServiceDescription(SQualityServiceIdMap& service_method_info_map_, - const std::string& service_name_, - const Registration::ServiceId& service_id_); + const Registration::SampleIdentifier& service_id_, + const std::string& service_name_); // internal quality topic info publisher/subscriber maps SQualityTopicIdMap m_publisher_info_map; diff --git a/ecal/core/src/registration/ecal_registration.cpp b/ecal/core/src/registration/ecal_registration.cpp index e42cf12e4a..aac2735cb0 100644 --- a/ecal/core/src/registration/ecal_registration.cpp +++ b/ecal/core/src/registration/ecal_registration.cpp @@ -161,10 +161,68 @@ namespace eCAL { namespace Registration { + std::set GetPublisherIDs() + { + if (g_descgate() == nullptr) return std::set(); + return g_descgate()->GetPublisherIDs(); + } + + bool GetPublisherInfo(const STopicId& id_, SQualityTopicInfo& topic_info_) + { + if (g_descgate() == nullptr) return false; + return g_descgate()->GetPublisherInfo(id_, topic_info_); + } + + std::set GetSubscriberIDs() + { + if (g_descgate() == nullptr) return std::set(); + return g_descgate()->GetSubscriberIDs(); + } + + bool GetSubscriberInfo(const STopicId& id_, SQualityTopicInfo& topic_info_) + { + if (g_descgate() == nullptr) return false; + return g_descgate()->GetSubscriberInfo(id_, topic_info_); + } + + std::set GetServiceIDs() + { + if (g_descgate() == nullptr) return std::set(); + return g_descgate()->GetServiceIDs(); + } + + bool GetServiceInfo(const SServiceId& id_, SQualityServiceInfo& service_info_) + { + if (g_descgate() == nullptr) return false; + return g_descgate()->GetServiceInfo(id_, service_info_); + } + + std::set GetClientIDs() + { + if (g_descgate() == nullptr) return std::set(); + return g_descgate()->GetClientIDs(); + } + + bool GetClientInfo(const SServiceId& id_, SQualityServiceInfo& service_info_) + { + if (g_descgate() == nullptr) return false; + return g_descgate()->GetClientInfo(id_, service_info_); + } + QualityTopicInfoMultiMap GetPublishers() { - if (g_descgate() == nullptr) return QualityTopicInfoMultiMap(); - return g_descgate()->GetPublishers(); + std::set id_set = GetPublisherIDs(); + + Registration::QualityTopicInfoMultiMap multi_map; + for (const auto& id : id_set) + { + SQualityTopicInfo quality_info; + if (GetPublisherInfo(id, quality_info)) + { + multi_map.insert(std::pair(id.topic_name, quality_info)); + } + } + return multi_map; } QualityTopicInfoSet GetPublishers(const std::string& topic_name_) @@ -174,8 +232,18 @@ namespace eCAL QualityTopicInfoMultiMap GetSubscribers() { - if (g_descgate() == nullptr) return QualityTopicInfoMultiMap(); - return g_descgate()->GetSubscribers(); + std::set id_set = GetSubscriberIDs(); + + Registration::QualityTopicInfoMultiMap multi_map; + for (const auto& id : id_set) + { + SQualityTopicInfo quality_info; + if (GetSubscriberInfo(id, quality_info)) + { + multi_map.insert(std::pair(id.topic_name, quality_info)); + } + } + return multi_map; } QualityTopicInfoSet GetSubscribers(const std::string& topic_name_) @@ -198,14 +266,34 @@ namespace eCAL QualityServiceInfoMultimap GetServices() { - if (g_descgate() == nullptr) return QualityServiceInfoMultimap(); - return g_descgate()->GetServices(); + std::set id_set = GetServiceIDs(); + + Registration::QualityServiceInfoMultimap multi_map; + for (const auto& id : id_set) + { + SQualityServiceInfo quality_info; + if (GetServiceInfo(id, quality_info)) + { + multi_map.insert(std::pair(SServiceMethod{ id.service_name, id.method_name }, quality_info)); + } + } + return multi_map; } QualityServiceInfoMultimap GetClients() { - if (g_descgate() == nullptr) return QualityServiceInfoMultimap(); - return g_descgate()->GetClients(); + std::set id_set = GetClientIDs(); + + Registration::QualityServiceInfoMultimap multi_map; + for (const auto& id : id_set) + { + SQualityServiceInfo quality_info; + if (GetClientInfo(id, quality_info)) + { + multi_map.insert(std::pair(SServiceMethod{ id.service_name, id.method_name }, quality_info)); + } + } + return multi_map; } SServiceMethodInformation GetHighestQualityServiceMethodInformation(const SQualityServiceInfoSet& quality_service_info_set_) @@ -239,10 +327,9 @@ namespace eCAL void GetTopics(std::map& quality_topic_info_map_) { quality_topic_info_map_.clear(); - if (g_descgate() == nullptr) return; - QualityTopicInfoMultiMap pub_sub_map = g_descgate()->GetPublishers(); - QualityTopicInfoMultiMap sub_map = g_descgate()->GetSubscribers(); + QualityTopicInfoMultiMap pub_sub_map = GetPublishers(); + QualityTopicInfoMultiMap sub_map = GetSubscribers(); pub_sub_map.insert(sub_map.begin(), sub_map.end()); // transform into a map with the highest quality data type information @@ -296,10 +383,9 @@ namespace eCAL void GetServices(std::map& quality_service_info_map_) { quality_service_info_map_.clear(); - if (g_descgate() == nullptr) return; // transform into a map with the highest quality service method information - quality_service_info_map_ = ReduceQualityServiceIdMap(g_descgate()->GetServices()); + quality_service_info_map_ = ReduceQualityServiceIdMap(GetServices()); } void GetServiceMethodNames(std::set& service_method_names_) @@ -355,10 +441,9 @@ namespace eCAL void GetClients(std::map& quality_client_info_map_) { quality_client_info_map_.clear(); - if (g_descgate() == nullptr) return; // transform into a map with the highest quality service method information - quality_client_info_map_ = ReduceQualityServiceIdMap(g_descgate()->GetClients()); + quality_client_info_map_ = ReduceQualityServiceIdMap(GetClients()); } void GetClientMethodNames(std::set& client_method_names_) diff --git a/ecal/core/src/serialization/ecal_struct_sample_registration.h b/ecal/core/src/serialization/ecal_struct_sample_registration.h index 54b0bdcaea..3490716051 100644 --- a/ecal/core/src/serialization/ecal_struct_sample_registration.h +++ b/ecal/core/src/serialization/ecal_struct_sample_registration.h @@ -235,25 +235,6 @@ namespace eCAL } }; - struct SampleIdentifier - { - std::string entity_id; // unique id within that process - int32_t process_id = 0; // process id which produced the sample - std::string host_name; // host which produced the sample - - bool operator==(const SampleIdentifier& other) const { - return entity_id == other.entity_id && - process_id == other.process_id && - host_name == other.host_name; - } - - bool operator<(const SampleIdentifier& other) const - { - return std::tie(process_id, entity_id, host_name) - < std::tie(other.process_id, other.entity_id, other.host_name); - } - }; - // Registration sample struct Sample { diff --git a/ecal/tests/CMakeLists.txt b/ecal/tests/CMakeLists.txt index 28a6203d29..81bc6ea624 100644 --- a/ecal/tests/CMakeLists.txt +++ b/ecal/tests/CMakeLists.txt @@ -35,7 +35,7 @@ add_subdirectory(cpp/config_test) if(ECAL_CORE_REGISTRATION) add_subdirectory(cpp/registration_test) - add_subdirectory(cpp/registration_test_2) + add_subdirectory(cpp/registration_test_public) endif() add_subdirectory(cpp/event_test) diff --git a/ecal/tests/cpp/descgate_test/CMakeLists.txt b/ecal/tests/cpp/descgate_test/CMakeLists.txt index 284c224655..618604f280 100644 --- a/ecal/tests/cpp/descgate_test/CMakeLists.txt +++ b/ecal/tests/cpp/descgate_test/CMakeLists.txt @@ -22,7 +22,7 @@ find_package(Threads REQUIRED) find_package(GTest REQUIRED) set(descgate_test_src - src/getpublisher.cpp + src/descgate_getentities.cpp ${ECAL_CORE_PROJECT_ROOT}/core/src/ecal_descgate.cpp ) diff --git a/ecal/tests/cpp/descgate_test/src/getpublisher.cpp b/ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp similarity index 76% rename from ecal/tests/cpp/descgate_test/src/getpublisher.cpp rename to ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp index 3209a19cf2..afb58b4021 100644 --- a/ecal/tests/cpp/descgate_test/src/getpublisher.cpp +++ b/ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp @@ -116,14 +116,14 @@ TEST(core_cpp_descgate, PublisherExpiration) while ((runs--) != 0) { desc_gate.ApplySample(CreatePublisher("pub1", 1), eCAL::tl_none); - EXPECT_EQ(1, desc_gate.GetPublishers().size()); + EXPECT_EQ(1, desc_gate.GetPublisherIDs().size()); } // now let the sample expire desc_gate.ApplySample(DestroyPublisher("pub1", 1), eCAL::tl_none); // sample should be expired - EXPECT_EQ(0, desc_gate.GetPublishers().size()); + EXPECT_EQ(0, desc_gate.GetPublisherIDs().size()); } TEST(core_cpp_descgate, PublisherQualities) @@ -136,33 +136,24 @@ TEST(core_cpp_descgate, PublisherQualities) // create and apply publisher pub2 desc_gate.ApplySample(CreatePublisher("pub2", 2), eCAL::tl_none); - // check gate size - auto sample_map = desc_gate.GetPublishers(); - EXPECT_EQ(2, sample_map.size()); + // check size + auto id_set = desc_gate.GetPublisherIDs(); + EXPECT_EQ(2, id_set.size()); - // check pub1 quality + // check publisher qualities { - auto pub_it = sample_map.find("pub1"); - EXPECT_NE(pub_it, sample_map.end()); - if (pub_it != sample_map.end()) + for (const auto& id : id_set) { - EXPECT_EQ(1, pub_it->second.id); - EXPECT_EQ("pub1-tdatatype.name", pub_it->second.info.name); - EXPECT_EQ("pub1-tdatatype.encoding", pub_it->second.info.encoding); - EXPECT_EQ("pub1-tdatatype.descriptor", pub_it->second.info.descriptor); - } - } - - // check pub2 quality - { - auto pub_it = sample_map.find("pub2"); - EXPECT_NE(pub_it, sample_map.end()); - if (pub_it != sample_map.end()) - { - EXPECT_EQ(2, pub_it->second.id); - EXPECT_EQ("pub2-tdatatype.name", pub_it->second.info.name); - EXPECT_EQ("pub2-tdatatype.encoding", pub_it->second.info.encoding); - EXPECT_EQ("pub2-tdatatype.descriptor", pub_it->second.info.descriptor); + eCAL::Registration::SQualityTopicInfo quality_info; + bool found = desc_gate.GetPublisherInfo(id, quality_info); + EXPECT_TRUE(found); + if (found) + { + std::string tname = id.topic_name; + EXPECT_EQ(tname + "tdatatype.name", quality_info.info.name); + EXPECT_EQ(tname + "tdatatype.encoding", quality_info.info.encoding); + EXPECT_EQ(tname + "tdatatype.descriptor", quality_info.info.descriptor); + } } } @@ -171,7 +162,7 @@ TEST(core_cpp_descgate, PublisherQualities) desc_gate.ApplySample(DestroyPublisher("pub2", 2), eCAL::tl_none); // sample should be expired - EXPECT_EQ(0, desc_gate.GetPublishers().size()); + EXPECT_EQ(0, desc_gate.GetPublisherIDs().size()); } TEST(core_cpp_descgate, ManyPublisher) @@ -186,7 +177,7 @@ TEST(core_cpp_descgate, ManyPublisher) } // map should contain num_pub samples - EXPECT_EQ(num_pub, desc_gate.GetPublishers().size()); + EXPECT_EQ(num_pub, desc_gate.GetPublisherIDs().size()); // now let the samples expire for (auto pub = 0; pub < num_pub; ++pub) @@ -196,7 +187,7 @@ TEST(core_cpp_descgate, ManyPublisher) } // samples should be expired - EXPECT_EQ(0, desc_gate.GetPublishers().size()); + EXPECT_EQ(0, desc_gate.GetPublisherIDs().size()); } TEST(core_cpp_descgate, SubscriberExpiration) @@ -208,14 +199,14 @@ TEST(core_cpp_descgate, SubscriberExpiration) while ((runs--) != 0) { desc_gate.ApplySample(CreateSubscriber("sub1", 1), eCAL::tl_none); - EXPECT_EQ(1, desc_gate.GetSubscribers().size()); + EXPECT_EQ(1, desc_gate.GetSubscriberIDs().size()); } // now let the sample expire desc_gate.ApplySample(DestroySubscriber("sub1", 1), eCAL::tl_none); // sample should be expired - EXPECT_EQ(0, desc_gate.GetSubscribers().size()); + EXPECT_EQ(0, desc_gate.GetSubscriberIDs().size()); } TEST(core_cpp_descgate, SubscriberQualities) @@ -228,33 +219,24 @@ TEST(core_cpp_descgate, SubscriberQualities) // create and apply subscriber sub2 desc_gate.ApplySample(CreateSubscriber("sub2", 2), eCAL::tl_none); - // check gate size - auto sample_map = desc_gate.GetSubscribers(); - EXPECT_EQ(2, sample_map.size()); - - // check sub1 quality - { - auto sub_it = sample_map.find("sub1"); - EXPECT_NE(sub_it, sample_map.end()); - if (sub_it != sample_map.end()) - { - EXPECT_EQ(1, sub_it->second.id); - EXPECT_EQ("sub1-tdatatype.name", sub_it->second.info.name); - EXPECT_EQ("sub1-tdatatype.encoding", sub_it->second.info.encoding); - EXPECT_EQ("sub1-tdatatype.descriptor", sub_it->second.info.descriptor); - } - } + // check size + auto id_set = desc_gate.GetPublisherIDs(); + EXPECT_EQ(2, id_set.size()); - // check sub2 quality + // check subscriber qualities { - auto sub_it = sample_map.find("sub2"); - EXPECT_NE(sub_it, sample_map.end()); - if (sub_it != sample_map.end()) + for (const auto& id : id_set) { - EXPECT_EQ(2, sub_it->second.id); - EXPECT_EQ("sub2-tdatatype.name", sub_it->second.info.name); - EXPECT_EQ("sub2-tdatatype.encoding", sub_it->second.info.encoding); - EXPECT_EQ("sub2-tdatatype.descriptor", sub_it->second.info.descriptor); + eCAL::Registration::SQualityTopicInfo quality_info; + bool found = desc_gate.GetSubscriberInfo(id, quality_info); + EXPECT_TRUE(found); + if (found) + { + std::string tname = id.topic_name; + EXPECT_EQ(tname + "tdatatype.name", quality_info.info.name); + EXPECT_EQ(tname + "tdatatype.encoding", quality_info.info.encoding); + EXPECT_EQ(tname + "tdatatype.descriptor", quality_info.info.descriptor); + } } } @@ -263,7 +245,7 @@ TEST(core_cpp_descgate, SubscriberQualities) desc_gate.ApplySample(DestroySubscriber("sub2", 2), eCAL::tl_none); // sample should be expired - EXPECT_EQ(0, desc_gate.GetSubscribers().size()); + EXPECT_EQ(0, desc_gate.GetSubscriberIDs().size()); } TEST(core_cpp_descgate, ManySubscriber) @@ -278,7 +260,7 @@ TEST(core_cpp_descgate, ManySubscriber) } // map should contain num_sub samples - EXPECT_EQ(num_sub, desc_gate.GetSubscribers().size()); + EXPECT_EQ(num_sub, desc_gate.GetSubscriberIDs().size()); // now let the samples expire for (auto sub = 0; sub < num_sub; ++sub) @@ -288,7 +270,7 @@ TEST(core_cpp_descgate, ManySubscriber) } // samples should be expired - EXPECT_EQ(0, desc_gate.GetSubscribers().size()); + EXPECT_EQ(0, desc_gate.GetSubscriberIDs().size()); } TEST(core_cpp_descgate, ServiceExpiration) @@ -301,14 +283,14 @@ TEST(core_cpp_descgate, ServiceExpiration) { desc_gate.ApplySample(CreateService("service1", 1), eCAL::tl_none); - EXPECT_EQ(1, desc_gate.GetServices().size()); + EXPECT_EQ(1, desc_gate.GetServiceIDs().size()); } // now let the sample expire desc_gate.ApplySample(DestroyService("service1", 1), eCAL::tl_none); // sample should be expired - EXPECT_EQ(0, desc_gate.GetServices().size()); + EXPECT_EQ(0, desc_gate.GetServiceIDs().size()); } TEST(core_cpp_descgate, ManyService) @@ -323,7 +305,7 @@ TEST(core_cpp_descgate, ManyService) } // map should contain num_service samples - EXPECT_EQ(num_service, desc_gate.GetServices().size()); + EXPECT_EQ(num_service, desc_gate.GetServiceIDs().size()); // now let the samples expire for (auto service = 0; service < num_service; ++service) @@ -333,7 +315,7 @@ TEST(core_cpp_descgate, ManyService) } // samples should be expired - EXPECT_EQ(0, desc_gate.GetServices().size()); + EXPECT_EQ(0, desc_gate.GetServiceIDs().size()); } TEST(core_cpp_descgate, ClientExpiration) @@ -345,14 +327,14 @@ TEST(core_cpp_descgate, ClientExpiration) while ((runs--) != 0) { desc_gate.ApplySample(CreateClient("client1", 1), eCAL::tl_none); - EXPECT_EQ(1, desc_gate.GetClients().size()); + EXPECT_EQ(1, desc_gate.GetClientIDs().size()); } // now let the sample expire desc_gate.ApplySample(DestroyClient("client1", 1), eCAL::tl_none); // sample should be expired - EXPECT_EQ(0, desc_gate.GetClients().size()); + EXPECT_EQ(0, desc_gate.GetClientIDs().size()); } TEST(core_cpp_descgate, ManyClient) @@ -367,7 +349,7 @@ TEST(core_cpp_descgate, ManyClient) } // map should contain num_client samples - EXPECT_EQ(num_client, desc_gate.GetClients().size()); + EXPECT_EQ(num_client, desc_gate.GetClientIDs().size()); // now let the samples expire for (auto client = 0; client < num_client; ++client) @@ -377,5 +359,5 @@ TEST(core_cpp_descgate, ManyClient) } // samples should be expired - EXPECT_EQ(0, desc_gate.GetClients().size()); + EXPECT_EQ(0, desc_gate.GetClientIDs().size()); } diff --git a/ecal/tests/cpp/registration_test_2/CMakeLists.txt b/ecal/tests/cpp/registration_test_public/CMakeLists.txt similarity index 93% rename from ecal/tests/cpp/registration_test_2/CMakeLists.txt rename to ecal/tests/cpp/registration_test_public/CMakeLists.txt index e7b7db3dd2..c20365afca 100644 --- a/ecal/tests/cpp/registration_test_2/CMakeLists.txt +++ b/ecal/tests/cpp/registration_test_public/CMakeLists.txt @@ -16,7 +16,7 @@ # # ========================= eCAL LICENSE ================================= -project(test_registration_2) +project(test_registration_public) find_package(Threads REQUIRED) find_package(GTest REQUIRED) @@ -52,7 +52,7 @@ target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) ecal_install_gtest(${PROJECT_NAME}) -set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER tests/cpp/registration_2) +set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER tests/cpp/core) source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${${PROJECT_NAME}_src} diff --git a/ecal/tests/cpp/registration_test_2/src/registration_getclients.cpp b/ecal/tests/cpp/registration_test_public/src/registration_getclients.cpp similarity index 85% rename from ecal/tests/cpp/registration_test_2/src/registration_getclients.cpp rename to ecal/tests/cpp/registration_test_public/src/registration_getclients.cpp index d79c8136a0..8c3a09b067 100644 --- a/ecal/tests/cpp/registration_test_2/src/registration_getclients.cpp +++ b/ecal/tests/cpp/registration_test_public/src/registration_getclients.cpp @@ -25,11 +25,10 @@ enum { CMN_MONITORING_TIMEOUT_MS = (5000 + 100), CMN_REGISTRATION_REFRESH_MS = (1000) }; - -TEST(core_cpp_registration, ClientExpiration) +TEST(core_cpp_registration_public, ClientExpiration) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -89,10 +88,10 @@ TEST(core_cpp_registration, ClientExpiration) eCAL::Finalize(); } -TEST(core_cpp_registration, ClientEqualQualities) +TEST(core_cpp_registration_public, ClientEqualQualities) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -187,10 +186,10 @@ TEST(core_cpp_registration, ClientEqualQualities) eCAL::Finalize(); } -TEST(core_cpp_registration, ClientDifferentQualities) +TEST(core_cpp_registration_public, ClientDifferentQualities) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -263,3 +262,41 @@ TEST(core_cpp_registration, ClientDifferentQualities) // finalize eCAL API eCAL::Finalize(); } + +TEST(core_cpp_registration_public, GetClientIDs) +{ + // initialize eCAL API + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); + + // enable loop back communication in the same process + eCAL::Util::EnableLoopback(true); + + // create simple client + { + // create client + eCAL::SServiceMethodInformation service_method_info; + service_method_info.request_type.name = "foo::req_type"; + service_method_info.request_type.descriptor = "foo::req_desc"; + service_method_info.response_type.name = "foo::resp_type"; + service_method_info.response_type.descriptor = "foo::resp_desc"; + const eCAL::CServiceClient client("foo::service", { {"foo::method", service_method_info} }); + + // let's register + eCAL::Process::SleepMS(2 * CMN_REGISTRATION_REFRESH_MS); + + // get client + auto id_set = eCAL::Registration::GetClientIDs(); + EXPECT_EQ(1, id_set.size()); + if (id_set.size() > 0) + { + eCAL::Registration::SQualityServiceInfo info; + EXPECT_TRUE(eCAL::Registration::GetClientInfo(*id_set.begin(), info)); + + // check service/method names + EXPECT_EQ(service_method_info, info.info); + } + } + + // finalize eCAL API + eCAL::Finalize(); +} diff --git a/ecal/tests/cpp/registration_test_2/src/registration_getservices.cpp b/ecal/tests/cpp/registration_test_public/src/registration_getservices.cpp similarity index 81% rename from ecal/tests/cpp/registration_test_2/src/registration_getservices.cpp rename to ecal/tests/cpp/registration_test_public/src/registration_getservices.cpp index 7aba62527f..195053c40c 100644 --- a/ecal/tests/cpp/registration_test_2/src/registration_getservices.cpp +++ b/ecal/tests/cpp/registration_test_public/src/registration_getservices.cpp @@ -26,10 +26,10 @@ enum { CMN_REGISTRATION_REFRESH_MS = (1000) }; -TEST(core_cpp_registration_2, ServiceExpiration) +TEST(core_cpp_registration_public, ServiceExpiration) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration_2"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -85,10 +85,10 @@ TEST(core_cpp_registration_2, ServiceExpiration) eCAL::Finalize(); } -TEST(core_cpp_registration_2, ServiceEqualQualities) +TEST(core_cpp_registration_public, ServiceEqualQualities) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration_2"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -175,10 +175,10 @@ TEST(core_cpp_registration_2, ServiceEqualQualities) eCAL::Finalize(); } -TEST(core_cpp_registration_2, ServiceDifferentQualities) +TEST(core_cpp_registration_public, ServiceDifferentQualities) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration_2"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -243,3 +243,49 @@ TEST(core_cpp_registration_2, ServiceDifferentQualities) // finalize eCAL API eCAL::Finalize(); } + +TEST(core_cpp_registration_public, GetServiceIDs) +{ + // initialize eCAL API + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); + + // enable loop back communication in the same process + eCAL::Util::EnableLoopback(true); + + // create simple server + { + // create server + eCAL::CServiceServer service("foo::service"); + + // add description + eCAL::SServiceMethodInformation service_method_info; + service_method_info.request_type.name = "foo::req_type"; + service_method_info.request_type.descriptor = "foo::req_desc"; + service_method_info.response_type.name = "foo::resp_type"; + service_method_info.response_type.descriptor = "foo::resp_desc"; + + service.AddDescription("foo::method", + service_method_info.request_type.name, + service_method_info.request_type.descriptor, + service_method_info.response_type.name, + service_method_info.response_type.descriptor); + + // let's register + eCAL::Process::SleepMS(2 * CMN_REGISTRATION_REFRESH_MS); + + // get server + auto id_set = eCAL::Registration::GetServiceIDs(); + EXPECT_EQ(1, id_set.size()); + if (id_set.size() > 0) + { + eCAL::Registration::SQualityServiceInfo info; + EXPECT_TRUE(eCAL::Registration::GetServiceInfo(*id_set.begin(), info)); + + // check service/method names + EXPECT_EQ(service_method_info, info.info); + } + } + + // finalize eCAL API + eCAL::Finalize(); +} diff --git a/ecal/tests/cpp/registration_test_2/src/registration_gettopics.cpp b/ecal/tests/cpp/registration_test_public/src/registration_gettopics.cpp similarity index 73% rename from ecal/tests/cpp/registration_test_2/src/registration_gettopics.cpp rename to ecal/tests/cpp/registration_test_public/src/registration_gettopics.cpp index c0127164aa..6edceff9c5 100644 --- a/ecal/tests/cpp/registration_test_2/src/registration_gettopics.cpp +++ b/ecal/tests/cpp/registration_test_public/src/registration_gettopics.cpp @@ -31,10 +31,10 @@ enum { CMN_REGISTRATION_REFRESH_MS = (1000) }; -TEST(core_cpp_registration_2, GetTopics) +TEST(core_cpp_registration_public, GetTopics) { // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration_2"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -135,14 +135,14 @@ TEST(core_cpp_registration_2, GetTopics) eCAL::Finalize(); } -TEST(core_cpp_registration_2, GetTopicsParallel) +TEST(core_cpp_registration_public, GetTopicsParallel) { constexpr const int max_publisher_count(2000); constexpr const int waiting_time_thread(4000); constexpr const int parallel_threads(1); // initialize eCAL API - eCAL::Initialize(0, nullptr, "core_cpp_registration_2"); + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); // enable loop back communication in the same process eCAL::Util::EnableLoopback(true); @@ -205,3 +205,69 @@ TEST(core_cpp_registration_2, GetTopicsParallel) // finalize eCAL API eCAL::Finalize(); } + +TEST(core_cpp_registration_public, GetTopicIDs) +{ + // initialize eCAL API + eCAL::Initialize(0, nullptr, "core_cpp_registration_public"); + + // enable loop back communication in the same process + eCAL::Util::EnableLoopback(true); + + // create and check a few pub/sub entities + { + eCAL::SDataTypeInformation info_A1{ "typeA1" ,"", "descA1" }; + eCAL::SDataTypeInformation info_A2{ "typeA2" ,"", "descA2" }; + eCAL::SDataTypeInformation info_A3{ "typeA3" ,"", "descA3" }; + + eCAL::SDataTypeInformation info_B1{ "typeB1" ,"", "descB1" }; + eCAL::SDataTypeInformation info_B2{ "typeB2" ,"", "descB2" }; + + // create 3 publisher + eCAL::CPublisher pub1("A1", info_A1); + eCAL::CPublisher pub2("A2", info_A2); + eCAL::CPublisher pub3("A3", info_A3); + + // create 2 subscriber + eCAL::CSubscriber sub1("B1", info_B1); + eCAL::CSubscriber sub2("B2", info_B2); + + // let's register + eCAL::Process::SleepMS(2 * CMN_REGISTRATION_REFRESH_MS); + + // get publisher + { + auto id_set = eCAL::Registration::GetPublisherIDs(); + EXPECT_EQ(3, id_set.size()); + + // check publisher datatype information + for (const auto& id : id_set) + { + eCAL::Registration::SQualityTopicInfo info; + EXPECT_TRUE(eCAL::Registration::GetPublisherInfo(id, info)); + EXPECT_EQ(std::string("type") + id.topic_name, info.info.name); + EXPECT_EQ("", info.info.encoding); + EXPECT_EQ(std::string("desc") + id.topic_name, info.info.descriptor); + } + } + + // get subscriber + { + auto id_set = eCAL::Registration::GetSubscriberIDs(); + EXPECT_EQ(2, id_set.size()); + + // check subscriber datatype information + for (const auto& id : id_set) + { + eCAL::Registration::SQualityTopicInfo info; + EXPECT_TRUE(eCAL::Registration::GetSubscriberInfo(id, info)); + EXPECT_EQ(std::string("type") + id.topic_name, info.info.name); + EXPECT_EQ("", info.info.encoding); + EXPECT_EQ(std::string("desc") + id.topic_name, info.info.descriptor); + } + } + } + + // finalize eCAL API + eCAL::Finalize(); +} From 3e597961cc07c3bc38a99e7b7a5d82002f0f60fe Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:27:01 +0200 Subject: [PATCH 2/7] 2 tests fixed --- .../cpp/descgate_test/src/descgate_getentities.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp b/ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp index afb58b4021..c17bf5ec4f 100644 --- a/ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp +++ b/ecal/tests/cpp/descgate_test/src/descgate_getentities.cpp @@ -150,9 +150,9 @@ TEST(core_cpp_descgate, PublisherQualities) if (found) { std::string tname = id.topic_name; - EXPECT_EQ(tname + "tdatatype.name", quality_info.info.name); - EXPECT_EQ(tname + "tdatatype.encoding", quality_info.info.encoding); - EXPECT_EQ(tname + "tdatatype.descriptor", quality_info.info.descriptor); + EXPECT_EQ(tname + "-tdatatype.name", quality_info.info.name); + EXPECT_EQ(tname + "-tdatatype.encoding", quality_info.info.encoding); + EXPECT_EQ(tname + "-tdatatype.descriptor", quality_info.info.descriptor); } } } @@ -220,7 +220,7 @@ TEST(core_cpp_descgate, SubscriberQualities) desc_gate.ApplySample(CreateSubscriber("sub2", 2), eCAL::tl_none); // check size - auto id_set = desc_gate.GetPublisherIDs(); + auto id_set = desc_gate.GetSubscriberIDs(); EXPECT_EQ(2, id_set.size()); // check subscriber qualities @@ -233,9 +233,9 @@ TEST(core_cpp_descgate, SubscriberQualities) if (found) { std::string tname = id.topic_name; - EXPECT_EQ(tname + "tdatatype.name", quality_info.info.name); - EXPECT_EQ(tname + "tdatatype.encoding", quality_info.info.encoding); - EXPECT_EQ(tname + "tdatatype.descriptor", quality_info.info.descriptor); + EXPECT_EQ(tname + "-tdatatype.name", quality_info.info.name); + EXPECT_EQ(tname + "-tdatatype.encoding", quality_info.info.encoding); + EXPECT_EQ(tname + "-tdatatype.descriptor", quality_info.info.descriptor); } } } From cf608e21f5e7d8aa29509d90314fe2c0b969ee04 Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:36:37 +0200 Subject: [PATCH 3/7] fixed various clang-tidy and kk-review issues :-) --- ecal/core/include/ecal/ecal_registration.h | 6 ++---- ecal/core/src/ecal_descgate.cpp | 2 -- ecal/core/src/registration/ecal_registration.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/ecal/core/include/ecal/ecal_registration.h b/ecal/core/include/ecal/ecal_registration.h index f72ef1578d..f189727024 100644 --- a/ecal/core/include/ecal/ecal_registration.h +++ b/ecal/core/include/ecal/ecal_registration.h @@ -58,13 +58,12 @@ namespace eCAL using TopicId = std::uint64_t; struct SQualityTopicInfo { - TopicId id = 0; SDataTypeInformation info; DescQualityFlags quality = DescQualityFlags::NO_QUALITY; bool operator<(const SQualityTopicInfo& other) const { - return std::tie(quality, id) < std::tie(other.quality, other.id); + return std::tie(quality) < std::tie(other.quality); } }; using QualityTopicInfoMultiMap = std::multimap; @@ -73,14 +72,13 @@ namespace eCAL using ServiceId = std::uint64_t; struct SQualityServiceInfo { - ServiceId id = 0; SServiceMethodInformation info; DescQualityFlags request_quality = DescQualityFlags::NO_QUALITY; DescQualityFlags response_quality = DescQualityFlags::NO_QUALITY; bool operator<(const SQualityServiceInfo& other) const { - return std::tie(request_quality, response_quality, id) < std::tie(other.request_quality, other.response_quality, other.id); + return std::tie(request_quality, response_quality) < std::tie(other.request_quality, other.response_quality); } }; struct SServiceMethod diff --git a/ecal/core/src/ecal_descgate.cpp b/ecal/core/src/ecal_descgate.cpp index 93c0aee247..fcdef83817 100644 --- a/ecal/core/src/ecal_descgate.cpp +++ b/ecal/core/src/ecal_descgate.cpp @@ -214,7 +214,6 @@ namespace eCAL const auto topic_info_key = Registration::STopicId{ topic_id_, topic_name_ }; Registration::SQualityTopicInfo topic_quality_info; - topic_quality_info.id = std::stoull(topic_id_.entity_id); topic_quality_info.info = topic_info_; topic_quality_info.quality = topic_quality_; @@ -246,7 +245,6 @@ namespace eCAL const auto service_method_info_key = Registration::SServiceId{ service_id_, service_name_, method_name_}; Registration::SQualityServiceInfo service_quality_info; - service_quality_info.id = std::stoull(service_id_.entity_id); service_quality_info.info.request_type = request_type_information_; service_quality_info.info.response_type = response_type_information_; service_quality_info.request_quality = request_type_quality_; diff --git a/ecal/core/src/registration/ecal_registration.cpp b/ecal/core/src/registration/ecal_registration.cpp index aac2735cb0..21b7bc4ed2 100644 --- a/ecal/core/src/registration/ecal_registration.cpp +++ b/ecal/core/src/registration/ecal_registration.cpp @@ -211,7 +211,7 @@ namespace eCAL QualityTopicInfoMultiMap GetPublishers() { - std::set id_set = GetPublisherIDs(); + const std::set id_set = GetPublisherIDs(); Registration::QualityTopicInfoMultiMap multi_map; for (const auto& id : id_set) @@ -232,7 +232,7 @@ namespace eCAL QualityTopicInfoMultiMap GetSubscribers() { - std::set id_set = GetSubscriberIDs(); + const std::set id_set = GetSubscriberIDs(); Registration::QualityTopicInfoMultiMap multi_map; for (const auto& id : id_set) @@ -266,7 +266,7 @@ namespace eCAL QualityServiceInfoMultimap GetServices() { - std::set id_set = GetServiceIDs(); + const std::set id_set = GetServiceIDs(); Registration::QualityServiceInfoMultimap multi_map; for (const auto& id : id_set) @@ -282,7 +282,7 @@ namespace eCAL QualityServiceInfoMultimap GetClients() { - std::set id_set = GetClientIDs(); + const std::set id_set = GetClientIDs(); Registration::QualityServiceInfoMultimap multi_map; for (const auto& id : id_set) From bc4928fde2acd9fc325869fb73c25be66a491a2b Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Tue, 13 Aug 2024 20:50:02 +0200 Subject: [PATCH 4/7] topic and service data type information may be updated at runtime --- ecal/core/src/ecal_descgate.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ecal/core/src/ecal_descgate.cpp b/ecal/core/src/ecal_descgate.cpp index fcdef83817..24ec6a5922 100644 --- a/ecal/core/src/ecal_descgate.cpp +++ b/ecal/core/src/ecal_descgate.cpp @@ -218,11 +218,7 @@ namespace eCAL topic_quality_info.quality = topic_quality_; const std::unique_lock lock(topic_info_map_.mtx); - auto iter = topic_info_map_.map.find(topic_info_key); - if (iter == topic_info_map_.map.end()) - { - topic_info_map_.map[topic_info_key] = topic_quality_info; - } + topic_info_map_.map[topic_info_key] = topic_quality_info; } void CDescGate::RemTopicDescription(SQualityTopicIdMap& topic_info_map_, @@ -251,11 +247,7 @@ namespace eCAL service_quality_info.response_quality = response_type_quality_; const std::lock_guard lock(service_method_info_map_.mtx); - auto iter = service_method_info_map_.map.find(service_method_info_key); - if (iter == service_method_info_map_.map.end()) - { - service_method_info_map_.map[service_method_info_key] = service_quality_info; - } + service_method_info_map_.map[service_method_info_key] = service_quality_info; } void CDescGate::RemServiceDescription(SQualityServiceIdMap& service_method_info_map_, From 55b483c079200b9c6677c6e60f1656e868a91671 Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Mon, 19 Aug 2024 11:35:05 +0200 Subject: [PATCH 5/7] additional DataTypeInformation for comparison doxygen comments for the new API functions --- ecal/core/include/ecal/ecal_registration.h | 50 +++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/ecal/core/include/ecal/ecal_registration.h b/ecal/core/include/ecal/ecal_registration.h index f189727024..5afd1ffdec 100644 --- a/ecal/core/include/ecal/ecal_registration.h +++ b/ecal/core/include/ecal/ecal_registration.h @@ -63,7 +63,7 @@ namespace eCAL bool operator<(const SQualityTopicInfo& other) const { - return std::tie(quality) < std::tie(other.quality); + return std::tie(quality, info) < std::tie(other.quality, info); } }; using QualityTopicInfoMultiMap = std::multimap; @@ -94,20 +94,60 @@ namespace eCAL using QualityServiceInfoMultimap = std::multimap; using SQualityServiceInfoSet = std::set; - // get publisher information + /** + * @brief Get complete snapshot of all known publisher. + * + * @return Set of topic id's. + **/ ECAL_API std::set GetPublisherIDs(); + + /** + * @brief Get data type information with quality for specific publisher. + * + * @return True if information could be queried. + **/ ECAL_API bool GetPublisherInfo(const STopicId& id_, SQualityTopicInfo& topic_info_); - // get subscriber information + /** + * @brief Get complete snapshot of all known subscriber. + * + * @return Set of topic id's. + **/ ECAL_API std::set GetSubscriberIDs(); + + /** + * @brief Get data type information with quality for specific subscriber. + * + * @return True if information could be queried. + **/ ECAL_API bool GetSubscriberInfo(const STopicId& id_, SQualityTopicInfo& topic_info_); - // get service information + /** + * @brief Get complete snapshot of all known services. + * + * @return Set of service id's. + **/ ECAL_API std::set GetServiceIDs(); + + /** + * @brief Get service method information with quality for specific service. + * + * @return True if information could be queried. + **/ ECAL_API bool GetServiceInfo(const SServiceId& id_, SQualityServiceInfo& service_info_); - // get client information + /** + * @brief Get complete snapshot of all known clients. + * + * @return Set of service id's. + **/ ECAL_API std::set GetClientIDs(); + + /** + * @brief Get service method information with quality for specific client. + * + * @return True if information could be queried. + **/ ECAL_API bool GetClientInfo(const SServiceId& id_, SQualityServiceInfo& service_info_); /** From 90adfe66194f99297ceb346d4a3695b601198283 Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:19:21 +0200 Subject: [PATCH 6/7] eCAL::Registration::SampleIdentifier (additional) back to ecal_struct_sample_registration.h --- .../ecal_struct_sample_registration.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ecal/core/src/serialization/ecal_struct_sample_registration.h b/ecal/core/src/serialization/ecal_struct_sample_registration.h index 3490716051..54b0bdcaea 100644 --- a/ecal/core/src/serialization/ecal_struct_sample_registration.h +++ b/ecal/core/src/serialization/ecal_struct_sample_registration.h @@ -235,6 +235,25 @@ namespace eCAL } }; + struct SampleIdentifier + { + std::string entity_id; // unique id within that process + int32_t process_id = 0; // process id which produced the sample + std::string host_name; // host which produced the sample + + bool operator==(const SampleIdentifier& other) const { + return entity_id == other.entity_id && + process_id == other.process_id && + host_name == other.host_name; + } + + bool operator<(const SampleIdentifier& other) const + { + return std::tie(process_id, entity_id, host_name) + < std::tie(other.process_id, other.entity_id, other.host_name); + } + }; + // Registration sample struct Sample { From e9694135fdfe3541d5320d4f2a49b0c2f6200950 Mon Sep 17 00:00:00 2001 From: rex-schilasky <49162693+rex-schilasky@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:14:18 +0200 Subject: [PATCH 7/7] last commit reverted .. needs to be done in a separate PR --- .../ecal_struct_sample_registration.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ecal/core/src/serialization/ecal_struct_sample_registration.h b/ecal/core/src/serialization/ecal_struct_sample_registration.h index 54b0bdcaea..3490716051 100644 --- a/ecal/core/src/serialization/ecal_struct_sample_registration.h +++ b/ecal/core/src/serialization/ecal_struct_sample_registration.h @@ -235,25 +235,6 @@ namespace eCAL } }; - struct SampleIdentifier - { - std::string entity_id; // unique id within that process - int32_t process_id = 0; // process id which produced the sample - std::string host_name; // host which produced the sample - - bool operator==(const SampleIdentifier& other) const { - return entity_id == other.entity_id && - process_id == other.process_id && - host_name == other.host_name; - } - - bool operator<(const SampleIdentifier& other) const - { - return std::tie(process_id, entity_id, host_name) - < std::tie(other.process_id, other.entity_id, other.host_name); - } - }; - // Registration sample struct Sample {