Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[21458] Add IDL format to topic entities #245

Merged
merged 6 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/cpp/HelloWorldExample/Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ void Monitor::Listener::on_topic_discovery(
EntityId topic_id,
const DomainListener::Status& status)
{

static_cast<void>(domain_id);
Info topic_info = StatisticsBackend::get_info(topic_id);

Expand Down
10 changes: 10 additions & 0 deletions include/fastdds_statistics_backend/StatisticsBackend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,16 @@ class StatisticsBackend
static Info get_info(
EntityId entity_id);

/**
* @brief Get the IDL representation of a data type in string format for a given topic entity
*
* @param entity_id The entity for which the data type IDL is retrieved.
* @return String object describing the entity's data type IDL.
*/
FASTDDS_STATISTICS_BACKEND_DllAPI
static std::string get_type_idl(
EntityId entity_id);

/**
* @brief Provides access to the data measured during the monitoring.
*
Expand Down
13 changes: 13 additions & 0 deletions src/cpp/StatisticsBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,19 @@ Info StatisticsBackend::get_info(
return StatisticsBackendData::get_instance()->database_->get_info(entity_id);
}

std::string StatisticsBackend::get_type_idl(
EntityId entity_id)
{
// Check if the entity is a topic
if (EntityKind::TOPIC != get_type(entity_id))
{
throw BadParameter("EntityId received does not match with a valid topic entity");
}
Info topic_info = StatisticsBackend::get_info(entity_id);
return StatisticsBackendData::get_instance()->database_->get_type_idl(topic_info[DATA_TYPE_TAG]);

}

JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
std::vector<StatisticsData> StatisticsBackend::get_data(
DataKind data_type,
const std::vector<EntityId>& entity_ids_source,
Expand Down
50 changes: 47 additions & 3 deletions src/cpp/database/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ EntityId Database::insert_new_topic(
std::shared_ptr<Domain> domain = std::const_pointer_cast<Domain>(
std::static_pointer_cast<const Domain>(get_entity_nts(domain_id)));

// Create the topic to insert in the database
auto topic = std::make_shared<Topic>(
name,
type_name,
Expand All @@ -279,6 +280,33 @@ EntityId Database::insert_new_topic(
return entity_id;
}

bool Database::is_type_in_database(
const std::string& type_name)
{

if (type_idls_.find(type_name) != type_idls_.end())
{
return true;
}
else
{
return false;
}
JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
}

void Database::insert_new_type_idl(
const std::string& type_name,
const std::string& type_idl)
{
std::lock_guard<std::shared_timed_mutex> guard(mutex_);
if (type_name.empty() || type_idl.empty())
{
throw BadParameter("Type name or type IDL cannot be empty");
}
type_idls_[type_name] = type_idl;
}


JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
EntityId Database::insert_new_endpoint(
const std::string& endpoint_guid,
const std::string& name,
Expand Down Expand Up @@ -656,7 +684,7 @@ void Database::insert_nts(
throw BadParameter("Topic data type cannot be empty");
}

/* Check that domain exits */
/* Check that domain exists */
bool domain_exists = false;
for (const auto& domain_it : domains_)
{
Expand Down Expand Up @@ -2103,6 +2131,22 @@ std::vector<std::pair<EntityId, EntityId>> Database::get_entities_by_name_nts(
return entities;
}

std::string Database::get_type_idl(const std::string& type_name) const
{
std::shared_lock<std::shared_timed_mutex> lock(mutex_);
return get_type_idl_nts(type_name);
}

std::string Database::get_type_idl_nts(const std::string& type_name) const
{
auto it = type_idls_.find(type_name);
if (it != type_idls_.end())
{
return it->second;
}
throw BadParameter("Type " + type_name + " not found in the database");
JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
}

void Database::erase(
EntityId& domain_id)
{
Expand Down Expand Up @@ -4624,7 +4668,6 @@ DatabaseDump Database::dump_entity_(
entity_info[ALIAS_TAG] = entity->alias;
entity_info[DATA_TYPE_TAG] = entity->data_type;
entity_info[STATUS_TAG] = entity->status;

entity_info[DOMAIN_ENTITY_TAG] = id_to_string(entity->domain->id);

// metatraffic and active attributes are stored but ignored when loading
Expand Down Expand Up @@ -5303,8 +5346,9 @@ Info Database::get_info(
break;
}
}

return info;

}
JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved

void Database::check_entity_kinds(
Expand Down
47 changes: 47 additions & 0 deletions src/cpp/database/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class Database
const std::string& topic_type,
const EntityId& topic_id);


JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
/**
* @brief Create new Topic and insert it in database.
* @param name The name of the Topic.
Expand All @@ -156,6 +157,24 @@ class Database
const std::string& alias,
const EntityId& domain_id);

/**
* @brief Check if a Topic data type is already in the database
* @param type_name The type name of the Topic.
*
* @return True if the Topic data type is in the database.
*/
bool is_type_in_database(
const std::string& type_name);

/**
* @brief Insert a new type IDL into the database.
* @param topic_type The type of the topic.
* @param topic_idl The IDL representation of the type
*/
void insert_new_type_idl(
const std::string& topic_type,
const std::string& topic_idl);

/**
* @brief Create new Endpoint and corresponding Locator, and insert them in database.
* @param endpoint_guid The GUID of the Endpoint.
Expand Down Expand Up @@ -444,6 +463,16 @@ class Database
EntityKind entity_kind,
const std::string& name) const;

/**
* @brief Get the type IDL of a given type name, if it exists.
*
* @param type_name The name of the data type for which to search.
* @throws eprosima::statistics_backend::BadParameter if \c type_name does not exist in the database.
* @return The IDL representation of the type in std::string format.
*/
std::string get_type_idl(
const std::string& type_name) const;

/**
* @brief Get the entity of a given EntityKind that matches with the requested GUID.
*
Expand Down Expand Up @@ -1167,6 +1196,16 @@ class Database
EntityKind entity_kind,
const std::string& name) const;

/**
* @brief Get the type IDL of a given type name, if it exists. This method is not thread safe.
*
* @param type_name The name of the data type for which to search.
* @throws eprosima::statistics_backend::BadParameter if \c type_name does not exist in the database.
* @return The IDL representation of the type in std::string format.
*/
std::string get_type_idl_nts(
const std::string& type_name) const;

/**
* @brief Get the entity of a given EntityKind that matches with the requested GUID. This method is not thread safe.
*
Expand Down Expand Up @@ -1446,6 +1485,14 @@ class Database
*/
std::map<EntityId, std::map<EntityId, std::shared_ptr<Topic>>> topics_;

/**
* Collection of topic IDLs sorted by topic data types, with which they are biunivocally identified.
* This is used to store the IDLs of the discovered topics
*
* Each value in the collection is in turn a map of the actual Topic IDLs sorted by data type
*/
std::map<std::string, std::string> type_idls_;

//! Graph map describing per domain complete topology of the entities.
std::map<EntityId, Graph> domain_view_graph;

Expand Down
6 changes: 6 additions & 0 deletions src/cpp/database/database_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,12 @@ EntityId DatabaseEntityQueue::process_endpoint_discovery(
details::StatisticsBackendData::DiscoveryStatus::DISCOVERY);
}

// Store type IDL in the database in case it is not already stored. Ignore metatraffic topics
if (!database_->is_type_in_database(info.type_name) && !info.is_virtual_metatraffic)
{
database_->insert_new_type_idl(info.type_name, info.type_idl);
}

// Create the endpoint
EntityId endpoint_id;
std::stringstream name;
Expand Down
4 changes: 2 additions & 2 deletions src/cpp/database/database_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <fastdds/rtps/common/SequenceNumber.hpp>
#include <fastdds/rtps/common/RemoteLocators.hpp>
#include <fastdds/dds/log/Log.hpp>

#include <fastdds_statistics_backend/types/JSONTags.h>

#include <database/database.hpp>
Expand Down Expand Up @@ -372,9 +371,10 @@ struct EntityDiscoveryInfo
std::string user;
std::string process;

// Enpoint data
// Endpoint data
std::string topic_name;
std::string type_name;
std::string type_idl;
fastdds::rtps::RemoteLocatorList locators;

// Alias
Expand Down
47 changes: 46 additions & 1 deletion src/cpp/subscriber/StatisticsParticipantListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@

#include <fastdds/dds/core/status/StatusMask.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
#include <fastdds/dds/log/Log.hpp>
#include <fastdds/rtps/writer/WriterDiscoveryStatus.hpp>
#include <fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilder.hpp>
#include <fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilderFactory.hpp>
#include <fastdds/dds/xtypes/utils.hpp>
#include <fastdds/rtps/common/EntityId_t.hpp>
#include <fastdds/rtps/writer/WriterDiscoveryStatus.hpp>

#include "database/database_queue.hpp"
#include "subscriber/QosSerializer.hpp"
Expand Down Expand Up @@ -318,12 +322,34 @@ void StatisticsParticipantListener::on_data_reader_discovery(
}
}

// Create IDL representation of the discovered type
// Get remote type information
xtypes::TypeObject remote_type_object;
if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
info.type_information.type_information.complete().typeid_with_size().type_id(),
remote_type_object))
{
// Error
return;
}

// Build remotely discovered type
DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
remote_type_object)->build();

// Serialize DynamicType into its IDL representation
std::stringstream idl;
idl_serialize(remote_type, idl);
discovery_info.type_idl = idl.str();
JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved

entity_queue_->push(timestamp, discovery_info);

// Wait until the entity queue is processed and restart the data queues
entity_queue_->flush();
data_queue_->start_consumer();
monitor_service_status_data_queue_->start_consumer();


JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved
}

void StatisticsParticipantListener::on_data_writer_discovery(
Expand Down Expand Up @@ -375,6 +401,25 @@ void StatisticsParticipantListener::on_data_writer_discovery(
break;
}
}
// Create IDL representation of the discovered type
// Get remote type information
xtypes::TypeObject remote_type_object;
if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
info.type_information.type_information.complete().typeid_with_size().type_id(),
remote_type_object))
{
// Error
return;
}

// Build remotely discovered type
DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
remote_type_object)->build();

// Serialize DynamicType into its IDL representation
std::stringstream idl;
idl_serialize(remote_type, idl);
discovery_info.type_idl = idl.str();
JesusPoderoso marked this conversation as resolved.
Show resolved Hide resolved

entity_queue_->push(timestamp, discovery_info);

Expand Down
5 changes: 5 additions & 0 deletions test/mock/database/database/database/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class Database
MOCK_METHOD2(is_topic_in_database, bool(
const std::string& topic_type,
const EntityId& topic_id));
MOCK_METHOD1(is_type_in_database, bool(
const std::string& type_name));
MOCK_METHOD2(insert_new_type_idl, void(
const std::string& type_name,
const std::string& type_idl));

MOCK_METHOD4(insert_new_topic, EntityId(
const std::string& name,
Expand Down
Loading