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 <[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:
#	include/fastdds/rtps/flowcontrol/FlowControllerDescriptor.hpp
#	resources/xsd/fastRTPS_profiles.xsd
#	test/unittest/dds/profiles/test_xml_profiles.xml
#	test/unittest/dds/profiles/test_xml_profiles_for_string.xml
#	test/unittest/xmlparser/XMLParserTests.cpp
#	test/unittest/xmlparser/XMLProfileParserTests.cpp
#	test/unittest/xmlparser/test_xml_profile.xml
#	test/unittest/xmlparser/test_xml_profile_env_var.xml
#	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 #21244: Solve conflicts and remove threadsettings from flow_controller_descriptor

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 Jun 27, 2024
1 parent 7a7172a commit 274732e
Show file tree
Hide file tree
Showing 20 changed files with 1,319 additions and 10 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 @@ -496,6 +507,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 @@ -615,6 +631,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 @@ -114,6 +114,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 @@ -257,6 +258,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
39 changes: 35 additions & 4 deletions resources/xsd/fastRTPS_profiles.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@
<xs:restriction base="xs:unsignedShort"/>
</xs:simpleType>

<xs:simpleType name="octetType">
<xs:restriction base="xs:unsignedByte"/>
</xs:simpleType>

<xs:simpleType name="boolType">
<xs:restriction base="xs:boolean"/> <!-- {true, false} -->
</xs:simpleType>
Expand Down Expand Up @@ -616,6 +612,7 @@
<xs:complexType name="publishModeQosPolicyType">
<xs:all>
<xs:element name="kind" type="publishModeQosKindType"/>
<xs:element name="flow_controller_name" type="string" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>

Expand All @@ -626,6 +623,39 @@
</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]-->
<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>

<!--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>

<xs:complexType name="domainIdVectorType">
<xs:sequence>
<xs:element name="domainId" type="uint16Type" maxOccurs="unbounded"/>
Expand Down Expand Up @@ -736,6 +766,7 @@
</xs:element>
<xs:element name="propertiesPolicy" type="propertyPolicyType" minOccurs="0"/>
<xs:element name="name" type="stringType" minOccurs="0"/>
<xs:element name="flow_controller_descriptor_list" type="flowControllerDescriptorListType" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>

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 @@ -679,7 +679,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 @@ -26,6 +26,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 @@ -754,6 +757,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 @@ -2480,6 +2625,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
{
logError(XMLPARSER, "Invalid element found into 'publishModeQosPolicyType'. Name: " << name);
Expand Down
18 changes: 18 additions & 0 deletions src/cpp/rtps/xmlparser/XMLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1794,6 +1794,7 @@ XMLP_ret XMLParser::fillDataNode(
<xs:element name="userData" type="octetVectorType" minOccurs="0"/>
<xs:element name="participantID" type="int32Type" minOccurs="0"/>
<xs:element name="throughputController" type="throughputControllerType" minOccurs="0"/>
<xs:element name="flow_controller_descriptors" type="flowControllerDescriptorsType" minOccurs="0"/>
<xs:element name="userTransports" type="stringListType" minOccurs="0"/>
<xs:element name="useBuiltinTransports" type="boolType" minOccurs="0"/>
<xs:element name="propertiesPolicy" type="propertyPolicyType" minOccurs="0"/>
Expand Down Expand Up @@ -1963,6 +1964,16 @@ XMLP_ret XMLParser::fillDataNode(
}
logWarning(XML_PARSER, THROUGHPUT_CONT << " XML tag is deprecated");
}
else if (strcmp(name, FLOW_CONTROLLER_DESCRIPTOR_LIST) == 0)
{
// flow_controller_descriptors
if (XMLP_ret::XML_OK !=
getXMLFlowControllerDescriptorList(p_aux0,
participant_node.get()->rtps.flow_controllers, ident))
{
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, USER_TRANS) == 0)
{
// userTransports
Expand Down Expand Up @@ -2287,6 +2298,13 @@ XMLP_ret XMLParser::fillDataNode(
return XMLP_ret::XML_OK;
}

XMLP_ret XMLParser::clear()
{
std::lock_guard<std::mutex> lock(collections_mtx_);
flow_controller_descriptor_names_.clear();
return XMLP_ret::XML_OK;
}

} // namespace xmlparser
} // namespace fastrtps
} // namespace eprosima
Loading

0 comments on commit 274732e

Please sign in to comment.