12.1. Configuring RTI Services

RTI Services are configured using XML and offer multiple ways to load the configurations. The loading alternatives are in general standard across all RTI Services. This section covers how you can provide XML configurations to RTI Services, as well as specific behaviors on how the XML is parsed, validated, and interpreted.

12.1.1. How to Load and Select an XML Configuration

To run an RTI Service with a specific configuration you need to provide two pieces:

  • XML content with one or more configurations
    This is the actual XML code that contains the service-specific configurations. We refer to this as the input XML document. There are two different input sources: File system or in-memory strings.

  • Configuration name
    The name of the actual service configuration to be run. Each RTI Service defines a top-level element that shall contain a name attribute that uniquely identifies it.

12.1.1.1. Loading from Files

RTI Services can receive a list of file paths separated by semicolons (;):

filepath_1;filepath_2; ... filepath_N

File paths can be relative or absolute and files are loaded in order from left to right. How you provide the file path list depends on whether you run the service from the shipped executable or embed it into your application using the Service API 1.

Use the -cfgFile option.

Warning

On some operating systems, ; is interpreted as a command separator, so you will need to escape the path list with double quotes ".

For example on Linux systems:

$NDDSHOME/bin/rtiroutingservice -cfgFile "file.xml;/home/file2.xml"
$NDDSHOME/bin/rtirecordingservice -cfgFile "file.xml;/home/file2.xml"
$NDDSHOME/bin/rticlouddiscoveryservice -cfgFile "file.xml;/home/file2.xml"

where [NDDSHOME] indicates the path to your Connext DDS installation.

Set the ServiceProperty::cfg_file member.

For example in C++:

ServiceProperty property;
property.cfg_file("file.xml;/home/file2.xml");
...
Service service(property);
1

Service API may not be available for certain RTI Services.

12.1.1.2. Loading from In-Memory Strings

If you are embedding RTI Services into your application using the Service API, the input XML document can be also be provided through a string array object. You can do so by setting the ServiceProperty::cfg_strings member.

For example in C++:

std::vector<std::string> xml_strings;
xml_strings.resize(2);
/* This sample demonstrates using Routing Service */
xml_strings[0] = "<dds><routing_service name=\"MyService\">";
xml_strings[1] = "</routing_service></dds>";
property.cfg_strings(xml_strings);
...
Service service(property);

12.1.1.3. Selecting which Configuration to Run

As stated earlier, the input XML document may contain one or more service configurations. You will need to select which specific configuration to run by providing its configuration name.

How you provide the configuration name depends on whether you run the service from the shipped executable or by embedding it into your application using the Service API.

For example, consider the following input XML document in a file named MyService.xml that contains two configurations.

<dds>
    <routing_service name="Service1"> ... </routing_service>

    <routing_service name="Service2"> ... </routing_service>
</dds>
<dds>
    <recording_service name="Service1"> ... </recording_service>

    <recording_service name="Service2"> ... </recording_service>
</dds>
<dds>
    <cloud_discovery_service name="Service1"> ... </cloud_discovery_service>

    <cloud_discovery_service name="Service2"> ... </cloud_discovery_service>
</dds>

You can run the configuration for Service1 as follows:

Use the -cfgName option.

For example, on Linux systems:

$NDDSHOME/bin/rtiroutingservice -cfgFile MyService.xml -cfgName Service1
$NDDSHOME/bin/rtirecordingservice -cfgFile MyService.xml -cfgName Service1
$NDDSHOME/bin/rticlouddiscoveryservice -cfgFile MyService.xml -cfgName Service1

Set the ServiceProperty::cfg_name member.

For example in C++:

ServiceProperty property;
property.cfg_file("MyService.xml");
property.cfg_name("Service1");
...
Service service(property);

12.1.1.4. Default Files

In addition to manually providing input XML files, RTI Services also attempt to automatically load a set of files from predefined locations:

Table 12.1 RTI Services Default Files

File

Allowed Content

[working directory]/USER_[SERVICE].xml

  • Service-specific elements

  • QoS profiles

  • Types

[NDDSHOME]/resource/xml/RTI_[SERVICE].xml

  • Service-specific elements

  • QoS profiles

  • Types

[working directory]/USER_QOS_PRORFILES.xml

  • QoS profiles

  • Types

where [SERVICE] refers to the concrete product name in uppercase. For example:

  • ROUTING_SERVICE for RTI Routing Service

  • RECORDING_SERVICE for RTI Recording Service

  • CLOUD_DISCOVERY_SERVICE for RTI Cloud Discovery Service

These files are loaded only if present.

You can disable the loading of default files by using the proper option:

Use the -skipDefaultFiles option.

Set the ServiceProperty::skip_default_files member to true.

12.1.1.5. XML Syntax and Validation

The XML representation of DDS-related resources must follow these syntax rules:

  • It shall be a well-formed XML document according to the criteria defined in clause 2.1 of the Extensible Markup Language standard.

  • It shall use UTF-8 character encoding for XML elements and values.

  • It shall use <dds> as the root tag of every document.

To validate the loaded configuration, each RTI Service relies on an XSD document that describes the format of the XML content. The validation of the input XML document occurs after all the files and strings have been parsed. If the validation fails, the RTI Service will fail to load the XML and log an error. For example here is an error in the case of RTI Cloud Discovery Service:

NDDSHOME/bin/rticlouddiscoveryservice
[/cloud_discovery_services/default|CREATE] line 26: Element 'invalid_example_tag': This element is not expected.
[/cloud_discovery_services/default|CREATE] CDSService_loadConfiguration:!validate configuration
[/cloud_discovery_services/default|CREATE] CDSService_initialize:!load configuration
[/cloud_discovery_services/default|CREATE] CDSService_new:!init service
main:!create service

You can disable the XSD validation process by using the proper option:

Use the -ignoreXsdValidation option.

Set the ServiceProperty::enforce_xsd_validation member to false.

We recommend including a reference to this document in the XML file that contains the service’s configuration; this provides helpful features in code editors such as Visual Studio®, Eclipse®, and NetBeans®, including validation and auto-completion while you are editing the XML file.

The XSD for the RTI Service configuration elements is in [NDDSHOME]/resource/schema/rti_[service_name].xsd, where [service_name] refers to product name in lower snake case. For example:

  • routing_service for RTI Routing Service

  • recording_service for RTI Recording Service

  • cloud_discovery_service for RTI Cloud Discovery Service

To include a reference to the XSD document in your XML file, use the attribute xsi:noNamespaceSchemaLocation in the <dds> tag. For example:

<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="[NDDSHOME]/resource/schema/rti_routing_service.xsd">
    <!-- ... -->
</dds>

Warning

The product XSD file provided under [NDDSHOME]/resource/schema is to assist you in the process of creating an XML configuration document. RTI Services have the XSD builtin in memory, so making modifications to the reference XSD will not have an impact on the validation process.

12.1.1.6. Listing Available Configurations

The shipped executables of some RTI Services provide an option to list all the available configurations in the specified input XML document. You can run the service with the -listConfig option to list the available configurations and exit. For example, on Linux systems:

rtiroutingservice -listConfig
Available configurations:
- default:([NDDSHOME]/resource/xml/RTI_ROUTING_SERVICE.xml)
    Routes all topics from domain 0 to domain 1
- defaultBothWays:([NDDSHOME]/resource/xml/RTI_ROUTING_SERVICE.xml)
    Routes all topics from domain 0 to domain 1 and the other way around
- defaultReliable:([NDDSHOME]/resource/xml/RTI_ROUTING_SERVICE.xml)
    Routes all topics from domain 0 to domain 1 using reliable communication
rticlouddiscoveryservice -listConfig
Available configurations:
- rti.cds.builtin.config.default:(builtin string)
    Empty configuration. Assumes default values.
- rti.cds.builtin.config.default_wan:(builtin string)
    Enables Real-Time WAN Transport.
                XML variables:
                    - RTI_CDS_PORT: CDS public and host port number
                    - RTI_CDS_PUBLIC_ADDR: CDS WAN public address

Each listed configuration indicates the input source (file path or string) and the content of the <documentation> tag if present. This operation lists all the configurations detected from the specified input XML document from all the locations and files.

12.1.1.7. Configuration Variables

The builtin XML parser of the RTI Service offers a special mechanism to reuse and customize content at run time through the concept of Configuration variables.

A configuration variable is an RTI-specific construct that you can use in the input XML documents to set placeholders for content that will be expanded at parsing time. A variable is specified as follows:

$(VAR_NAME)

where VAR_NAME is the name that identifies the variable. You can use configuration variables in your XML content as an attribute value and element text.

<element attribute="$(VAR_ATTR)">my expanded $(VAR_TEXT)</element>

The possible ways a variable can be expanded are listed below in precedence order:

  1. Process environment.

    export VAR_NAME=my_value
    
  2. Using a specific option when running the service.

    Use the -DVAR_NAME=VALUE option

    $<rtiservicename> ... -DVAR_NAME=my_value
    

    where <rtiservicename> is one of rtiroutingservice, rtirecordingservice or rticlouddiscoveryservice.

    Set the ServiceProperty::user_environment member

    ServiceProperty property;
    property.user_environment()["VAR_NAME"] = "var_value";
    ...
    
  3. <configuration_variables> section, which represents an unbounded list of variable name-variable value pairs.

    <configuration_variables>
        <value>
            <element>
                <name>VAR_NAME</name>
                <value>var_value</value>
            </element>
            ...
        </value>
    </configuration_variables>
    

All three of these mechanisms can be used in combination or separately. For the above example, you could expand one variable using the process environment and another variable using the command-line option. The following command:

export VAR_ATTR=expanded_attr
<rtiservicename> ... -DVAR_TEXT=expanded_text

where <rtiservicename> is one of rtiroutingservice, rtirecordingservice or rticlouddiscoveryservice, will result in the following actual parsed XML with the expanded variables:

<element attribute="expanded_attr">my expanded expanded_text</element>

If the RTI Service cannot expand a variable, it will load the XML document and log an error indicating which variable could not be expanded. Here is an example for RTI Routing Service:

[/routing_services/default|CREATE] RTIXMLUTILSVariableExpansor_expandString:variable with name=ADMIN_DOMAIN_ID not defined
[/routing_services/default|CREATE] RTIXMLUTILSVariableExpansor_visit:!parse at line=19 for tag=domain_id: expand environment variable in element text
[/routing_services/default|CREATE] ROUTERXmlVariableExpansor_visit:!parse at line=19 for tag=domain_id
...

12.1.2. How to Load Default QoS Profiles

Generally, loading a default QoS profile follows the same mechanism as Connext DDS applications. The details on how to specify default QoS profiles in XML is explained in the section Overwriting Default QoS in the RTI Connext DDS Core Libraries User’s Manual.

In short, you will need to mark a profile as the default using the is_default_qos attribute. For RTI Services, you will need to do this as part of the default file USER_QOS_PROFILES.xml (see Default Files). This requirement is necessary since the default QoS profiles are parsed by the underlying DomainParticipantFactory and not the service itself.

Warning

Marking as default a QoS profile defined in a different file than USER_QOS_PROFILES.xml will have no effect.

12.1.3. How to Set Logging Properties

You can configure different aspects of the logging infrastructure that is part of RTI Services and Connext DDS. This section describes different ways to set these logging properties.

12.1.3.1. Command-Line Options

The shipped executable for an RTI Service typically offers some out-of-the-box options to configure logging. Typically, you will find these options:

  • -verbosity sets the verbosity level for the messages generated by the service and Connext DDS.

  • -logFormat configures the format of the log messages, such as whether they contain timestamps, thread IDs, etc.

  • -logFile redirects the logging to a specified text file.

You can refer to the Usage section of each individual product user’s manual for further details.

12.1.3.2. Service API

To configure the service-level verbosity, use the Logger singleton class part of the service API. For example, the following sets WARNING level for the service logs in RTI Routing Service. For other services change the preceding rti::routing prefix to match the RTI Service you are working with.

rti::routing::Logger::instance().service_verbosity(
        rti::config::Verbosity::WARNING);

To configure the Connext DDS-level verbosity (for logs generated by the DDS libraries), you can use the Connext DDS configuration logger API. For example, the following sets WARNING level for the Connext DDS logs:

rti::config::Logger::instance().verbosity(
        rti::config::Verbosity::WARNING);

For the remaining overall logging properties, such as the log format, output file, and so on, you can also use the Connext DDS configuration logger API. For example, to redirect the logging to an output file:

rti::config::Logger::instance().output_file(my_service_logs.txt);

12.1.3.3. XML Configuration

As an alternative to the previous two methods, you can configure some logging properties through the LoggingQosPolicy which can be specified in XML. For more information, see the LOGGING QosPolicy (DDS Extension) in the RTI Connext DDS Core Libraries User’s Manual.

The Logging QoS is configured within the <participant_factory_qos> that is part of a QoS profile. Since multiple profiles can be present in the loaded XML document, to tell Connext DDS which one to use, you will need to mark the profile as the default using the is_default_qos attribute, or for the DomainParticipantFactory, the is_default_participant_factory_profile attribute.

See How to Load Default QoS Profiles for details on how to load default QoS profiles with RTI Services. For example, you can set different properties for the logger by placing the XML code seen below in the USER_QOS_PROFILES.xml default file:

<dds>
    <qos_library name="DefaultLibrary">
        <qos_profile name="DefaultProfile" is_default_participant_factory_profile ="true">
            <participant_factory_qos>
                <logging>
                    <!-- this element affects Connext logs only -->
                    <verbosity>ALL</verbosity>
                    <!-- for all Connext and Service logs -->
                    <category>ENTITIES</category>
                    <print_format>MAXIMAL</print_format>
                    <output_file>LoggerOutput1.txt</output_file>
                </logging>
            </participant_factory_qos>
        </qos_profile>
    </qos_library>
</dds>

See also

Controlling Messages from Connext DDS

Describes the types of logging messages and how to use the logger to enable them.

Identifying Threads used by Connext DDS

Describes the logging messages that provide thread-context information.

12.1.4. How to Run as an Operating System Daemon

Certain Operating Systems offer the capability to run processes in the background and non-interactively. On Linux or macOS systems, this is referred to as daemon processes. On Windows systems, this is referred to as a service.

How to run a process as a daemon depends on the OS and in some cases there are multiple options. This section describes the most common way to run an RTI Service as a daemon of the main OS.

12.1.4.1. Linux and macOS Systems

The simplest and more portable way requires you to use the Service API to create your own executable that instantiates the RTI Service and sets the running process as a daemon using the daemon() API. For example, for RTI Routing Service:

#include <stdlib.h>
#include "rti/routing/Service.hpp"

int main(int argc, char **argv)
{
    using namespace rti::routing;

    if (daemon(0,0)) {
        Logger::instance().error("Failed to create daemon process\n");
        return -1;
    }

    // parse arguments and configure ServiceProperty
    ServiceProperty property;
    property.cfg_file(argv[1]);
    ...
    Service service(property);

    service.start();
}

The above code generates an executable that runs the process as a daemon with zero-value arguments, indicating that the working directory is / and the standard output is redirected to /dev/null. You can find more information about the daemon() in the user man pages.

Note that if you link the application dynamically, you will need to guarantee that the dependency libraries are available as part of the library path. An alternative is to link the applications statically.

12.1.4.2. Windows Systems

To run a process as a Windows Service we recommend using the third party tool Non-Sucking Service Manager (NSSM). This tool allows you to run an existing executable as a service, while adjusting environment variables and command-line arguments.

Hence you can use NSSM to run the shipped executable of an RTI Service. For example, for Routing Service you can run:

nssm install myRouterService <rtiroutingservice> "-cfgName default"

The above command will install a service named myRouterService on your Windows system that runs Routing Service with the default configuration. Then you can manage the service with the nssm GUI utility itself or the Windows Services Control Manager (select Control Panel -> Administrative Services -> Services).

The example above causes the service to use the executable directory as the working directory and relies on the default configuration file in [NDDSHOME]/resource/xml. You can specify a different working directory as well as different command-line arguments as follows:

nssm set myRouterService AppDirectory <my_working_dir>
nssm set myRouterService AppParameters "-cfgFile my_router.xml -cfgName MyRoute"

Alternatively, you can use the Service API to embed the RTI Service into your own executable and implement the Windows Service APIs to run the executable as a Windows Service. (see How to: Create Windows Services).

Here are some things to consider when running an RTI Service as a Windows Service:

  • All AppParameters arguments must be enclosed in quotation marks.

  • If you specify -cfgFile in the Start Parameters field, you must use the full path to the file.

  • Some versions of Windows do not allow Windows Services to communicate with other services/applications using shared memory. In such case, you will need to disable the shared memory transport in all DomainParticipants created by the RTI Service.

  • In some scenarios, you may need to add a multicast address to your discovery peers or simply use RTI Cloud Discovery Service.

12.1.5. How to use a License File with RTI Services

If your RTI Connext DDS distribution requires a license file, you will receive one from RTI via email. To install the license file, follow the instructions in Installing RTI Connext DDS, in the RTI Connext DDS Installation Guide. Alternatively, you can provide the RTI Service with the path to your license file using either the -licenseFile command-line argument or the license_file_name field in the Service Property of the Service API.

Note

Some RTI Services do not require a license file.

Check the command line arguments list for the RTI Service to see if a -licenseFile argument exists. If it doesn’t, you can use the RTI Service without a license file.

OR

Check the Service API documentation for the RTI Service in the language of your choice for a license_file_name or similar Service Property field. If such a field does not exist, you can use the RTI Service without a license file.

Each time your RTI Service starts, it looks for the license file in the following locations, in order, until it finds a valid license:

  1. The file specified in the environment variable RTI_LICENSE_FILE, which you may set to point to the full path of the license file, including the filename. For example, on Linux:

    export RTI_LICENSE_FILE=/home/username/my_rti_license.dat
    
  2. The file rti_license.dat in the current working directory.

  3. The file rti_license.dat in the directory specified by the environment variable NDDSHOME.

12.1.6. Key Terms

XML document

The input XML contained within the <dds> root, which contains one or more configurations for an RTI Service.

Configuration name

Unique identification of a service top-level configuration element. Provided with the name attribute.

Configuration variable

An RTI-specific construct to be used in XML to define content that can be expanded at run time.

Shipped executable

An RTI-provided command-line executable that runs an RTI Service.

Service API

Public API that allows you to embed an RTI Service into your custom application.