Skip to content

Commit 1a739ff

Browse files
Allow creation of built-in content filters with different type name (#5867) (#5874)
* Allow creation of built-in content filters with different type name (#5867) * Refs #23265. Add unit test. Signed-off-by: Miguel Company <[email protected]> * Refs #23265. Add blackbox test. Signed-off-by: Miguel Company <[email protected]> * Refs #23265. Use type identifiers when creating DDS filter object. Signed-off-by: Miguel Company <[email protected]> * Refs #23265. Refactor for readability. Signed-off-by: Miguel Company <[email protected]> * Refs #23265. Apply review suggestion. Signed-off-by: Miguel Company <[email protected]> --------- Signed-off-by: Miguel Company <[email protected]> (cherry picked from commit 92260c2) # Conflicts: # test/blackbox/common/DDSBlackboxTestsContentFilter.cpp * Fix conflicts Signed-off-by: Miguel Company <[email protected]> * Fix linters Signed-off-by: Miguel Company <[email protected]> --------- Signed-off-by: Miguel Company <[email protected]> Co-authored-by: Miguel Company <[email protected]>
1 parent cd7ca97 commit 1a739ff

File tree

3 files changed

+96
-13
lines changed

3 files changed

+96
-13
lines changed

src/cpp/fastdds/topic/DDSSQLFilter/DDSFilterFactory.cpp

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,42 @@ DDSFilterFactory::~DDSFilterFactory()
456456
pool.clear();
457457
}
458458

459+
static std::shared_ptr<xtypes::TypeObject> get_complete_type_object(
460+
const char* type_name,
461+
const TopicDataType* data_type)
462+
{
463+
ReturnCode_t ret;
464+
465+
// Try to get the complete TypeObject from the type name
466+
std::shared_ptr<xtypes::TypeObjectPair> type_objects = std::make_shared<xtypes::TypeObjectPair>();
467+
ret = DomainParticipantFactory::get_instance()->type_object_registry().get_type_objects(
468+
type_name, *type_objects);
469+
if (RETCODE_OK == ret)
470+
{
471+
return std::make_shared<xtypes::TypeObject>(type_objects->complete_type_object);
472+
}
473+
474+
// If not found, try to get the complete TypeObject from the type identifier
475+
xtypes::TypeObject complete_type_object;
476+
if (xtypes::EK_COMPLETE == data_type->type_identifiers().type_identifier1()._d())
477+
{
478+
ret = DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
479+
data_type->type_identifiers().type_identifier1(), complete_type_object);
480+
}
481+
else if (xtypes::EK_COMPLETE == data_type->type_identifiers().type_identifier2()._d())
482+
{
483+
ret = DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
484+
data_type->type_identifiers().type_identifier2(), complete_type_object);
485+
}
486+
487+
if (RETCODE_OK == ret)
488+
{
489+
return std::make_shared<xtypes::TypeObject>(complete_type_object);
490+
}
491+
492+
return nullptr;
493+
}
494+
459495
ReturnCode_t DDSFilterFactory::create_content_filter(
460496
const char* filter_class_name,
461497
const char* type_name,
@@ -464,8 +500,6 @@ ReturnCode_t DDSFilterFactory::create_content_filter(
464500
const IContentFilterFactory::ParameterSeq& filter_parameters,
465501
IContentFilter*& filter_instance)
466502
{
467-
static_cast<void>(data_type);
468-
469503
ReturnCode_t ret = RETCODE_UNSUPPORTED;
470504

471505
if (nullptr == filter_expression)
@@ -522,22 +556,19 @@ ReturnCode_t DDSFilterFactory::create_content_filter(
522556
}
523557
else
524558
{
525-
std::shared_ptr<xtypes::TypeObjectPair> type_objects = std::make_shared<xtypes::TypeObjectPair>();
526-
ret = DomainParticipantFactory::get_instance()->type_object_registry().get_type_objects(
527-
type_name, *type_objects);
528-
if (RETCODE_OK != ret)
559+
std::shared_ptr<xtypes::TypeObject> type_object = get_complete_type_object(type_name, data_type);
560+
561+
if (!type_object)
529562
{
530563
EPROSIMA_LOG_ERROR(DDSSQLFILTER, "No TypeObject found for type " << type_name);
531564
}
532565
else
533566
{
534-
auto node =
535-
parser::parse_filter_expression(filter_expression,
536-
std::make_shared<xtypes::TypeObject>(type_objects->complete_type_object));
567+
auto node = parser::parse_filter_expression(filter_expression, type_object);
537568
if (node)
538569
{
539570
DynamicType::_ref_type dyn_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
540-
type_objects->complete_type_object)->build();
571+
*type_object)->build();
541572
if (dyn_type)
542573
{
543574
DDSFilterExpression* expr = get_expression();
@@ -548,8 +579,7 @@ ReturnCode_t DDSFilterFactory::create_content_filter(
548579
{
549580
expr->parameters.emplace_back();
550581
}
551-
ExpressionParsingState state{ std::make_shared<xtypes::TypeObject>(
552-
type_objects->complete_type_object),
582+
ExpressionParsingState state{ std::make_shared<xtypes::TypeObject>(*type_object),
553583
filter_parameters, expr };
554584
ret = convert_tree<DDSFilterCondition>(state, expr->root, *(node->children[0]));
555585
if (RETCODE_OK == ret)

test/blackbox/common/DDSBlackboxTestsContentFilter.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ class DDSContentFilter : public testing::TestWithParam<communication_type>
282282
{
283283
std::this_thread::sleep_for(std::chrono::milliseconds(100));
284284
reader->get_subscription_matched_status(status);
285-
} while (status.current_count < 1);
285+
}
286+
while (status.current_count < 1);
286287
}
287288

288289
return reader;
@@ -708,6 +709,36 @@ TEST(DDSContentFilter, OnlyFilterAliveChanges)
708709
ASSERT_EQ(reader.get_sample_lost_status().total_count, 0);
709710
}
710711

712+
/*
713+
* Regression test for https://eprosima.easyredmine.com/issues/23265
714+
*
715+
* This test checks that a DDSSQL content filter can be created with a type name that is different from the one
716+
* in the generated type support.
717+
*/
718+
TEST(DDSContentFilter, filter_other_type_name)
719+
{
720+
using namespace eprosima::fastdds;
721+
722+
// Create a DomainParticipant
723+
DomainParticipant* participant =
724+
dds::DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
725+
ASSERT_NE(participant, nullptr);
726+
727+
// Create a ContentFilteredTopic with a different type name
728+
dds::TypeSupport type_support(new HelloWorldPubSubType());
729+
ASSERT_EQ(type_support.register_type(participant, "CustomType"), RETCODE_OK);
730+
dds::Topic* topic = participant->create_topic(
731+
"TestTopic", "CustomType", TOPIC_QOS_DEFAULT);
732+
ASSERT_NE(topic, nullptr);
733+
dds::ContentFilteredTopic* filtered_topic = participant->create_contentfilteredtopic(
734+
"FilteredTopic", topic, "index <= %0", { "6" });
735+
ASSERT_NE(filtered_topic, nullptr);
736+
737+
// Delete all entities
738+
ASSERT_EQ(participant->delete_contained_entities(), RETCODE_OK);
739+
ASSERT_EQ(dds::DomainParticipantFactory::get_instance()->delete_participant(participant), RETCODE_OK);
740+
}
741+
711742
#ifdef INSTANTIATE_TEST_SUITE_P
712743
#define GTEST_INSTANTIATE_TEST_MACRO(x, y, z, w) INSTANTIATE_TEST_SUITE_P(x, y, z, w)
713744
#else

test/unittest/dds/topic/DDSSQLFilter/DDSSQLFilterTests.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,28 @@ TEST_F(DDSSQLFilterTests, type_compatibility_compare_operand_op_operand)
559559
}
560560
}
561561

562+
/*
563+
* Regression test for https://eprosima.easyredmine.com/issues/23265
564+
*
565+
* This test checks that a DDSSQL content filter can be created with a type name that is different from the one
566+
* used to register the type object representation.
567+
*/
568+
TEST_F(DDSSQLFilterTests, different_type_name)
569+
{
570+
ContentFilterTestTypePubSubType type;
571+
type.register_type_object_representation();
572+
573+
IContentFilter* filter_instance = nullptr;
574+
DDSFilterFactory factory;
575+
StackAllocatedSequence<const char*, 10> params;
576+
577+
EXPECT_EQ(factory.create_content_filter("DDSSQL", "MyCustomType", &type,
578+
"uint16_field = 3", params, filter_instance), RETCODE_OK);
579+
580+
EXPECT_EQ(RETCODE_OK,
581+
factory.delete_content_filter("DDSSQL", filter_instance));
582+
}
583+
562584
/**
563585
* Singleton that holds the serialized payloads to be evaluated
564586
*/

0 commit comments

Comments
 (0)