2. 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.

2.1. Resource Model

In this section you will learn the details of the Routing Service application resource model (see Section 12.1). It describes all the different resource classes, their functions and responsibilities, and their relationships with other resources.

Figure 2.1 shows a high-level view of the main classes that comprise the application resource model.

|RS| Resource Model

Figure 2.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 meta-data. A resource in this plane is also known as an entity. The data provision and processing is performed using plugins (see Section 7 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 2.2.

|RS| Resource Model

Figure 2.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 (Section 2.2.1). It’s recommended though that you still review the general model for a solid understanding of Routing Service.

2.1.1. Directory

Table 2.1 provides a resource directory with quick links to access different types of information for each resource or entity.

Table 2.1 Resource Reference
Resource Configuration Administration Monitoring
Service Section 4.5.1 Section 5.2.2 Section 6.2.1
DomainRoute Section 4.5.4 Section 5.2.3 Section 6.2.2
Connection Section 4.5.4 Section 5.2.4 Section 6.2.2
Session Section 4.5.5 Section 5.2.5 Section 6.2.3
Route Section 4.5.6 Section 5.2.7 Section 6.2.5
Input Section 4.5.7 Section 5.2.8 Section 6.2.6
Output Section 4.5.7 Section 5.2.8 Section 6.2.6

2.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 Section 6 and Section 5, respectively.

In the data plane, the Service is composed of a collection of user plugins instances and a collection of DomainRoutes.

2.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 Section 7). Figure 2.3 shows the relationship between the Service and the plugin objects.

|SERVICE| plugins objects

Figure 2.3 Routing Service composed of different plugins

See Section 12.4 for more information about plugin management.

2.1.2.2. Service States

A Service can be in one of the states listed in Table 2.2.

Table 2.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 Service API (see Section 3).
  • 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

2.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.

2.1.3.1. DataReader States

A DomainRoute can be in one of the states listed in Table 2.3.

Table 2.3 DataReader 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

2.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 4.7 and Table 4.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.

2.1.4.1. Plugin Interaction

Figure 2.4 shows the relationship with the plugin objects. A Connection shall hold one, and only one, adapter::Connection object.

|CONNECTION| plugins objects

Figure 2.4 Relationship of plugins with a Connection

2.1.4.2. Connection States

A Connection can be in one of the states listed in Table 2.4.

Table 2.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

2.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:

  • registered type 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 Section 4.5.7.2.1). 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.

2.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 2.5 shows the event processing mechanism. Consider a Session with a pool of N threads and composed of P Routes.

|CONNECTION| plugins objects

Figure 2.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 Section 2.1.6 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 2.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).

2.1.5.1. Plugin Interaction

Figure 2.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 2.6 Relationship of plugins with a Session

2.1.5.2. Session States

A Session can be in one of the states listed in Table 2.5.

Table 2.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

2.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.

2.1.6.1. Plugin Interaction

Figure 2.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 2.7 Relationship of plugins with a Route

For more information about the Processor behavior and Route events, see the main page of API documentation (Section 7).

2.1.6.2. Route States

A Route state machine is shown in Figure 2.8.

|ROUTE| state machine

Figure 2.8 Route state machine

Table 2.6 shows all the states a Route can enter.

Table 2.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 disable 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

2.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 for each pair:

\[[S_{m}, T_{n}]\]

where Sm and Tn are the name for the stream m and the name of the type n, respectively. 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 2.9 illustrates this relationship.

|AR| as a factory of |ROUTEs|

Figure 2.9 AutoRoute as a map of Routes keyed by stream and type names

The AutoRoute creates a Route only if it has not previously matched the Sm and Tn pair. AutoRoutes never delete the created Route, independently 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.

2.1.7.1. AutoRoute States

An AutoRoute can be in one of the states listed in Table 2.7.

Table 2.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

2.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.

2.1.8.1. Plugin Interaction

Figure 2.10 shows the relationship with the plugin objects. An Input shall hold one, and only one, adapter::StreamReader object.

|INPUT| plugins objects

Figure 2.10 Relationship of plugins with an Input

2.1.8.2. Input States

An Input can be in one of the states listed in Table 2.8.

Table 2.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

2.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.

2.1.9.1. Plugin Interaction

Figure 2.11 shows the relationship with the plugin objects. An Output shall hold one, and only one, adapter::StreamWriter object. Optionally, an Output can hold one, and only one, transformation::Transformation object.

|OUTPUT| plugins objects

Figure 2.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.

2.1.9.2. Output States

An Output can be in one of the states listed in Table 2.9.

Table 2.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

2.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.

2.2.1. DDS Adapter

This is an Adapter implementation that provides access to DDS domains. Figure 2.12 shows the architecture of the DDS Adapter.

DDS |ADAPTER| architecture

Figure 2.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 2.1 except that the Adapter entity they enclose is created from the builtin DDS Adapter (Section 2.2.1). Figure 2.13 shows the DDS specialization of the generic resource model.

|RS| Resource Model

Figure 2.13 Routing Service DDS Application Resource Model

2.2.1.1. DDS AdapterPlugin

The DdsAdapter is an implementation of the Adapter interface. It’s responsible for creating DDS Connections.

Table 2.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)

2.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 2.11 DDS Connection
Mapping Configuration Tag
Composed of only one DomainParticipant <domain_route>/<participant> (see Table 4.8)

2.2.1.3. DDS Session

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

Table 2.12 DDS Session
Mapping Configuration Tag
Composed of only one Publisher and one Subscriber <session>/<subscriber_qos> and <session>/<publisher_qos> (see Table 4.9)

Note that, as explained in Section 2.1.5.1, a new DdsSession object is instantiated for each pair <session> and <participant> element within the parent DomainRoute.

2.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 2.13 DDS StreamReader
Mapping Configuration Tag
Composed of only one DataReader <route>/<dds_input> and <topic_route>/<input> (see Table 4.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.

2.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 2.14 DDS StreamWriter
Mapping Configuration Tag
Composed of only one DataWriter <route>/<dds_output> and <topic_route>/<output> (see Table 4.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.

2.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 Section 9.2).

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.