Skip to content

Commit

Permalink
Add onlyForTopics and forbiddenTopics config option
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiasstarkwayve committed Jun 10, 2024
1 parent f724b4f commit 4f42a40
Show file tree
Hide file tree
Showing 13 changed files with 264 additions and 30 deletions.
36 changes: 30 additions & 6 deletions docs/manual/config/config_file_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ The default value is: ``default``
//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Attributes: :ref:`config<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@config]>`, :ref:`library<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@library]>`, :ref:`name<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@name]>`, :ref:`priority<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@priority]>`
Attributes: :ref:`config<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@config]>`, :ref:`forbiddenTopics<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@forbiddenTopics]>`, :ref:`library<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@library]>`, :ref:`name<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@name]>`, :ref:`onlyForTopics<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@onlyForTopics]>`, :ref:`priority<//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@priority]>`

This element defines a PSMX.

Expand All @@ -626,6 +626,18 @@ This attribute specifies any configuration data for the PSMX instance.This has n
The default value is: ``<empty>``


.. _`//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@forbiddenTopics]`:

//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@forbiddenTopics]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Text

A comma-separated list of topics that should never use this psmx.Mutually exclusive with onlyForTopics.

The default value is: ``<empty>``


.. _`//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@library]`:

//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@library]
Expand All @@ -650,6 +662,18 @@ This attribute specifies the name of the interface.
The default value is: ``<empty>``


.. _`//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@onlyForTopics]`:

//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@onlyForTopics]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Text

A comma-separated list of all the topics that should use this PSMX.This option can be used to restrict the PSMX to a selected list of topics.Mutually exclusive with forbiddenTopics.

The default value is: ``<empty>``


.. _`//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@priority]`:

//CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@priority]
Expand Down Expand Up @@ -2642,14 +2666,14 @@ The categorisation of tracing output is incomplete and hence most of the verbosi
The default value is: ``none``

..
generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d]
generated from ddsi_config.h[a6553d01e0d7a9c01fda217e68613a8ae1875883]
generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa]
generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536]
generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64]
generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc]
generated from ddsi__cfgelems.h[8c3942cd63352722dacc9df4db7cddae90a2cc13]
generated from ddsi_config.c[9a5b3e0862f49dc8bcd57b48b20efa1fc7702f42]
generated from _confgen.h[b3b98385ecc752860a55e126b3893423730f53ab]
generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65]
generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934]
generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01]
generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4]
generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0]
generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830]
generated from generate_defconfig.c[0ef1411470804c3db386c20c8752b161eb8418ae]
28 changes: 22 additions & 6 deletions docs/manual/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ The default value is: `default`


##### //CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange
Attributes: [config](#cycloneddsdomaingeneralinterfacespubsubmessageexchangeconfig), [library](#cycloneddsdomaingeneralinterfacespubsubmessageexchangelibrary), [name](#cycloneddsdomaingeneralinterfacespubsubmessageexchangename), [priority](#cycloneddsdomaingeneralinterfacespubsubmessageexchangepriority)
Attributes: [config](#cycloneddsdomaingeneralinterfacespubsubmessageexchangeconfig), [forbiddenTopics](#cycloneddsdomaingeneralinterfacespubsubmessageexchangeforbiddentopics), [library](#cycloneddsdomaingeneralinterfacespubsubmessageexchangelibrary), [name](#cycloneddsdomaingeneralinterfacespubsubmessageexchangename), [onlyForTopics](#cycloneddsdomaingeneralinterfacespubsubmessageexchangeonlyfortopics), [priority](#cycloneddsdomaingeneralinterfacespubsubmessageexchangepriority)

This element defines a PSMX.

Expand All @@ -415,6 +415,14 @@ This attribute specifies any configuration data for the PSMX instance.This has n
The default value is: `<empty>`


##### //CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@forbiddenTopics]
Text

A comma-separated list of topics that should never use this psmx.Mutually exclusive with onlyForTopics.

The default value is: `<empty>`


##### //CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@library]
Text

Expand All @@ -431,6 +439,14 @@ This attribute specifies the name of the interface.
The default value is: `<empty>`


##### //CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@onlyForTopics]
Text

A comma-separated list of all the topics that should use this PSMX.This option can be used to restrict the PSMX to a selected list of topics.Mutually exclusive with forbiddenTopics.

The default value is: `<empty>`


##### //CycloneDDS/Domain/General/Interfaces/PubSubMessageExchange[@priority]
Text

Expand Down Expand Up @@ -1846,14 +1862,14 @@ While none prevents any message from being written to a DDSI2 log file.
The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.

The default value is: `none`
<!--- generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] -->
<!--- generated from ddsi_config.h[a6553d01e0d7a9c01fda217e68613a8ae1875883] -->
<!--- generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -->
<!--- generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536] -->
<!--- generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64] -->
<!--- generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] -->
<!--- generated from ddsi__cfgelems.h[8c3942cd63352722dacc9df4db7cddae90a2cc13] -->
<!--- generated from ddsi_config.c[9a5b3e0862f49dc8bcd57b48b20efa1fc7702f42] -->
<!--- generated from _confgen.h[b3b98385ecc752860a55e126b3893423730f53ab] -->
<!--- generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] -->
<!--- generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] -->
<!--- generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] -->
<!--- generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4] -->
<!--- generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0] -->
<!--- generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830] -->
<!--- generated from generate_defconfig.c[0ef1411470804c3db386c20c8752b161eb8418ae] -->
22 changes: 17 additions & 5 deletions etc/cyclonedds.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,12 @@ CycloneDDS configuration""" ] ]
text
}?
& [ a:documentation [ xml:lang="en" """
<p>A comma-separated list of topics that should never use this psmx.Mutually exclusive with onlyForTopics.</p>
<p>The default value is: <code>&lt;empty&gt;</code></p>""" ] ]
attribute forbiddenTopics {
text
}?
& [ a:documentation [ xml:lang="en" """
<p>This attribute specifies the filename of the interface library. </p>
<p>The default value is: <code>&lt;empty&gt;</code></p>""" ] ]
attribute library {
Expand All @@ -308,6 +314,12 @@ CycloneDDS configuration""" ] ]
text
}?
& [ a:documentation [ xml:lang="en" """
<p>A comma-separated list of all the topics that should use this PSMX.This option can be used to restrict the PSMX to a selected list of topics.Mutually exclusive with forbiddenTopics.</p>
<p>The default value is: <code>&lt;empty&gt;</code></p>""" ] ]
attribute onlyForTopics {
text
}?
& [ a:documentation [ xml:lang="en" """
<p>This attribute specifies the interface priority (decimal integer or <i>default</i>). The default value for a PSMX is 0.</p>
<p>The default value is: <code>default</code></p>""" ] ]
attribute priority {
Expand Down Expand Up @@ -1283,14 +1295,14 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" }
memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" }
}
# generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d]
# generated from ddsi_config.h[a6553d01e0d7a9c01fda217e68613a8ae1875883]
# generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa]
# generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536]
# generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64]
# generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc]
# generated from ddsi__cfgelems.h[8c3942cd63352722dacc9df4db7cddae90a2cc13]
# generated from ddsi_config.c[9a5b3e0862f49dc8bcd57b48b20efa1fc7702f42]
# generated from _confgen.h[b3b98385ecc752860a55e126b3893423730f53ab]
# generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65]
# generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934]
# generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01]
# generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4]
# generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0]
# generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830]
# generated from generate_defconfig.c[0ef1411470804c3db386c20c8752b161eb8418ae]
24 changes: 19 additions & 5 deletions etc/cyclonedds.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,13 @@ CycloneDDS configuration</xs:documentation>
<xs:annotation>
<xs:documentation>
&lt;p&gt;This attribute specifies any configuration data for the PSMX instance.This has no meaning in CycloneDDS itself, and its parsing is deferred to thePSMX implementation.&lt;/p&gt;
&lt;p&gt;The default value is: &lt;code&gt;&amp;lt;empty&amp;gt;&lt;/code&gt;&lt;/p&gt;</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="forbiddenTopics">
<xs:annotation>
<xs:documentation>
&lt;p&gt;A comma-separated list of topics that should never use this psmx.Mutually exclusive with onlyForTopics.&lt;/p&gt;
&lt;p&gt;The default value is: &lt;code&gt;&amp;lt;empty&amp;gt;&lt;/code&gt;&lt;/p&gt;</xs:documentation>
</xs:annotation>
</xs:attribute>
Expand All @@ -493,6 +500,13 @@ CycloneDDS configuration</xs:documentation>
<xs:annotation>
<xs:documentation>
&lt;p&gt;This attribute specifies the name of the interface. &lt;/p&gt;
&lt;p&gt;The default value is: &lt;code&gt;&amp;lt;empty&amp;gt;&lt;/code&gt;&lt;/p&gt;</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="onlyForTopics">
<xs:annotation>
<xs:documentation>
&lt;p&gt;A comma-separated list of all the topics that should use this PSMX.This option can be used to restrict the PSMX to a selected list of topics.Mutually exclusive with forbiddenTopics.&lt;/p&gt;
&lt;p&gt;The default value is: &lt;code&gt;&amp;lt;empty&amp;gt;&lt;/code&gt;&lt;/p&gt;</xs:documentation>
</xs:annotation>
</xs:attribute>
Expand Down Expand Up @@ -1939,14 +1953,14 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==&lt;br&gt;
</xs:restriction>
</xs:simpleType>
</xs:schema>
<!--- generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] -->
<!--- generated from ddsi_config.h[a6553d01e0d7a9c01fda217e68613a8ae1875883] -->
<!--- generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] -->
<!--- generated from ddsi__cfgelems.h[d4d0b8c7cf61f0a1cfa4b62e02458cf7b8962536] -->
<!--- generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64] -->
<!--- generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] -->
<!--- generated from ddsi__cfgelems.h[8c3942cd63352722dacc9df4db7cddae90a2cc13] -->
<!--- generated from ddsi_config.c[9a5b3e0862f49dc8bcd57b48b20efa1fc7702f42] -->
<!--- generated from _confgen.h[b3b98385ecc752860a55e126b3893423730f53ab] -->
<!--- generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] -->
<!--- generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] -->
<!--- generated from generate_md.c[789b92e422631684352909cfb8bf43f6ceb16a01] -->
<!--- generated from generate_rst.c[3c4b523fbb57c8e4a7e247379d06a8021ccc21c4] -->
<!--- generated from generate_xsd.c[6b6818d7f17a35d56c376c04ec1410427f34c0f0] -->
<!--- generated from generate_defconfig.c[63ca9d8ae2f1ce2e761c9d4c0510a45eb062d830] -->
<!--- generated from generate_defconfig.c[0ef1411470804c3db386c20c8752b161eb8418ae] -->
2 changes: 2 additions & 0 deletions src/core/ddsc/include/dds/ddsc/dds_psmx.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ typedef struct dds_psmx {
dds_psmx_ops_t ops; //!< associated functions
const char *instance_name; //!< name of this PSMX instance
int32_t priority; //!< priority of choosing this interface
char ** only_for_topics; //!< See ddsi_config_psmx. Format is nullptr-terminated array of separately allocated char*
char ** forbidden_topics; //!< See ddsi_config_psmx. Format is nullptr-terminated array of separately allocated char*
const struct ddsi_locator *locator; //!< the locator for this PSMX instance
dds_psmx_instance_id_t instance_id; //!< the identifier of this PSMX instance
struct dds_psmx_topic_list_elem *psmx_topics; //!< associated topics
Expand Down
61 changes: 61 additions & 0 deletions src/core/ddsc/src/dds_psmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <string.h>

#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/dynlib.h"
#include "dds/ddsrt/mh3.h"
#include "dds/ddsi/ddsi_locator.h"
Expand All @@ -26,6 +27,8 @@
static struct dds_psmx_endpoint * psmx_create_endpoint (struct dds_psmx_topic *psmx_topic, const struct dds_qos *qos, dds_psmx_endpoint_type_t endpoint_type);
static dds_return_t psmx_delete_endpoint (struct dds_psmx_endpoint *psmx_endpoint);

void deep_cleanup_topic_array(char **topic_array);

dds_return_t dds_add_psmx_topic_to_list (struct dds_psmx_topic *psmx_topic, struct dds_psmx_topic_list_elem **list)
{
if (!psmx_topic)
Expand Down Expand Up @@ -83,6 +86,14 @@ dds_return_t dds_remove_psmx_topic_from_list (struct dds_psmx_topic *psmx_topic,
return ret;
}

// Free all members of a nullptr-terminated array of separately allocated char pointers
void deep_cleanup_topic_array(char **topic_array) {
for (char * topic = *topic_array; topic; topic++) {
ddsrt_free((void*)topic);
}
ddsrt_free((void*)topic_array);
}

dds_return_t dds_add_psmx_endpoint_to_list (struct dds_psmx_endpoint *psmx_endpoint, struct dds_psmx_endpoint_list_elem **list)
{
if (!psmx_endpoint)
Expand Down Expand Up @@ -163,6 +174,12 @@ dds_return_t dds_psmx_cleanup_generic (struct dds_psmx *psmx)
dds_free ((void *) psmx->instance_name);
dds_free ((void *) psmx->locator);

deep_cleanup_topic_array(psmx->only_for_topics);
psmx->only_for_topics = NULL;

deep_cleanup_topic_array(psmx->forbidden_topics);
psmx->forbidden_topics = NULL;

while (ret == DDS_RETCODE_OK && psmx->psmx_topics)
ret = dds_remove_psmx_topic_from_list (psmx->psmx_topics->topic, &psmx->psmx_topics);

Expand Down Expand Up @@ -249,10 +266,54 @@ static dds_return_t psmx_instance_load (const struct ddsi_domaingv *gv, struct d
goto err_init;
}
psmx_instance->priority = config->priority.value;

if (config->only_for_topics.size > 0 && config->forbidden_topics.size > 0) {
ret = DDS_RETCODE_UNSUPPORTED;
GVERROR ("Failed to initialize PSMX instance '%s': conflicting options only_for_topics and forbidden_topics were both present",
config->name);
goto err_init;
}

// Copy over the only_for_topics and forbidden_topics array, switching to nullptr-terminated array of separately-allocated strings
psmx_instance->only_for_topics = psmx_instance->forbidden_topics = NULL;

// Allocate +1 for the final nullptr terminator
psmx_instance->only_for_topics = ddsrt_calloc_s(config->only_for_topics.size + 1, sizeof(char*));
psmx_instance->forbidden_topics = ddsrt_calloc_s(config->forbidden_topics.size + 1, sizeof(char*));
if (!psmx_instance->only_for_topics || !psmx_instance->forbidden_topics) {
GVERROR ("Failed to initialize PSMX instance '%s': out of memory",
config->name);
goto err_topic_arrays_oom;
}

for (size_t i = 0 ; i < config->only_for_topics.size; i++) {
psmx_instance->only_for_topics[i] = ddsrt_strdup(config->only_for_topics.topics[i]);
if (psmx_instance->only_for_topics[i] == NULL) {
GVERROR ("Failed to initialize PSMX instance '%s': out of memory",
config->name);
goto err_topic_arrays_oom;
}
}
for (size_t i = 0 ; i < config->forbidden_topics.size; i++) {
psmx_instance->forbidden_topics[i] = ddsrt_strdup(config->forbidden_topics.topics[i]);
if (psmx_instance->forbidden_topics[i] == NULL) {
GVERROR ("Failed to initialize PSMX instance '%s': out of memory",
config->name);
goto err_topic_arrays_oom;
}
}

*out = psmx_instance;
*lib_handle = handle;
return DDS_RETCODE_OK;

err_topic_arrays_oom:
if (psmx_instance->only_for_topics) {
deep_cleanup_topic_array(psmx_instance->only_for_topics);
}
if (psmx_instance->forbidden_topics) {
deep_cleanup_topic_array(psmx_instance->forbidden_topics);
}
err_init:
err_dlsym:
ddsrt_dlclose (handle);
Expand Down
24 changes: 24 additions & 0 deletions src/core/ddsc/src/dds_topic.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,30 @@ dds_entity_t dds_create_topic_impl (
struct dds_psmx *psmx = dom->psmx_instances.instances[i];
if (!psmx->ops.type_qos_supported (psmx, DDS_PSMX_ENDPOINT_TYPE_UNSET, sertype_registered->data_type_props, new_qos))
continue;

// Check if the topic is in the forbiddenTopics or NOT in the onlyForTopics list, depending
// on which one is used.
// First off, topics not mentioned are allowed iff only_for_topics is unused
bool allowed_by_config = !psmx->only_for_topics[0];
// Then any topic in only_for_topics is allowed
for (char **topic = psmx->only_for_topics; *topic; topic++) {
if (strcmp(ktp->name, *topic) == 0) {
allowed_by_config = true;
break;
}
}
// And any topic in forbidden_topics is forbidden
for (char **topic = psmx->forbidden_topics; *topic; topic++) {
if (strcmp(ktp->name, *topic) == 0) {
allowed_by_config = false;
break;
}
}

if (!allowed_by_config) {
continue;
}

struct dds_psmx_topic *psmx_topic = psmx->ops.create_topic (psmx, ktp->name, sertype_registered->type_name, sertype_registered->data_type_props);
if (psmx_topic == NULL)
{
Expand Down
Loading

0 comments on commit 4f42a40

Please sign in to comment.