10. Core Concepts¶
This section aims to provide a deeper understanding of the Routing Service architecture and give you the required insight to configure and use it effectively.
You will learn about:
Application resource model: Gives you a full picture of all the elements that compose Routing Service, including details about their relationships with the pluggable components and their lifecycle.
Builtin plugins: Describes the builtin pluggable components that are part of the Routing Service module.
10.1. Resource Model¶
In this section you will learn the details of the Routing Service application resource model (see Application Resource Model). It describes all the different resource classes, their functions and responsibilities, and their relationships with other resources.
Figure 10.1 shows a high-level view of the main classes that comprise the application resource model.
![|RS| Resource Model](_images/RouterResourceModel.png)
Figure 10.1 Routing Service Application Resource Model¶
There are two main logical planes, each addressing orthogonal sets of capabilities:
Data Plane: Set of resources associated with data flow, both user data and metadata. A resource in this plane is also known as an entity. The data provision and processing is performed using plugins (see Software Development Kit for an overview of the list of available plugins).
Control Plane: Set of resources associated with service monitoring and administration. These are the resources in charge of providing monitoring information and run-time administration of the resources from the data plane.
An alternative representation of the resource module is shown in Figure 10.2.
![|RS| Resource Model](_images/RouterObjectModel.png)
Figure 10.2 Routing Service Alternative representation of the Application Resource Model¶
The next sections describe each entity with detail. The documentation for each entity will provide:
A Description of the role and responsibility of the entity within Routing Service.
The relationship, if any, with plugin components. This part will give you an understanding of how Routing Service achieves custom behavior.
A Description of the states an entity can go through.
The next sections describe Routing Service from a generic point of view, independently of the Adapter (or any other type of plugin) that is used. To read more about how DDS is integrated with Routing Service, please see the (DDS Adapter). It’s recommended though that you still review the general model for a solid understanding of Routing Service.
10.1.1. Directory¶
Table 10.1 provides a resource directory with quick links to access different types of information for each resource or entity.
Resource |
Configuration |
Administration |
Monitoring |
---|---|---|---|
10.1.2. Service¶
The Service is the top-level resource. The Service is the entity that encapsulates all the resources needed for the operation of both the control and data planes. Typically, a Service refers to an execution of Routing Service.
In the control plane, the Service is composed of the Monitoring and Administration resources, which are optionally available sub-services. These components are described in Monitoring and Remote Administration, respectively.
In the data plane, the Service is composed of a collection of user plugins instances and a collection of DomainRoutes.
10.1.2.1. Plugin Interaction¶
The Service is responsible for loading and owning any of the plugins that you can provide through the Software Development Kit (see Software Development Kit). Figure 10.3 shows the relationship between the Service and the plugin objects.
![|SERVICE| plugins objects](_images/RouterServicePlugins.png)
Figure 10.3 Routing Service composed of different plugins¶
See Plugin Management for more information about plugin management.
10.1.2.2. Service States¶
A Service can be in one of the states listed in Table 10.2.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
A Service object has loaded the specified service configuration. Monitoring and Administration services are started if they are enabled in the configuration. |
|
N/A |
|
A Service object has created all the underlying resources,
including creating and starting all the contained DomainRoutes, as
specified in the configuration. |
|
N/A |
|
A Service object has deleted all the resources created during the start phase: the service discovery thread and DomainRoutes are deleted. Additionally, any plugin instances are deleted. |
|
|
|
A Service object has deleted all the resources created during the enable phase. Entering this state occurs only temporarily while the Service object is being deleted. |
|
N/A |
10.1.3. DomainRoute¶
A DomainRoute defines a collection of independent data domains (such as DDS, MQTT, AMQP, etc.), each modeled as a Connection. It’s also composed of a collection of Sessions.
10.1.3.1. DomainRoute States¶
A DomainRoute can be in one of the states listed in Table 10.3.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
A DomainRoute object has created all the underlying Connections and Sessions as indicated in the configuration. |
|
N/A |
|
A DomainRoute object has enabled all the contained Connections and started all the contained Sessions. The DomainRoute is attached to the service discovery thread and may start processing stream discovery data. |
|
N/A |
|
A DomainRoute object has stopped all Sessions and disabled all the Connections. The DomainRoute is detached from the service discovery thread. |
|
N/A |
|
A DomainRoute object has deleted all the underlying Connections. Entering this state occurs only temporarily while the DomainRoute object is being deleted. |
|
N/A |
10.1.4. Connection¶
A Connection defines an access point to a specific data domain. The access to a data domain is provided through an instance of an Adapter plugin, which is specified in the configuration (See Table 8.7 and Table 8.8). For example, the associated Adapter plugin implementation could provide a connection to an HTTP Server through an HTTP Client, or a logical connection to a DDS Domain through a DomainParticipant.
The Connection is also responsible for tracking all the stream information that is provided by the underlying input and output stream discovery StreamReaders. The Connection gets notified about new or disposed streams and propagates this information downstream to the Routes and AutoRoutes, which will process and generate events accordingly.
Note
A DomainParticipant is a special type of Connection that represents an instance of a
DdsConnection
. For this case, special custom tags are available that
facilitate configuring the DdsConnection
.
10.1.4.1. Plugin Interaction¶
Figure 10.4 shows the relationship with the plugin
objects. A Connection shall hold one, and only one, adapter::Connection
object.
![|CONNECTION| plugins objects](_images/RouterConnectionPlugins.png)
Figure 10.4 Relationship of plugins with a Connection¶
10.1.4.2. Connection States¶
A Connection can be in one of the states listed in Table 10.4.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
A Connection object has created the underlying Adapter connection object. |
|
|
|
A Connection object has deleted the Adapter connection object it holds. |
|
|
10.1.4.3. Type Registration¶
The Connection is the entity where type registration takes place. A Connection keeps a list of registered types, where each entry in the list contains:
type registered name: Unique name used to identify and register a concrete type within the Connection.
type representation: In-memory structure that describes the type itself. The type representation is adapter-dependent and Routing Service assumes
TypeCode
as default type representation for types.
A type is associated with a stream and its registration is required in order to create StreamReaders and StreamWriters. A type can be registered in two ways:
Through stream discovery information, provided by the builtin stream discovery StreamReaders. On stream discovery, the associated information contains the registered name and the representation for a type.
Through XML Connection configuration (see Defining Types in the Configuration File). A type definition is provided in XML and the Routing Service parser will generate a
TypeCode
from it. Connection configuration can then reference this XML type definition to register it.
10.1.5. Session¶
A Session defines a collection of Routes and AutoRoutes. It also defines a multi-threaded safe context for Route event processing.
Events from a Route are processed sequentially within the same Session. A Route event is processed by a single thread at a time. That is, the same route cannot be processed concurrently. However, within a Session, different Routes that can be processed concurrently, as many as the number of threads available within the Session.
Figure 10.5 shows the event processing mechanism.
Consider a Session with a pool of N
threads and composed of P
Routes.
![|CONNECTION| plugins objects](_images/RouterSessionThreads.png)
Figure 10.5 Processing mechanism of Routes within a Session¶
Session threads are idle waiting for Routes to become active. An active Route is one that has events pending processing.
Once an active Route is selected for processing, all the pending events at that time will be consumed sequentially one after the other (see Route for information about route processing). To prevent starvation, new events arriving will be deferred for the next selection cycle.
A Session selects Routes for processing in a round-robin fashion, following the same order as they are defined in the Session configuration. At a maximum only
N
Routes can be processed concurrently. Remaining active Routes will wait until a thread becomes available.
Figure 10.5 shows a Session concurrently processing
N
active Routes. Other remaining P-N
Routes, such as RouteP,
are active and waiting for a thread to become available;
RouteP-1 is not active (no pending events).
10.1.5.1. Plugin Interaction¶
Figure 10.6 shows the relationship with the plugin
objects. A Session shall hold one adapter::Session
object for each
Connection in the parent DomainRoute.
![|SESSION| plugins objects](_images/RouterSessionPlugins.png)
Figure 10.6 Relationship of plugins with a Session¶
10.1.5.2. Session States¶
A Session can be in one of the states listed in Table 10.5.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
A Session object has created all the underlying |
|
|
|
A Session object has started the thread pool, and enabled all the underlying AutoRoutes and Routes. In this state, the Session is actively processing Route events. |
|
N/A |
|
A Session object has stopped the thread pool, and disabled all the underlying AutoRoutes and Routes. |
|
N/A |
|
A Session object has deleted all the |
|
|
10.1.6. Route¶
A Route defines a processing unit for data streams. A Route is composed
of N
Inputs and M
Outputs, each referencing any of the Connections
defined as part of the parent DomainRoute.
A Route generates certain events that are processed safely and serially within one of the threads from the parent Session. Route events are processed through a pluggable Processor.
Note
A TopicRoute is a special type of Route. All its Inputs and Outputs are tied to the builtin DDS Adapter. For this case, special and custom tags are available that facilitate configuring the TopicRoute.
10.1.6.1. Plugin Interaction¶
Figure 10.7 shows the relationship with the plugin objects. A Route shall hold one Processor object, which will receive the notifications of the events affecting the owner Route.
![|SESSION| plugins objects](_images/RouterRoutePlugins.png)
Figure 10.7 Relationship of plugins with a Route¶
For more information about the Processor behavior and Route events, see the main page of API documentation (Software Development Kit).
10.1.6.2. Route States¶
A Route state machine is shown in Figure 10.8.
![|ROUTE| state machine](_images/RouterRouteState.png)
Figure 10.8 Route state machine¶
Table 10.6 shows all the states a Route can enter.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
A Route has created the underlying Processor. The Route is attached to the parent Session and is receiving event notifications. |
|
|
|
A Route has deleted the underlying Processor. The Route is detached from the parent Session so no events are notified. |
|
|
|
A Route has enabled all its Inputs and Outputs. |
|
|
|
A Route has disabled at least one of its Inputs and Outputs. |
|
|
|
A Route is ready to process data stream related events. These include:
|
|
|
|
A Route is temporarily suspending the processing of data stream related events. |
|
|
10.1.7. AutoRoute¶
An AutoRoute represents a factory of single-input single-output Routes. An AutoRoute creates Routes based on a name filter criteria that matches the name or type of a stream.
An AutoRoute creates a Route per stream name:
where Sm is the name for the stream m
. The name of the type
Tm, only plays a role while passing the filter criteria and while creating
the generated Route’s Input and Output.
This means a stream name that is shared by multiple type names won’t spawn a new Route from an AutoRoute per type name. Rather it will reuse the first one generated for the shared stream name.
Note
It is not advised to have streams share the same name but have different type names when using an AutoRoute. It can lead to a situation where the Input and Output discover streams with different type names, leading to an incompatible Route creation - especially when dealing with the builtin DDS Adapter. In such a situation it is better to bifurcate the streams based on their stream name.
In the case of the builtin DDS Adapter, if the two types under the same topic (stream) name are compatible as per the rules of Extensible Types, only then will data be successfully routed by the common generated Route.
The generation of a Route occurs only on the event of a newly discovered stream. The resulting Route has a single Input and a single Output, both for the same stream name and type.
The created Route executes within the context of the parent Session of the AutoRoute. Figure 10.9 illustrates this relationship.
![|AR| as a factory of |ROUTEs|](_images/RouterAutoRouteMap.png)
Figure 10.9 AutoRoute as a map of Routes keyed by stream name¶
The AutoRoute creates a Route only if it has not previously matched Sm. AutoRoutes never delete the created Route, regardless of whether the matching streams are disposed or not.
Note
An AutoTopicRoute is a special type of AutoRoute whose Inputs and Outputs are tied to the builtin DDS Adapter. For this case, special and custom tags are available that facilitate configuring the AutoTopicRoute.
10.1.7.1. AutoRoute States¶
An AutoRoute can be in one of the states listed in Table 10.7.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
AutoRoute object is read to start matching streams and create Routes. Previously discovered streams are matched retroactively. |
|
N/A |
|
This state is equivalent to the |
|
N/A |
|
This state is equivalent to the |
|
N/A |
|
AutoRoute stops matching all newly discovered streams. All the Routes created from this AutoRoute are deleted. |
|
N/A |
10.1.8. Input¶
An Input is responsible for obtaining data associated with a specific stream uniquely identified by its name and type. An Input must reference an existing Connection within the parent DomainRoute. The referenced Connection determines the data domain where the Input will obtain data.
An Input has scope only within the parent Route. It cannot be shared in other Routes. If another Route requires accessing the same data stream, a new Input shall be defined within such Route.
10.1.8.1. Plugin Interaction¶
Figure 10.10 shows the relationship with the plugin
objects. An Input shall hold one, and only one, adapter::StreamReader
object. Optionally, an Input may hold one and only
transformation::Transformation
instance, that is applied to the sample stream
returned by the adapter::StreamReader
.
![|INPUT| plugins objects](_images/RouterInputPlugins.png)
Figure 10.10 Relationship of plugins with an Input¶
The Input obtains data from a domain by calling the StreamReader::read
operation. If a Transformation is present, the Transformation::transform
operation is called right after reading from the StreamReader. The
Transformation::return_loan
is called when the obtained loaned samples are
returned.
10.1.8.2. Input States¶
An Input can be in one of the states listed in Table 10.8.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
Input has created its underlying StreamReader and it’s ready to read data. |
The following two conditions shall be met:
|
|
|
This state is equivalent to the |
|
N/A |
|
This state is equivalent to the |
|
N/A |
|
Input has deleted its underlying StreamReader and can no longer read data. |
Creation mode condition becomes false |
|
10.1.9. Output¶
An Output is responsible for writing data associated with a specific stream uniquely identified by its name and type. An Output must reference an existing Connection within the parent DomainRoute. The referenced Connection determines the data domain where the Output will provide data.
An Output has scope only within the parent Route. It cannot be shared in other Routes. If another Route requires access to the same data stream, a new Output shall be defined within such Route.
10.1.9.1. Plugin Interaction¶
Figure 10.11 shows the relationship with the plugin
objects. An Output shall hold one, and only one, adapter::StreamWriter
object. Optionally, an Input may hold one and only
transformation::Transformation
instance, that is applied to a sample stream
before is passed to the adapter::StreamWriter
.
![|OUTPUT| plugins objects](_images/RouterOutputPlugins.png)
Figure 10.11 Relationship of plugins with an Output¶
The Output provides the data to a domain by calling the StreamWriter::write
operation. If a Transformation is present, the Transformation::transform
operation is called right before writing on the StreamWriter, followed by a
Transformation::return_loan
right after.
10.1.9.2. Output States¶
An Output can be in one of the states listed in Table 10.9.
State |
Description |
Trigger |
Plugin callback |
---|---|---|---|
|
Output has created its underlying StreamWriter and it’s ready to write data. |
The following two conditions shall be met:
|
|
|
This state is equivalent to the |
|
N/A |
|
This state is equivalent to the |
|
N/A |
|
Output has deleted its underlying StreamWriter and can no longer write data. |
Creation mode condition becomes false |
|
10.2. Builtin plugins¶
Builtin plugins come pre-registered in memory within Routing Service. Any configurable aspects are available through dedicated special tags for enhanced usability.
10.2.1. DDS Adapter¶
This is an Adapter implementation that provides access to DDS domains. Figure 10.12 shows the architecture of the DDS Adapter.
![DDS |ADAPTER| architecture](_images/RouterDdsAdapter.png)
Figure 10.12 DDS Adapter architecture¶
Most of the use cases expect to have DDS as the main data domain in the user data plane. For this reason, you will find that Routing Service specializes some entities so that they are directly associated with DDS. These entities are:
Participant
AutoTopicRoute
TopicRoute
DdsInput
DdsOutput
These entities are equivalent to the generic entities shown in Figure 10.1 except that the Adapter entity they enclose is created from the builtin DDS Adapter (DDS Adapter). Figure 10.13 shows the DDS specialization of the generic resource model.
![|RS| Resource Model](_images/RouterDdsResourceModel.png)
Figure 10.13 Routing Service DDS Application Resource Model¶
10.2.1.1. DDS AdapterPlugin¶
The DdsAdapter
is an implementation of the Adapter interface. It’s
responsible for creating DDS Connections.
Mapping |
Configuration Tag |
---|---|
It uses the DomainParticipantFactory to create the participants needed by each DDS Connection |
|
10.2.1.2. DDS Connection¶
The DdsConnection
is an implementation of the Connections interface.
It is responsible for joining to a specific DDS Domain. It’s also the factory
for creating DDS Sessions, StreamReaders and StreamWriters.
The DdsConnection
relies on the DdsAdapter
for creating DomainParticipants. This
class creates the Topics associated with the DataReaders and DataWriters it also
creates.
Mapping |
Configuration Tag |
---|---|
Composed of only one DomainParticipant |
|
10.2.1.3. DDS Session¶
The DdsSession
is an implementation of the Session interface. It’s
responsible for creating Subscribers and Publishers.
Mapping |
Configuration Tag |
---|---|
Composed of only one Publisher and one Subscriber |
|
Note that, as explained in Plugin Interaction,
a new DdsSession
object is instantiated for each pair <session>
and
<participant>
element within the parent DomainRoute.
10.2.1.4. DDS StreamReader¶
The DdsStreamReader
is an implementation of the StreamReader interface. It’s
responsible for reading data from a Topic and providing it to the parent
Route, which is in charge of processing it through the installed Processor.
Mapping |
Configuration Tag |
---|---|
Composed of only one DataReader |
|
The referenced DDS Connection and parent <session>
determines from which
DomainParticipant and Subscriber the DataReader is created.
The configuration of the Input owning the StreamReader indicates:
The referenced DDS Connection that contains the DomainParticipant
The parent
<session>
, which along with the referenced Connection, determines whichDdsSession
and hence Subscriber is used to create the DataReader.The name of the Topic in the domain of the DomainParticipant.
10.2.1.5. DDS StreamWriter¶
The DdsStreamWriter
is an implementation of the StreamWriter interface. It’s
responsible for writing data to a Topic. The data is provided by the parent
Route through the installed Processor.
Mapping |
Configuration Tag |
---|---|
Composed of only one DataWriter |
|
The referenced DDS Connection and parent <session>
determines from which
DomainParticipant and Publisher the DataWriter is created.
The configuration of the Output owning the StreamWriter indicates:
The referenced DDS Connection that contains the DomainParticipant
The parent
<session>
, which along with the referenced Connection determines whichDdsSession
and hence Publisher is used to create the DataWriter.The name of the Topic in the domain of the DomainParticipant.
10.2.2. Forwarding Processor¶
This is a Processor implementation that forwards samples within a Route.
The plugin registered name is reserved and has the value
rti.routingservice.RoutingProcessor
.
The functions of the builtin forwarding Processor are:
Forwarding all the live data samples received from each Input to each Output.
Proxying the TopicQueries received by the
DdsStreamWriter
, making sure all the TopicQuery data samples received from each Input are sent to the corresponding Outputs and final destination DataReaders. (see Propagation Mode).
These functions are executed under the notification of the DATA_ON_INPUTS
and PERODIC_ACTION
events. The builtin forwarding Processor is set by
default in all AutoRoutes and Routes.
Note that if you install your own Processor implementation, you will override
the functionality described above. In this case, even if the dedicated
configuration tags are specified (such as <topic_query_proxy>
), they will
not have any effect.