Topic data manipulation

8 posts / 0 new
Last post
Offline
Last seen: 2 days 12 hours ago
Joined: 12/09/2024
Posts: 4
Topic data manipulation

Hi,

I'm looking to perform integration testing on system utilizing 7.3.0 and am researching the best solution. I've explored the docs regarding the rti routing service, qos ownership, etc. but have not found a solution.

Ideally I'm seeking the ability to manipulate data from a datawriter before it reaches any datareaders within the same domain. One idea is to change the datawriter's topic, then introduce a new reader/writer which reads the original data from the new topic, modifies it, and writes the modified data back to the intended topic. 

So if the flow is normally  Write Topic A >>> Read Topic A it would then become Write Topic B >>> Read Topic B (original data) >>> Write Topic A (modified data) >>> Read Topic A

Does the toolkit include any way for me to modify a datawriters topic? Alternatively, are there any other solutions that I haven't considered?

Thanks

 

 

Howard's picture
Offline
Last seen: 3 days 1 hour ago
Joined: 11/29/2012
Posts: 618

Well, everything you mentioned are ways to do it.  You haven't said anything about why the different ways don't work for you...i.e., why are you looking for additional ways.

Also, what exactly do you mean "manipulate data"?  Is the data type the same before and after, i.e., is the data type of Topic A and Topic B exactly the same?  So, you are just changing data values?

How many topics do you need to do this for?   How often do you need to change which topics for which this needs to be done?  How often do you need to change how the data is manipulated for a topic?

Will a solution in which you hard code what topics and the type of data manipulation be sufficient (such that any changes would require code changes and a recompile)?  Or do you need one that can be dynamically modified?

But, yes, fundamentally, you would need to have a process that subscribes to a topic, and then reformulates and republish data that it receives.

However, it's impossible to prevent a DataReader from receiving data from a DataWriter (in a system in which this was working already) unless you're able to change one of the following:

1) QoS setting of the original DataWriter or DataReader

2) DDS domain of the original DataWriter or DataReader app

Given that you can do so, then you can then prevent the original DataWriter connecting to the original DataReader and insert your own process that would subscribe to the original DataWriter and publish to the original DataReader.

That can be done with your own intercepting app.  And if you value the ability to make changes without recompilation, then you can create the app in Python (assuming the performance is sufficient).

You can also do this using RTI Routing Service and writing your own custom Routing Service transform (or Routing Service processor) plugins.  More complicated to do, but has advantages if you have lots of different configurations that you want to test.

Offline
Last seen: 2 days 12 hours ago
Joined: 12/09/2024
Posts: 4

Hi Howard,

Thank you for the quick response.

Is the data type the same before and after, i.e., is the data type of Topic A and Topic B exactly the same?  So, you are just changing data values?

That's correct -- Topic A and Topic B are the same type, I'm only interested in modifying the values.

 

How many topics do you need to do this for?   How often do you need to change which topics for which this needs to be done?  How often do you need to change how the data is manipulated for a topic? 

Will a solution in which you hard code what topics and the type of data manipulation be sufficient (such that any changes would require code changes and a recompile)?  Or do you need one that can be dynamically modified?

At the moment accomplishing this for a single topic would suffice, but it'd be great to have a solution that will scale to any N number of topics. I don't need to change how the data is modified frequently.

 QoS setting of the original DataWriter or DataReader

My understanding is that I would need to modify the QoS profile so both the DataWriter and DataReader are set to exclusive and then "overtake" the original DataWriter by creating one with a higher strength.

If I create a new DataWriter with a higher strength, how could I read the data from the original DataWriter? And if I only knew which DataWriter the topic originated from but had no knowledge of any of the DataReaders for that topic would this approach still work?  Could you please explain a little more or point me in the right direction for documentation? 

 

 

Howard's picture
Offline
Last seen: 3 days 1 hour ago
Joined: 11/29/2012
Posts: 618

If you are able to modifty the QoS settings for the original apps that publish the topic being intercepted, then you can have the original DataWriter send its data to an "middleman" app's DataReader and not have that data received by the original subscribing app's DataReader by using the PARTITION QoS policy.

The OWNERSHIP QoS policy will not work since all DataReaders will receive data from the highest strength DataWriter when Exclusive Ownership is used.

With the Partition QoS (set on the DDSPublisher/DDSSubscriber objects used to create the DDSDataWriter/DDSDataReader objects, respectively), you can set a partition for the original publishing app and the DDSSubscriber of the DataReader of the "middleman" app.   DataReaders will only receive data from DataWriters in the same partition.

On the sending side, you don't need to do anything.  The "middleman"'s DataWriter will send the data to the original subscribing app's DataReader (not using any partitions, no need for QoS changes).  The original DataReader will not receive data from the original DataWriter since they are not sharing a partition.

Offline
Last seen: 2 days 12 hours ago
Joined: 12/09/2024
Posts: 4

I wasn't aware of partitions -- this is very helpful, thank you!

One detail I'm still trying to understand is whether I'm able to modify other domain participants objects within the python api. It seems possible through the admin console but I'm not sure it's exposed programatically?

For example: I can view all participants handles through

p = dds.DomainParticipant(domain_id=0)
participants = p.discovered_participants()
 
 
Is it possible to retrieve the instance object itself?
 
 
Howard's picture
Offline
Last seen: 3 days 1 hour ago
Joined: 11/29/2012
Posts: 618

No you are not able to modify a remotely discovered DomainParticipant entity.  That would require DDS to support a remote access interface for DomainParticipants, and then implement some sort of remote procedure call mechanism...which DDS and RTI Connext does not.

I'm not sure what you think you are able to do with Admin Console, but it does not allow you to make calls/change QoS values/stop/pause/etc a DomainParticipant object.

For RTI services such as Routing Service/Recording Service/Persistence Service, those services do implement an adminstration interface that allows you to remotely send commands to control those services.  The documentation for those interfaces are in their respective users manuals.

Offline
Last seen: 2 days 12 hours ago
Joined: 12/09/2024
Posts: 4

ahh I understand, thank you for the clarification.

It seems as though partitions are my best option as you recommend. Is there a minimal xml I can reference for implementing? Something like  /routing_service/shapes/topic_bridge_w_transf1.xmlbut for partitioning a Writer/Reader? I tried looking but came up empty.

Thank you again for all the help, I appreciate it. 

Howard's picture
Offline
Last seen: 3 days 1 hour ago
Joined: 11/29/2012
Posts: 618

Partitions are just QoS that you would set on the DDSPublisher and DDSSubscriber objects that are used to create the DataWriters and DataReaders.  Those QoS values you can set in code or in an XML QoS Profile.

For example:

  <dds>
    <qos_library name="MyLibrary">
        <qos_profile name="MyProfile" is_default_qos="true">
            <publisher_qos>
                <partition>
                    <name>Foo</name>
                </partition>
            </publisher_qos>
            <subscriber_qos>
                <partition>
                    <name>Foo</name>
                </partition>
            </subscriber_qos>
        </qos_profile>
    </qos_library>
</dds>

If you are trying to use Routing Service to implement the middleman app, then in the Routing Service config, you wll have to modify the Partition Qos for the Routing Service subscriber for the route.  Something like:

<dds>
    <routing_service name="MyRoutingService">
        <domain_route name="RouteTestTopic">
            <participant name="Participant1">
                <domain_id>0</domain_id>
            </participant>
            <session name="Session1">
                <subscriber_qos>
                    <partition>
                        <name>
                            <element>Foo</element>
                        </name>
                    </partition>
                </subscriber_qos>
                <topic_route name="TestTopicRoute">
                    <input participant="Participant1">
                        <topic_name>TestTopic</topic_name>
                    </input>
                    <output participant="Participant1">
                        <topic_name>TestTopic</topic_name>
                    </output>
                </topic_route>
            </session>
        </domain_route>
    </routing_service>
</dds>