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 opeating 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"
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);
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 for RTI Recording Service:
<dds>
<recording_service name="Service1"> ... </recording_service>
<recording_service name="Service2"> ... </recording_service>
</dds>
You can run the configuration for Service1
as follows:
Use the -cfgName
option.
For example in Linux:
$ NDDSHOME/bin/rtiroutingservice -cfgFile file.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:
File |
Allowed Content |
---|---|
|
|
|
|
|
|
where [SERVICE]
refers to the concrete product name in uppercase.
For example ROUTING_SERVICE
for RTI Routing Service or
RECORDING_SERVICE
for RTI Recording 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:
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 or recording_service
for RTI Recording 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:
rtiroutingservice -listConfig
Available configurations:
- default:(/Users/asanchez/rti/waveworks/develop/router.1.0/resource/xml/RTI_ROUTING_SERVICE.xml)
Routes all topics from domain 0 to domain 1
- defaultBothWays:(/Users/asanchez/rti/waveworks/develop/router.1.0/resource/xml/RTI_ROUTING_SERVICE.xml)
Routes all topics from domain 0 to domain 1 and the other way around
- defaultReliable:(/Users/asanchez/rti/waveworks/develop/router.1.0/resource/xml/RTI_ROUTING_SERVICE.xml)
Routes all topics from domain 0 to domain 1 using reliable communication
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:
Process environment.
export VAR_NAME=my_value
Using a specific option when running the service.
Use the
-DVAR_NAME=VALUE
optionrtirecordingservice ... -DVAR_NAME=my_value
Set the
ServiceProperty::user_environment
memberServiceProperty property; property.user_environment()["VAR_NAME"] = "var_value"; ...
<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
rtiroutingservice ... -DVAR_TEXT=expanded_text
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:
[/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:
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>
</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 deamon()
API. For example, for
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:
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:
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. 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.