Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding content filter interfaces [13290] #2359

Merged
merged 21 commits into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a7c80f6
Adding content filter interfaces (#2286)
MiguelCompany Dec 10, 2021
b808ed2
Updating content filter interfaces (#2351)
MiguelCompany Dec 16, 2021
4f612f0
Refs 13290. Added new test to ParticipantTests.
MiguelCompany Dec 17, 2021
239698b
Refs 13290. Added negative tests for create/delete contentfilteredtopic
MiguelCompany Dec 17, 2021
5fe2495
Refs 13290. Added custom filter mock class.
MiguelCompany Dec 17, 2021
f3308f6
Refs 13290. Added negative tests for register_content_filter_factory.
MiguelCompany Dec 17, 2021
dbe34f2
Refs 13290. Check for nullptr on register_content_filter_factory.
MiguelCompany Dec 17, 2021
182666f
Refs 13290. Added negative tests for lookup_content_filter_factory.
MiguelCompany Dec 17, 2021
dcf5ed7
Refs 13290. Added negative tests for unregister_content_filter_factory.
MiguelCompany Dec 17, 2021
1a2fe58
Refs 13290. Added tests for custom filter factory registration.
MiguelCompany Dec 17, 2021
7788306
Refs 13290. Added tests for custom filtered topic creation.
MiguelCompany Dec 17, 2021
0dd1428
Refs 13290. Fixed generation of filter_parameters.
MiguelCompany Dec 17, 2021
83bdf7f
Refs 13290. Added more checks on tests.
MiguelCompany Dec 20, 2021
2515388
Refs 13290. Added second participant and topic.
MiguelCompany Dec 20, 2021
5daaec6
Refs 13290. Added cross-participant checks.
MiguelCompany Dec 20, 2021
bcfb07d
Refs 13290. Added lookup_topicdescription checks.
MiguelCompany Dec 20, 2021
d73209b
Refs 13290. Avoid deleting the same entity twice.
MiguelCompany Dec 20, 2021
ffc00ba
Refs 13290. No need to check participant (implicit check when not fou…
MiguelCompany Dec 20, 2021
cb95e98
Refs 13290. Fixed link issues on unit tests.
MiguelCompany Dec 20, 2021
11a2add
Refs 13290. Linters.
MiguelCompany Dec 20, 2021
2502a78
Refs 13290. Additional checks to ensure collection traversal.
MiguelCompany Dec 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 103 additions & 10 deletions include/fastdds/dds/domain/DomainParticipant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,26 @@
#ifndef _FASTDDS_DOMAIN_PARTICIPANT_HPP_
#define _FASTDDS_DOMAIN_PARTICIPANT_HPP_

#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/rtps/common/Time_t.h>
#include <fastrtps/types/TypeIdentifier.h>
#include <functional>
#include <string>
#include <utility>
#include <vector>

#include <fastdds/dds/builtin/topic/ParticipantBuiltinTopicData.hpp>
#include <fastdds/dds/builtin/topic/TopicBuiltinTopicData.hpp>
#include <fastdds/dds/core/status/StatusMask.hpp>
#include <fastdds/dds/core/Entity.hpp>
#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>
#include <fastdds/dds/topic/ContentFilteredTopic.hpp>
#include <fastdds/dds/topic/IContentFilterFactory.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/rtps/attributes/RTPSParticipantAttributes.h>
#include <fastdds/rtps/common/Guid.h>
#include <fastdds/rtps/common/SampleIdentity.h>
#include <fastdds/rtps/common/Time_t.h>
#include <fastrtps/types/TypesBase.h>


#include <utility>
#include <fastrtps/types/TypeIdentifier.h>

using eprosima::fastrtps::types::ReturnCode_t;

Expand Down Expand Up @@ -76,7 +79,6 @@ class SubscriberListener;
class TopicQos;

// Not implemented classes
class ContentFilteredTopic;
class MultiTopic;

/**
Expand Down Expand Up @@ -262,14 +264,40 @@ class DomainParticipant : public Entity
* @param related_topic Related Topic to being subscribed
* @param filter_expression Logic expression to create filter
* @param expression_parameters Parameters to filter content
* @return Pointer to the created ContentFilteredTopic, nullptr in error case
* @return Pointer to the created ContentFilteredTopic.
* @return nullptr if @c related_topic does not belong to this participant.
* @return nullptr if a topic with the specified @c name has already been created.
* @return nullptr if a filter cannot be created with the specified @c filter_expression and
* @c expression_parameters.
*/
RTPS_DllAPI ContentFilteredTopic* create_contentfilteredtopic(
const std::string& name,
const Topic* related_topic,
Topic* related_topic,
const std::string& filter_expression,
const std::vector<std::string>& expression_parameters);

/**
* Create a ContentFilteredTopic in this Participant using a custom filter.
* @param name Name of the ContentFilteredTopic
* @param related_topic Related Topic to being subscribed
* @param filter_expression Logic expression to create filter
* @param expression_parameters Parameters to filter content
* @param filter_class_name Name of the filter class to use
*
* @return Pointer to the created ContentFilteredTopic.
* @return nullptr if @c related_topic does not belong to this participant.
* @return nullptr if a topic with the specified @c name has already been created.
* @return nullptr if a filter cannot be created with the specified @c filter_expression and
* @c expression_parameters.
* @return nullptr if the specified @c filter_class_name has not been registered.
*/
RTPS_DllAPI ContentFilteredTopic* create_contentfilteredtopic(
const std::string& name,
Topic* related_topic,
const std::string& filter_expression,
const std::vector<std::string>& expression_parameters,
const char* filter_class_name);

/**
* Deletes an existing ContentFilteredTopic.
* @param a_contentfilteredtopic ContentFilteredTopic to be deleted
Expand Down Expand Up @@ -720,6 +748,71 @@ class DomainParticipant : public Entity
const std::string& type_name,
std::function<void(const std::string& name, const fastrtps::types::DynamicType_ptr type)>& callback);

/**
* Register a custom content filter factory, which can be used to create a ContentFilteredTopic.
*
* DDS specifies a SQL-like content filter to be used by content filtered topics.
* If this filter does not meet your filtering requirements, you can register a custom filter factory.
*
* To use a custom filter, a factory for it must be registered in the following places:
* - In any application that uses the custom filter factory to create a ContentFilteredTopic and the corresponding
* DataReader.
* - In each application that writes the data to the applications mentioned above.
*
* For example, suppose Application A on the subscription side creates a Topic named X and a ContentFilteredTopic
* named filteredX (and a corresponding DataReader), using a previously registered content filter factory, myFilterFactory.
* With only that, you will have filtering at the subscription side.
* If you also want to perform filtering in any application that publishes Topic X, then you also need to register
* the same definition of the ContentFilterFactory myFilterFactory in that application.
*
* Each @c filter_class_name can only be used to register a content filter factory once per DomainParticipant.
*
* @param filter_class_name Name of the filter class. Cannot be nullptr, must not exceed 255 characters, and must
* be unique within this DomainParticipant.
* @param filter_factory Factory of content filters to be registered. Cannot be nullptr.
*
* @return RETCODE_BAD_PARAMETER if any parameter is nullptr, or the filter_class_name exceeds 255 characters.
* @return RETCODE_PRECONDITION_NOT_MET if the filter_class_name has been already registered.
* @return RETCODE_PRECONDITION_NOT_MET if filter_class_name is FASTDDS_SQLFILTER_NAME.
* @return RETCODE_OK if the filter is correctly registered.
*/
RTPS_DllAPI ReturnCode_t register_content_filter_factory(
const char* filter_class_name,
IContentFilterFactory* const filter_factory);

/**
* Lookup a custom content filter factory previously registered with register_content_filter_factory.
*
* @param filter_class_name Name of the filter class. Cannot be nullptr.
*
* @return nullptr if the given filter_class_name has not been previously registered on this DomainParticipant.
* Otherwise, the content filter factory previously registered with the given filter_class_name.
*/
RTPS_DllAPI IContentFilterFactory* lookup_content_filter_factory(
const char* filter_class_name);

/**
* Unregister a custom content filter factory previously registered with register_content_filter_factory.
*
* A filter_class_name can be unregistered only if it has been previously registered to the DomainParticipant with
* register_content_filter_factory.
*
* The unregistration of filter is not allowed if there are any existing ContentFilteredTopic objects that are
* using the filter.
*
* If there is any existing discovered DataReader with the same filter_class_name, filtering on the writer side will be
* stopped, but this operation will not fail.
*
* @param filter_class_name Name of the filter class. Cannot be nullptr.
*
* @return RETCODE_BAD_PARAMETER if the filter_class_name is nullptr.
* @return RERCODE_PRECONDITION_NOT_MET if the filter_class_name has not been previously registered.
* @return RERCODE_PRECONDITION_NOT_MET if there is any ContentFilteredTopic referencing the filter.
* @return RETCODE_OK if the filter is correctly unregistered.
*/
RTPS_DllAPI ReturnCode_t unregister_content_filter_factory(
const char* filter_class_name);

/**
* @brief Check if the Participant has any Publisher, Subscriber or Topic
* @return true if any, false otherwise.
Expand Down
104 changes: 104 additions & 0 deletions include/fastdds/dds/topic/ContentFilteredTopic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2021 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 ContentFilteredTopic.hpp
*/

#ifndef _FASTDDS_DDS_TOPIC_CONTENTFILTEREDTOPIC_HPP_
#define _FASTDDS_DDS_TOPIC_CONTENTFILTEREDTOPIC_HPP_

#include <fastrtps/fastrtps_dll.h>
#include <fastdds/dds/topic/TopicDescription.hpp>
#include <fastdds/dds/topic/Topic.hpp>

#define FASTDDS_SQLFILTER_NAME eprosima::fastdds::dds::sqlfilter_name

using eprosima::fastrtps::types::ReturnCode_t;

namespace eprosima {
namespace fastdds {
namespace dds {

class DomainParticipant;
class DomainParticipantImpl;
class ContentFilteredTopicImpl;

constexpr const char* const sqlfilter_name = "DDSSQL";

/**
* Specialization of TopicDescription that allows for content-based subscriptions
* @ingroup FASTDDS_MODULE
*/
class ContentFilteredTopic : public TopicDescription
{
friend class DomainParticipantImpl;

private:

RTPS_DllAPI ContentFilteredTopic(
const std::string& name,
Topic* related_topic,
const std::string& filter_expression,
const std::vector<std::string>& expression_parameters);

public:

/**
* @brief Destructor
*/
RTPS_DllAPI virtual ~ContentFilteredTopic();

/**
* @brief Getter for the related topic.
* This operation returns the Topic associated with the ContentFilteredTopic.
* That is, the Topic specified when the ContentFilteredTopic was created.
*/
RTPS_DllAPI Topic* get_related_topic() const;

RTPS_DllAPI const std::string& get_filter_expression() const;

RTPS_DllAPI ReturnCode_t get_expression_parameters(
std::vector<std::string>& expression_parameters) const;

RTPS_DllAPI ReturnCode_t set_expression_parameters(
const std::vector<std::string>& expression_parameters);

RTPS_DllAPI ReturnCode_t set_filter_expression(
const std::string& filter_expression,
const std::vector<std::string>& expression_parameters);

/**
* @brief Getter for the DomainParticipant
* @return DomainParticipant pointer
*/
virtual DomainParticipant* get_participant() const override;

/**
* @brief Getter for the TopicDescriptionImpl
* @return pointer to TopicDescriptionImpl
*/
TopicDescriptionImpl* get_impl() const override;

protected:

ContentFilteredTopicImpl* impl_;

};

} // namespace dds
} // namespace fastdds
} // namespace eprosima

#endif // _FASTDDS_DDS_TOPIC_CONTENTFILTEREDTOPIC_HPP_
60 changes: 60 additions & 0 deletions include/fastdds/dds/topic/IContentFilter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2021 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 IContentFilter.hpp
*/

#ifndef _FASTDDS_DDS_TOPIC_ICONTENTFILTER_HPP_
#define _FASTDDS_DDS_TOPIC_ICONTENTFILTER_HPP_

#include <fastrtps/fastrtps_dll.h>

#include <fastdds/dds/core/LoanableTypedCollection.hpp>

#include <fastdds/rtps/common/Guid.h>
#include <fastdds/rtps/common/SampleIdentity.h>
#include <fastdds/rtps/common/SerializedPayload.h>

#include <fastrtps/types/TypesBase.h>
#include <fastrtps/types/TypeDescriptor.h>

namespace eprosima {
namespace fastdds {
namespace dds {

struct IContentFilter
{
using SerializedPayload = eprosima::fastrtps::rtps::SerializedPayload_t;
using GUID_t = fastrtps::rtps::GUID_t;

struct FilterSampleInfo
{
using SampleIdentity = eprosima::fastrtps::rtps::SampleIdentity;

SampleIdentity sample_identity;
SampleIdentity related_sample_identity;
};

virtual bool evaluate(
const SerializedPayload& payload,
const FilterSampleInfo& sample_info,
const GUID_t& reader_guid) const = 0;
};

} // namespace dds
} // namespace fastdds
} // namespace eprosima

#endif // _FASTDDS_DDS_TOPIC_ICONTENTFILTER_HPP_
57 changes: 57 additions & 0 deletions include/fastdds/dds/topic/IContentFilterFactory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2021 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 IContentFilter.hpp
*/

#ifndef _FASTDDS_DDS_TOPIC_ICONTENTFILTERFACTORY_HPP_
#define _FASTDDS_DDS_TOPIC_ICONTENTFILTERFACTORY_HPP_

#include <fastrtps/fastrtps_dll.h>

#include <fastdds/dds/core/LoanableTypedCollection.hpp>
#include <fastdds/dds/topic/IContentFilter.hpp>
#include <fastdds/dds/topic/TopicDataType.hpp>

#include <fastrtps/types/TypesBase.h>

namespace eprosima {
namespace fastdds {
namespace dds {

struct IContentFilterFactory
{
using ReturnCode_t = eprosima::fastrtps::types::ReturnCode_t;
using ParameterSeq = LoanableTypedCollection<const char*>;
using TypeDescriptor = eprosima::fastrtps::types::TypeDescriptor;

virtual ReturnCode_t create_content_filter(
const char* filter_class_name,
const char* type_name,
const TopicDataType* data_type,
const char* filter_expression,
const ParameterSeq& filter_parameters,
IContentFilter*& filter_instance) = 0;

virtual ReturnCode_t delete_content_filter(
const char* filter_class_name,
IContentFilter* filter_instance) = 0;
};

} // namespace dds
} // namespace fastdds
} // namespace eprosima

#endif // _FASTDDS_DDS_TOPIC_ICONTENTFILTERFACTORY_HPP_
3 changes: 2 additions & 1 deletion include/fastdds/dds/topic/TopicDataType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
#ifndef _FASTDDS_TOPICDATATYPE_HPP_
#define _FASTDDS_TOPICDATATYPE_HPP_

#include <string>
#include <functional>
#include <memory>
#include <string>

#include <fastdds/dds/core/policy/QosPolicies.hpp>
#include <fastdds/rtps/common/InstanceHandle.h>
Expand Down
Loading