Skip to content

Commit

Permalink
Add XML configuration for FlowControllerDescriptor to 2.x (#4893) (#4905
Browse files Browse the repository at this point in the history
)

* Add XML configuration for FlowControllerDescriptor to 2.x (#4893)

* Refs #21136: Replace const char* with string

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21136: Update fastRTPS_profiles.xsd

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21136: Implement flow controller descriptor list in XML related source files

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21136: Update tests

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21136: versions.md

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21136: Linter

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21136: Apply rev

Signed-off-by: Mario Dominguez <[email protected]>

---------

Signed-off-by: Mario Dominguez <[email protected]>
(cherry picked from commit e6044e0)

# Conflicts:
#	test/unittest/xmlparser/XMLProfileParserTests.cpp
#	versions.md

* Bugfix: Revert XML Flow controller names to `const char*` (#4911)

* Refs #21054: Revert to const char* for flow controller names

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21054: Handle flow controller names in a XMLParser collection

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21054: Apply Miguel suggestion

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21054: Apply second suggestion

Signed-off-by: Mario Dominguez <[email protected]>

---------

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #21310: Fix building

Signed-off-by: Mario Dominguez <[email protected]>

---------

Signed-off-by: Mario Dominguez <[email protected]>
Co-authored-by: Mario Domínguez López <[email protected]>
Co-authored-by: Mario Dominguez <[email protected]>
  • Loading branch information
3 people authored Jul 11, 2024
1 parent 7abaad5 commit 212d05a
Show file tree
Hide file tree
Showing 20 changed files with 579 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace rtps {
struct FlowControllerDescriptor
{
//! Name of the flow controller.
const char* name = nullptr;
const char* name = FASTDDS_FLOW_CONTROLLER_DEFAULT;

//! Scheduler policy used by the flow controller.
//!
Expand Down
21 changes: 21 additions & 0 deletions include/fastrtps/xmlparser/XMLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <cstdio>
#include <map>
#include <memory>
#include <mutex>
#include <string>

#include <fastdds/dds/core/policy/QosPolicies.hpp>
Expand Down Expand Up @@ -103,6 +104,8 @@ class XMLParser

public:

using FlowControllerDescriptorList = std::vector<std::shared_ptr<fastdds::rtps::FlowControllerDescriptor>>;

/**
* Load the default XML file.
* @return XMLP_ret::XML_OK on success, XMLP_ret::XML_ERROR in other case.
Expand Down Expand Up @@ -172,6 +175,14 @@ class XMLParser
RTPS_DllAPI static XMLP_ret loadXMLDynamicTypes(
tinyxml2::XMLElement& types);


/**
* Clears the private static collections.
*
* @return XMLP_ret::XML_OK on success, XMLP_ret::XML_ERROR in other case.
*/
RTPS_DllAPI static XMLP_ret clear();

protected:

RTPS_DllAPI static XMLP_ret parseXML(
Expand Down Expand Up @@ -536,6 +547,11 @@ class XMLParser
rtps::ThroughputControllerDescriptor& throughputController,
uint8_t ident);

RTPS_DllAPI static XMLP_ret getXMLFlowControllerDescriptorList(
tinyxml2::XMLElement* elem,
FlowControllerDescriptorList& flow_controller_descriptor_list,
uint8_t ident);

RTPS_DllAPI static XMLP_ret getXMLPortParameters(
tinyxml2::XMLElement* elem,
rtps::PortParameters& port,
Expand Down Expand Up @@ -686,6 +702,11 @@ class XMLParser
tinyxml2::XMLElement* elem,
eprosima::fastdds::rtps::BuiltinTransports* bt,
uint8_t ident);

private:

static std::mutex collections_mtx_;
static std::set<std::string> flow_controller_descriptor_names_;
};

} // namespace xmlparser
Expand Down
12 changes: 12 additions & 0 deletions include/fastrtps/xmlparser/XMLParserCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ extern const char* PART_ID;
extern const char* IP4_TO_SEND;
extern const char* IP6_TO_SEND;
extern const char* THROUGHPUT_CONT;
extern const char* FLOW_CONTROLLER_DESCRIPTOR_LIST;
extern const char* USER_TRANS;
extern const char* USE_BUILTIN_TRANS;
extern const char* BUILTIN_TRANS;
Expand Down Expand Up @@ -287,6 +288,17 @@ extern const char* ALLOCATED_SAMPLES;
extern const char* EXTRA_SAMPLES;
extern const char* BYTES_PER_SECOND;
extern const char* PERIOD_MILLISECS;
extern const char* FLOW_CONTROLLER_DESCRIPTOR;
extern const char* SCHEDULER;
extern const char* SENDER_THREAD;
extern const char* MAX_BYTES_PER_PERIOD;
extern const char* PERIOD_MS;
extern const char* FLOW_CONTROLLER_NAME;
extern const char* FIFO;
extern const char* HIGH_PRIORITY;
extern const char* ROUND_ROBIN;
extern const char* PRIORITY_WITH_RESERVATION;
extern const char* FLOW_CONTROLLER_NAME;
extern const char* PORT_BASE;
extern const char* DOMAIN_ID_GAIN;
extern const char* PARTICIPANT_ID_GAIN;
Expand Down
41 changes: 40 additions & 1 deletion resources/xsd/fastRTPS_profiles.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
├ allocation [0~1],
├ userData [0~1],
├ prefix [0~1],
├ flow_controller_descriptor_list [flowControllerDescriptorListType],
├ builtin_controllers_sender_thread [threadSettingsType],
├ timed_events_thread [threadSettingsType],
├ discovery_server_thread [threadSettingsType],
Expand Down Expand Up @@ -182,6 +183,7 @@
<xs:element name="allocation" type="rtpsParticipantAllocationAttributesType" minOccurs="0" maxOccurs="1"/>
<xs:element name="userData" type="octectVectorQosPolicyType" minOccurs="0" maxOccurs="1"/>
<xs:element name="prefix" type="prefixType" minOccurs="0" maxOccurs="1"/>
<xs:element name="flow_controller_descriptor_list" type="flowControllerDescriptorListType" minOccurs="0" maxOccurs="1"/>
<xs:element name="builtin_controllers_sender_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
<xs:element name="timed_events_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
<xs:element name="discovery_server_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
Expand Down Expand Up @@ -1616,7 +1618,8 @@
</xs:complexType>

<!--QoS Publish Mode:
└ kind [string] ("ASYNCHRONOUS", "SYNCHRONOUS") -->
├ kind [string] ("ASYNCHRONOUS", "SYNCHRONOUS")
└ flow_controller_name [string] -->
<xs:complexType name="publishModeQosPolicyType">
<xs:all>
<xs:element name="kind" minOccurs="0" maxOccurs="1">
Expand All @@ -1627,6 +1630,7 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="flow_controller_name" type="string" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>

Expand Down Expand Up @@ -1757,6 +1761,41 @@
</xs:all>
</xs:complexType>

<!--Flow Controller Descriptor List Type:
└ flow_controller_descriptor [1~*]-->
<xs:complexType name="flowControllerDescriptorListType">
<xs:sequence minOccurs="1" maxOccurs="unbounded"> <!-- multiple instances of the elements -->
<xs:element name="flow_controller_descriptor" type="flowControllerDescriptorType"/>
</xs:sequence>
</xs:complexType>

<!--Flow Controller Descriptor Type:
├ name [string] req,
├ scheduler [flowControllerSchedulerPolicy],
├ max_bytes_per_period [int32],
├ period_ms [uint64],
└ sender_thread [threadSettingsType]-->
<xs:complexType name="flowControllerDescriptorType">
<xs:all>
<xs:element name="name" type="string" minOccurs="1" maxOccurs="1"/>
<xs:element name="scheduler" type="flowControllerSchedulerPolicy" minOccurs="0" maxOccurs="1"/>
<xs:element name="max_bytes_per_period" type="int32" minOccurs="0" maxOccurs="1"/>
<xs:element name="period_ms" type="uint64" minOccurs="0" maxOccurs="1"/>
<xs:element name="sender_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>

<!--Flow Controller Scheduler Policy Type [string]:
("FIFO", "ROUND_ROBIN", "HIGH_PRIORITY", "PRIORITY_WITH_RESERVATION")-->
<xs:simpleType name="flowControllerSchedulerPolicy">
<xs:restriction base="xs:string">
<xs:enumeration value="FIFO" />
<xs:enumeration value="ROUND_ROBIN" />
<xs:enumeration value="HIGH_PRIORITY" />
<xs:enumeration value="PRIORITY_WITH_RESERVATION" />
</xs:restriction>
</xs:simpleType>

<!--Thread Settings Type:
| ╠ att. port [uint32]
|
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/rtps/participant/RTPSParticipantImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ bool RTPSParticipantImpl::create_writer(

GUID_t guid(m_guid.guidPrefix, entId);
fastdds::rtps::FlowController* flow_controller = nullptr;
const char* flow_controller_name = param.flow_controller_name;
std::string flow_controller_name = param.flow_controller_name;

// Support of old flow controller style.
if (param.throughputController.bytesPerPeriod != UINT32_MAX && param.throughputController.periodMillisecs != 0)
Expand Down
168 changes: 168 additions & 0 deletions src/cpp/rtps/xmlparser/XMLElementParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ namespace eprosima {
namespace fastrtps {
namespace xmlparser {

std::mutex XMLParser::collections_mtx_;
std::set<std::string> XMLParser::flow_controller_descriptor_names_;

using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastdds::xml::detail;

Expand Down Expand Up @@ -986,6 +989,154 @@ XMLP_ret XMLParser::getXMLThroughputController(
return XMLP_ret::XML_OK;
}

XMLP_ret XMLParser::getXMLFlowControllerDescriptorList(
tinyxml2::XMLElement* elem,
FlowControllerDescriptorList& flow_controller_descriptor_list,
uint8_t ident)
{
/*
<xs:complexType name="flowControllerDescriptorListType">
<xs:sequence>
<xs:element name="flow_controller_descriptor" type="flowControllerDescriptorType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
*/

tinyxml2::XMLElement* p_aux0 = nullptr;
p_aux0 = elem->FirstChildElement(FLOW_CONTROLLER_DESCRIPTOR);
if (nullptr == p_aux0)
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Node '" << elem->Value() << "' without content");
return XMLP_ret::XML_ERROR;
}

while (nullptr != p_aux0)
{
/*
<xs:complexType name="flowControllerDescriptorType">
<xs:all>
<xs:element name="name" type="string" minOccurs="1" maxOccurs="1"/>
<xs:element name="scheduler" type="flowControllerSchedulerPolicy" minOccurs="0" maxOccurs="1"/>
<xs:element name="max_bytes_per_period" type="int32" minOccurs="0" maxOccurs="1"/>
<xs:element name="period_ms" type="uint64" minOccurs="0" maxOccurs="1"/>
<xs:element name="sender_thread" type="threadSettingsType" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>
<xs:simpleType name="flowControllerSchedulerPolicy">
<xs:restriction base="xs:string">
<xs:enumeration value="FIFO" />
<xs:enumeration value="ROUND_ROBIN" />
<xs:enumeration value="HIGH_PRIORITY" />
<xs:enumeration value="PRIORITY_WITH_RESERVATION" />
</xs:restriction>
</xs:simpleType>
*/

tinyxml2::XMLElement* p_aux1;
bool name_defined = false;
std::set<std::string> tags_present;

auto flow_controller_descriptor = std::make_shared<fastdds::rtps::FlowControllerDescriptor>();

for (p_aux1 = p_aux0->FirstChildElement(); p_aux1 != NULL; p_aux1 = p_aux1->NextSiblingElement())
{
const char* name = p_aux1->Name();

if (tags_present.count(name) != 0)
{
EPROSIMA_LOG_ERROR(XMLPARSER,
"Duplicated element found in 'flowControllerDescriptorType'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
else
{
tags_present.emplace(name);
}

if (strcmp(name, NAME) == 0)
{
std::lock_guard<std::mutex> lock(collections_mtx_);
// name - stringType
std::string element = get_element_text(p_aux1);
if (element.empty())
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Node '" << NAME << "' without content");
return XMLP_ret::XML_ERROR;
}
auto element_inserted = flow_controller_descriptor_names_.insert(element);
if (element_inserted.first == flow_controller_descriptor_names_.end())
{
EPROSIMA_LOG_ERROR(XMLPARSER,
"Insertion error for flow controller node '" << FLOW_CONTROLLER_NAME << "'");
return XMLP_ret::XML_ERROR;
}
flow_controller_descriptor->name = element_inserted.first->c_str();
name_defined = true;
}
else if (strcmp(name, SCHEDULER) == 0)
{
std::string text = get_element_text(p_aux1);
if (text.empty())
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Node '" << SCHEDULER << "' without content");
return XMLP_ret::XML_ERROR;
}

// scheduler - flowControllerSchedulerPolicy
if (!get_element_enum_value(text.c_str(), flow_controller_descriptor->scheduler,
FIFO, fastdds::rtps::FlowControllerSchedulerPolicy::FIFO,
HIGH_PRIORITY, fastdds::rtps::FlowControllerSchedulerPolicy::HIGH_PRIORITY,
ROUND_ROBIN, fastdds::rtps::FlowControllerSchedulerPolicy::ROUND_ROBIN,
PRIORITY_WITH_RESERVATION,
fastdds::rtps::FlowControllerSchedulerPolicy::PRIORITY_WITH_RESERVATION))
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Node '" << SCHEDULER << "' with bad content");
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, MAX_BYTES_PER_PERIOD) == 0)
{
// max_bytes_per_period - int32Type
if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &flow_controller_descriptor->max_bytes_per_period, ident))
{
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, PERIOD_MS) == 0)
{
// period_ms - uint64Type
if (XMLP_ret::XML_OK != getXMLUint(p_aux1, &flow_controller_descriptor->period_ms, ident))
{
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, SENDER_THREAD) == 0)
{
// sender_thread - threadSettingsType
getXMLThreadSettings(*p_aux1, flow_controller_descriptor->sender_thread);
}
else
{
EPROSIMA_LOG_ERROR(XMLPARSER,
"Invalid element found into 'flowControllerDescriptorType'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
}

if (!name_defined)
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Flow Controller Descriptor requires a 'name'");
return XMLP_ret::XML_ERROR;
}

flow_controller_descriptor_list.push_back(flow_controller_descriptor);
p_aux0 = p_aux0->NextSiblingElement(FLOW_CONTROLLER_DESCRIPTOR);

}

return XMLP_ret::XML_OK;
}

XMLP_ret XMLParser::getXMLTopicAttributes(
tinyxml2::XMLElement* elem,
TopicAttributes& topic,
Expand Down Expand Up @@ -2697,6 +2848,23 @@ XMLP_ret XMLParser::getXMLPublishModeQos(
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, FLOW_CONTROLLER_NAME) == 0)
{
std::lock_guard<std::mutex> lock(collections_mtx_);
std::string element = get_element_text(p_aux0);
if (element.empty())
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Node '" << FLOW_CONTROLLER_NAME << "' without content");
return XMLP_ret::XML_ERROR;
}
auto element_inserted = flow_controller_descriptor_names_.insert(element);
if (element_inserted.first == flow_controller_descriptor_names_.end())
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Insertion error for node '" << FLOW_CONTROLLER_NAME << "'");
return XMLP_ret::XML_ERROR;
}
publishMode.flow_controller_name = element_inserted.first->c_str();
}
else
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Invalid element found into 'publishModeQosPolicyType'. Name: " << name);
Expand Down
Loading

0 comments on commit 212d05a

Please sign in to comment.