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

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

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.

Table 10.1 Resource Reference

Resource

Configuration

Administration

Monitoring

Service

Routing Service Tag

Service

Service

DomainRoute

Domain Route

DomainRoute

DomainRoute

Connection

Domain Route

Connection

DomainRoute

Session

Session

Session

Session

Route

Route

Route

Route

Input

Input/Output

Input/Output

Input/Output

Output

Input/Output

Input/Output

Input/Output

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

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.

Table 10.2 Service States

State

Description

Trigger

Plugin callback

ENABLED

A Service object has loaded the specified service configuration. Monitoring and Administration services are started if they are enabled in the configuration.

  • User runs the Routing Service application either using the pre-built executable or through the Library API (see Usage).

  • Remote command

N/A

STARTED

A Service object has created all the underlying resources, including creating and starting all the contained DomainRoutes, as specified in the configuration.
Additionally, the service discovery thread (SDT) is also started. The SDT sets the context to read the data from the builtin input/output stream discovery StreamReaders
Plugin configurations are validated but the libraries are loaded and instances created lazily when they are first needed.

  • User spawns the entity

  • Remote command

N/A

STOPPED

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.

  • User deletes the entity

  • Remote command

  • AdapterPlugin:: delete

  • ProcessorPlugin:: delete

  • TransformationPlugin:: delete

DISABLED

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.

  • User shutdowns the entity

  • Remote command

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.

Table 10.3 DomainRoute states

State

Description

Trigger

Plugin callback

ENABLED

A DomainRoute object has created all the underlying Connections and Sessions as indicated in the configuration.

N/A

STARTED

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

STOPPED

A DomainRoute object has stopped all Sessions and disabled all the Connections. The DomainRoute is detached from the service discovery thread.

N/A

DISABLED

A DomainRoute object has deleted all the underlying Connections. Entering this state occurs only temporarily while the DomainRoute object is being deleted.

  • Stop DataReader

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

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.

Table 10.4 Connection states

State

Description

Trigger

Plugin callback

ENABLED

A Connection object has created the underlying Adapter connection object.

  • AdapterPlugin:: new (only once for each plugin class)

  • AdapterPlugin:: create_connection

DISABLED

A Connection object has deleted the Adapter connection object it holds.

AdapterPlugin:: delete_connection

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

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

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.

Table 10.5 Session states

State

Description

Trigger

Plugin callback

ENABLED

A Session object has created all the underlying adapter::Session objects. It has also created all the AutoRoutes and Routes that are defined in the configuration.

Connection::create_session

STARTED

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

STOPPED

A Session object has stopped the thread pool, and disabled all the underlying AutoRoutes and Routes.

N/A

DISABLED

A Session object has deleted all the adapter::Session objects it holds.

Connection::delete_session

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

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

Figure 10.8 Route state machine

Table 10.6 shows all the states a Route can enter.

Table 10.6 Route states

State

Description

Trigger

Plugin callback

ENABLED

A Route has created the underlying Processor. The Route is attached to the parent Session and is receiving event notifications.

  • ProcessorPlugin::new (only once for each plugin class)

  • ProcessorPlugin:: create_processor

DISABLED

A Route has deleted the underlying Processor. The Route is detached from the parent Session so no events are notified.

ProcessorPlugin:: delete_processor

STARTED

A Route has enabled all its Inputs and Outputs.

Processor::on_route_event

STOPPED

A Route has disabled at least one of its Inputs and Outputs.

Processor::on_route_event

RUNNING

A Route is ready to process data stream related events. These include:

  • DATA_ON_INPUTS

  • PERIODIC_ACTION

  • Processor::on_route_event

  • StreamReader::read

  • StreamReader::return_loan

  • Transformation::transform

  • Transformation::return_loan

  • StreamWriter::write

PAUSED

A Route is temporarily suspending the processing of data stream related events.

Processor:: on_route_event

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:

\[[S_{m}]\]

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|

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.

Table 10.7 AutoRoute states

State

Description

Trigger

Plugin callback

ENABLED

AutoRoute object is read to start matching streams and create Routes. Previously discovered streams are matched retroactively.

N/A

STARTED

This state is equivalent to the ENABLED state and the transition is automatic upon enabling. This state is added for consistency with the other entities.

  • Enable AutoRoute

N/A

STOPPED

This state is equivalent to the DISABLED state and the transition is automatic upon disabling. This state is added for consistency with the other entities.

  • Disable AutoRoute

N/A

DISABLED

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

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.

Table 10.8 Input states

State

Description

Trigger

Plugin callback

ENABLED

Input has created its underlying StreamReader and it’s ready to read data.

The following two conditions shall be met:

  • Matching type is available

  • Creation mode condition becomes true

  • Connection:: create_stream_reader

  • Processor:: on_route_event

STARTED

This state is equivalent to the ENABLED state and the transition is automatic upon enabling. This state is added for consistency with the other entities.

  • Enable Input

N/A

STOPPED

This state is equivalent to the DISABLED state and the transition is automatic upon disabling. This state is added for consistency with the other entities.

  • Disable Input

N/A

DISABLED

Input has deleted its underlying StreamReader and can no longer read data.

Creation mode condition becomes false

  • Connection:: delete_stream_reader

  • Processor:: on_route_event

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

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.

Table 10.9 Output states

State

Description

Trigger

Plugin callback

ENABLED

Output has created its underlying StreamWriter and it’s ready to write data.

The following two conditions shall be met:

  • Matching type is available

  • Creation mode condition becomes true

  • Connection:: create_stream_writer

  • Processor:: on_route_event

  • TransformationPlugin::new (only once for each plugin class)

  • TransformationPlugin::create_transformation

STARTED

This state is equivalent to the ENABLED state and the transition is automatic upon enabling. This state is added for consistency with the other entities.

  • Enable Output

N/A

STOPPED

This state is equivalent to the DISABLED state and the transition is automatic upon disabling. This state is added for consistency with the other entities.

  • Disable Output

N/A

DISABLED

Output has deleted its underlying StreamWriter and can no longer write data.

Creation mode condition becomes false

  • Connection:: delete_stream_writer

  • TransformationPlugin::delete_transformation

  • Processor:: on_route_event

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

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

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.

Table 10.10 DDS Adapter

Mapping

Configuration Tag

It uses the DomainParticipantFactory to create the participants needed by each DDS Connection

<participant_factory_qos> (only in USER_QOS_PROFILES.xml)

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.

Table 10.11 DDS Connection

Mapping

Configuration Tag

Composed of only one DomainParticipant

<domain_route>/<participant> (see Table 8.8)

10.2.1.3. DDS Session

The DdsSession is an implementation of the Session interface. It’s responsible for creating Subscribers and Publishers.

Table 10.12 DDS Session

Mapping

Configuration Tag

Composed of only one Publisher and one Subscriber

<session>/<subscriber_qos> and <session>/<publisher_qos> (see Table 8.9)

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.

Table 10.13 DDS StreamReader

Mapping

Configuration Tag

Composed of only one DataReader

<route>/<dds_input> and <topic_route>/<input> (see Table 8.13)

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 which DdsSession 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.

Table 10.14 DDS StreamWriter

Mapping

Configuration Tag

Composed of only one DataWriter

<route>/<dds_output> and <topic_route>/<output> (see Table 8.13)

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 which DdsSession 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.