Skip to content

Commit

Permalink
Add XML configuration for FlowControllerDescriptor to 2.x (#4893) (#4907
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 <mariodominguez@eprosima.com>

* Refs #21136: Update fastRTPS_profiles.xsd

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

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

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21136: Update tests

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21136: versions.md

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21136: Linter

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21136: Apply rev

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

---------

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>
(cherry picked from commit e6044e0)

* 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 <mariodominguez@eprosima.com>

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

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21054: Apply Miguel suggestion

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21054: Apply second suggestion

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

---------

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #21244: Solve conflicts and remove threadsettings from flow_controller_descriptor

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

---------

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>
Co-authored-by: Mario Domínguez López <116071334+Mario-DL@users.noreply.github.com>
Co-authored-by: Mario Dominguez <mariodominguez@eprosima.com>
  • Loading branch information
3 people authored and MiguelCompany committed Sep 6, 2024
1 parent e004c2b commit 1646246
Show file tree
Hide file tree
Showing 19 changed files with 490 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef FASTDDS_RTPS_FLOWCONTROL_FLOWCONTROLLERDESCRIPTOR_HPP
#define FASTDDS_RTPS_FLOWCONTROL_FLOWCONTROLLERDESCRIPTOR_HPP


#include "FlowControllerConsts.hpp"
#include "FlowControllerSchedulerPolicy.hpp"

Expand All @@ -31,7 +32,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 @@ -27,6 +27,7 @@
#include <fastrtps/attributes/LibrarySettingsAttributes.h>

#include <map>
#include <mutex>
#include <string>

namespace tinyxml2 {
Expand Down Expand Up @@ -91,6 +92,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 @@ -160,6 +163,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 @@ -501,6 +512,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 @@ -620,6 +636,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
11 changes: 11 additions & 0 deletions include/fastrtps/xmlparser/XMLParserCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,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 @@ -261,6 +262,16 @@ 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* 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: 39 additions & 2 deletions resources/xsd/fastRTPS_profiles.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@
├ propertiesPolicy [0~1],
├ allocation [0~1],
├ userData [0~1],
└ prefix [0~1]-->
├ prefix [0~1],
└ flow_controller_descriptor_list [flowControllerDescriptorListType]-->
<!-- TODO: How to ensure that the userTransports identifiers exist in transport descriptors in the XML file? -->
<xs:complexType name="participantProfileType">
<xs:all>
Expand Down Expand Up @@ -160,6 +161,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:all>
</xs:complexType>
</xs:element>
Expand Down Expand Up @@ -1554,7 +1556,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 @@ -1565,6 +1568,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 @@ -1695,7 +1699,40 @@
</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>


<!--| PRIMITIVE TYPES DEFINITION |-->
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 @@ -749,7 +749,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
162 changes: 162 additions & 0 deletions src/cpp/rtps/xmlparser/XMLElementParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::xmlparser;

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

XMLP_ret XMLParser::getXMLParticipantAllocationAttributes(
tinyxml2::XMLElement* elem,
rtps::RTPSParticipantAllocationAttributes& allocation,
Expand Down Expand Up @@ -782,6 +785,148 @@ 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)
{
logError(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: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)
{
logError(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
const char* element = p_aux1->GetText();
if (nullptr == element)
{
logError(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())
{
logError(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)
{
const char* text = p_aux1->GetText();
if (nullptr == text)
{
logError(XMLPARSER, "Node '" << SCHEDULER << "' without content");
return XMLP_ret::XML_ERROR;
}

// scheduler - flowControllerSchedulerPolicy
if (!get_element_enum_value(text, 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))
{
logError(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, (uint16_t*)&flow_controller_descriptor->period_ms, ident))
{
return XMLP_ret::XML_ERROR;
}
}
else
{
logError(XMLPARSER,
"Invalid element found into 'flowControllerDescriptorType'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
}

if (!name_defined)
{
logError(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 @@ -2522,6 +2667,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_);
const char* element = p_aux0->GetText();
if (nullptr == element)
{
logError(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())
{
logError(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 1646246

Please sign in to comment.