diff --git a/include/fastdds/dds/domain/DomainParticipantFactory.hpp b/include/fastdds/dds/domain/DomainParticipantFactory.hpp index 09df4a26027..8aeda9675e5 100644 --- a/include/fastdds/dds/domain/DomainParticipantFactory.hpp +++ b/include/fastdds/dds/domain/DomainParticipantFactory.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,19 @@ class DomainParticipantFactory DomainParticipantListener* listener = nullptr, const StatusMask& mask = StatusMask::all()); + /** + * Create a Participant. + * + * @param extended_qos DomainParticipantExtendedQos Reference. + * @param listener DomainParticipantListener Pointer (default: nullptr) + * @param mask StatusMask Reference (default: all) + * @return DomainParticipant pointer. (nullptr if not created.) + */ + FASTDDS_EXPORTED_API DomainParticipant* create_participant( + const DomainParticipantExtendedQos& extended_qos, + DomainParticipantListener* listener = nullptr, + const StatusMask& mask = StatusMask::all()); + /** * Create a Participant with default domain id and qos. * @@ -216,6 +230,17 @@ class DomainParticipantFactory const std::string& profile_name, DomainParticipantQos& qos) const; + /** + * Fills the DomainParticipantExtendedQos with the values of the XML profile. + * + * @param profile_name DomainParticipant profile name. + * @param extended_qos DomainParticipantExtendedQos object where the domain and qos are returned. + * @return RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise. + */ + FASTDDS_EXPORTED_API ReturnCode_t get_participant_extended_qos_from_profile( + const std::string& profile_name, + DomainParticipantExtendedQos& extended_qos) const; + /** * Remove a Participant and all associated publishers and subscribers. * diff --git a/include/fastdds/dds/domain/qos/DomainParticipantExtendedQos.hpp b/include/fastdds/dds/domain/qos/DomainParticipantExtendedQos.hpp new file mode 100644 index 00000000000..012742eaf2f --- /dev/null +++ b/include/fastdds/dds/domain/qos/DomainParticipantExtendedQos.hpp @@ -0,0 +1,102 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file DomainParticipantExtendedQos.hpp + * + */ + +#ifndef _FASTDDS_PARTICIPANTEXTENDEDQOS_HPP_ +#define _FASTDDS_PARTICIPANTEXTENDEDQOS_HPP_ + +#include + +#include "DomainParticipantQos.hpp" + +namespace eprosima { +namespace fastdds { +namespace dds { + +class DomainParticipantExtendedQos : public DomainParticipantQos +{ +public: + + /** + * @brief Constructor + */ + FASTDDS_EXPORTED_API DomainParticipantExtendedQos() + { + } + + /** + * @brief Destructor + */ + FASTDDS_EXPORTED_API virtual ~DomainParticipantExtendedQos() + { + } + + DomainParticipantExtendedQos& operator=( + const DomainParticipantQos& qos) + { + static_cast(*this) = qos; + + return *this; + } + + bool operator ==( + const DomainParticipantExtendedQos& b) const + { + return (this->domainId_ == b.domainId()) && + (DomainParticipantQos::operator==(b)); + } + + bool operator ==( + const DomainParticipantQos& b) const override + { + return (DomainParticipantQos::operator==(b)); + } + + /** + * Getter for domainId + * + * @return domainId reference + */ + const uint32_t& domainId() const + { + return domainId_; + } + + /** + * Getter for domainId + * + * @return domainId reference + */ + uint32_t& domainId() + { + return domainId_; + } + +private: + + //! DomainId to be used by the associated RTPSParticipant (default: 0) + uint32_t domainId_ = 0; + +}; + + +} /* namespace dds */ +} /* namespace fastdds */ +} /* namespace eprosima */ + +#endif /* _FASTDDS_PARTICIPANTEXTENDEDQOS_HPP_ */ diff --git a/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp b/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp index 9fdb758501a..00ceb970ebc 100644 --- a/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp +++ b/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp @@ -42,6 +42,8 @@ class DomainParticipantQos { public: + friend class DomainParticipantExtendedQos; + /*! * User defined flow controllers to use alongside. * @@ -73,7 +75,7 @@ class DomainParticipantQos { } - bool operator ==( + virtual bool operator ==( const DomainParticipantQos& b) const { return (this->user_data_ == b.user_data()) && diff --git a/src/cpp/fastdds/domain/DomainParticipantFactory.cpp b/src/cpp/fastdds/domain/DomainParticipantFactory.cpp index ef3850c4bad..c27d48c4673 100644 --- a/src/cpp/fastdds/domain/DomainParticipantFactory.cpp +++ b/src/cpp/fastdds/domain/DomainParticipantFactory.cpp @@ -205,6 +205,14 @@ DomainParticipant* DomainParticipantFactory::create_participant( return dom_part; } +DomainParticipant* DomainParticipantFactory::create_participant( + const DomainParticipantExtendedQos& extended_qos, + DomainParticipantListener* listener, + const StatusMask& mask) +{ + return create_participant(extended_qos.domainId(), extended_qos, listener, mask); +} + DomainParticipant* DomainParticipantFactory::create_participant_with_default_profile() { return create_participant_with_default_profile(nullptr, StatusMask::none()); @@ -335,6 +343,20 @@ ReturnCode_t DomainParticipantFactory::get_participant_qos_from_profile( return RETCODE_BAD_PARAMETER; } +ReturnCode_t DomainParticipantFactory::get_participant_extended_qos_from_profile( + const std::string& profile_name, + DomainParticipantExtendedQos& extended_qos) const +{ + ParticipantAttributes attr; + if (XMLP_ret::XML_OK == XMLProfileManager::fillParticipantAttributes(profile_name, attr, false)) + { + utils::set_extended_qos_from_attributes(extended_qos, attr); + return RETCODE_OK; + } + + return RETCODE_BAD_PARAMETER; +} + ReturnCode_t DomainParticipantFactory::load_profiles() { // NOTE: This could be done with a bool atomic to avoid taking the mutex in most cases, however the use of diff --git a/src/cpp/fastdds/utils/QosConverters.cpp b/src/cpp/fastdds/utils/QosConverters.cpp index a72537c23b8..550cee62521 100644 --- a/src/cpp/fastdds/utils/QosConverters.cpp +++ b/src/cpp/fastdds/utils/QosConverters.cpp @@ -183,6 +183,14 @@ void set_qos_from_attributes( qos.properties().binary_properties() = attr.properties.binary_properties(); } +void set_extended_qos_from_attributes( + DomainParticipantExtendedQos& extended_qos, + const eprosima::fastdds::ParticipantAttributes& attr) +{ + extended_qos.domainId() = attr.domainId; + set_qos_from_attributes(extended_qos, attr.rtps); +} + void set_attributes_from_qos( fastrtps::rtps::RTPSParticipantAttributes& attr, const DomainParticipantQos& qos) @@ -216,6 +224,14 @@ void set_attributes_from_qos( #endif // if HAVE_SECURITY } +void set_attributes_from_extended_qos( + eprosima::fastdds::ParticipantAttributes& attr, + const DomainParticipantExtendedQos& extended_qos) +{ + attr.domainId = extended_qos.domainId(); + set_attributes_from_qos(attr.rtps, extended_qos); +} + void set_qos_from_attributes( TopicQos& qos, const TopicAttributes& attr) diff --git a/src/cpp/fastdds/utils/QosConverters.hpp b/src/cpp/fastdds/utils/QosConverters.hpp index 4e554775c60..c8f76f0b3dc 100644 --- a/src/cpp/fastdds/utils/QosConverters.hpp +++ b/src/cpp/fastdds/utils/QosConverters.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include +#include #include #include #include @@ -79,6 +81,24 @@ void set_qos_from_attributes( DomainParticipantQos& qos, const eprosima::fastrtps::rtps::RTPSParticipantAttributes& attr); +/** + * @brief Fill DomainParticipantExtendedQos from a given attributes ParticipantAttributes object + * + * For the case of the non-binary properties, instead of the ParticipantAttributes overriding the + * property list in the DomainParticipantExtendedQos, a merge is performed in the following manner: + * + * - If any property from the ParticipantAttributes is not in the DomainParticipantExtendedQos, then it is appended + * to the DomainParticipantExtendedQos. + * - If any property from the ParticipantAttributes property is also in the DomainParticipantExtendedQos, then the + * value in the DomainParticipantExtendedQos is overridden with that of the ParticipantAttributes. + * + * @param[in, out] extended_qos The DomainParticipantExtendedQos to set + * @param[in] attr The ParticipantAttributes from which the @c extended_qos is set. + */ +void set_extended_qos_from_attributes( + DomainParticipantExtendedQos& extended_qos, + const eprosima::fastdds::ParticipantAttributes& attr); + /** * Obtains the RTPSParticipantAttributes from the DomainParticipantQos provided. * @@ -89,6 +109,16 @@ void set_attributes_from_qos( fastrtps::rtps::RTPSParticipantAttributes& attr, const DomainParticipantQos& qos); +/** + * Obtains the ParticipantAttributes from the DomainParticipantExtendedQos provided. + * + * @param[out] attr Pointer to the attributes from which to obtain data + * @param[in] extended_qos Pointer to the QoS to write on + */ +void set_attributes_from_extended_qos( + eprosima::fastdds::ParticipantAttributes& attr, + const DomainParticipantExtendedQos& extended_qos); + /** * Obtains the TopicQos from the TopicAttributes provided. * diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp index 6ad7ede6372..f4b5d28dbb7 100644 --- a/test/unittest/dds/participant/ParticipantTests.cpp +++ b/test/unittest/dds/participant/ParticipantTests.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -467,7 +468,20 @@ TEST(ParticipantTests, CreateDomainParticipant) EXPECT_EQ(participant->get_listener(), nullptr); ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant(participant) == RETCODE_OK); +} + +TEST(ParticipantTests, CreateDomainParticipantWithExtendedQos) +{ + DomainParticipantExtendedQos extended_qos; + + DomainParticipant* participant = + DomainParticipantFactory::get_instance()->create_participant( + extended_qos); + ASSERT_NE(participant, nullptr); + EXPECT_EQ(participant->get_listener(), nullptr); + + ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant(participant) == RETCODE_OK); } /** @@ -499,7 +513,7 @@ void check_equivalent_qos( ASSERT_EQ(qos_1.flow_controllers(), qos_2.flow_controllers()); } -void check_participant_with_profile ( +void check_participant_with_profile( DomainParticipant* participant, const std::string& profile_name) { @@ -512,6 +526,29 @@ void check_participant_with_profile ( check_equivalent_qos(qos, profile_qos); } +void check_equivalent_extended_qos( + const DomainParticipantExtendedQos& extended_qos_1, + const DomainParticipantExtendedQos& extended_qos_2) +{ + ASSERT_EQ(extended_qos_1.domainId(), extended_qos_2.domainId()); + check_equivalent_qos(extended_qos_1, extended_qos_2); +} + +void check_participant_extended_qos_from_profile( + DomainParticipant* participant, + const std::string& profile_name) +{ + DomainParticipantExtendedQos extended_qos; + + extended_qos = participant->get_qos(); + extended_qos.domainId() = participant->get_domain_id(); + + DomainParticipantExtendedQos profile_extended_qos; + EXPECT_EQ(DomainParticipantFactory::get_instance()->get_participant_extended_qos_from_profile(profile_name, profile_extended_qos), + RETCODE_OK); + check_equivalent_extended_qos(extended_qos, profile_extended_qos); +} + /** * This test checks two different things depending on whether FASTDDS_STATISTICS is defined when compiling the test: * @@ -571,6 +608,41 @@ TEST(ParticipantTests, CreateDomainParticipantWithProfile) ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant(participant) == RETCODE_OK); } +TEST(ParticipantTests, CreateDomainParticipantWithExtendedQosFromProfile) +{ + DomainParticipantFactory::get_instance()->load_XML_profiles_file("test_xml_profile.xml"); + uint32_t domain_id = 123u; // This is the domain ID set in the default profile above + + // Test create_participant_with_profile using the default profile + DomainParticipant* default_participant = + DomainParticipantFactory::get_instance()->create_participant_with_profile("test_default_participant_profile"); + ASSERT_NE(default_participant, nullptr); + ASSERT_EQ(default_participant->get_domain_id(), domain_id); //Keep the DID given to the method, not the one on the profile + check_participant_extended_qos_from_profile(default_participant, "test_default_participant_profile"); + ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant( + default_participant) == RETCODE_OK); + + // Test create_participant_with_profile using "test_participant_profile" + uint32_t did = 123u; // This is the domain ID set in the "test_participant_profile" + + DomainParticipant* participant = + DomainParticipantFactory::get_instance()->create_participant_with_profile("test_participant_profile"); + ASSERT_NE(participant, nullptr); + ASSERT_EQ(participant->get_domain_id(), did); //Keep the DID given to the method, not the one on the profile + check_participant_extended_qos_from_profile(participant, "test_participant_profile"); + ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant(participant) == RETCODE_OK); + + // Test get_participant_extended_qos_from_profile and create_participant with that extended_qos + DomainParticipantExtendedQos extended_qos; + ASSERT_TRUE(DomainParticipantFactory::get_instance()->get_participant_extended_qos_from_profile( + "test_participant_profile", extended_qos) == RETCODE_OK); + + DomainParticipant* new_participant = + DomainParticipantFactory::get_instance()->create_participant(extended_qos); + check_participant_extended_qos_from_profile(new_participant, "test_participant_profile"); + ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant(new_participant) == RETCODE_OK); +} + TEST(ParticipantTests, CreateDomainParticipantWithDefaultProfile) { uint32_t domain_id = 123u; // This is the domain ID set in the default profile above