.. include:: ../../../router.1.0/srcDoc/vars.rst .. _section-Common-Config: ********************************** Configuring |RTI_SERVICEs_HEADING| ********************************** |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. 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** |br| 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** |br| 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. Loading from Files ------------------ |RTI_SERVICEs| can receive a list of file paths separated by semicolons (``;``): .. code-block:: console 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 [#f1]_. .. tabs:: .. group-tab:: Shipped Executable 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: .. tabs:: .. group-tab:: |RTI_ROUTINGSERVICE| .. code-block:: console $NDDSHOME/bin/rtiroutingservice -cfgFile "file.xml;/home/file2.xml" .. group-tab:: |RTI_RECS| .. code-block:: console $NDDSHOME/bin/rtirecordingservice -cfgFile "file.xml;/home/file2.xml" .. group-tab:: |RTI_CDS| .. code-block:: console $NDDSHOME/bin/rticlouddiscoveryservice -cfgFile "file.xml;/home/file2.xml" where ``[NDDSHOME]`` indicates the path to your |CONNEXT| installation. .. group-tab:: Service API Set the ``ServiceProperty::cfg_file`` member. For example in C++: .. code-block:: C++ :emphasize-lines: 2 ServiceProperty property; property.cfg_file("file.xml;/home/file2.xml"); ... Service service(property); .. [#f1] Service API may not be available for certain |RTI_SERVICEs|. 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++: .. code-block:: C++ :emphasize-lines: 3,5,6 std::vector xml_strings; xml_strings.resize(2); /* This sample demonstrates using Routing Service */ xml_strings[0] = ""; xml_strings[1] = ""; property.cfg_strings(xml_strings); ... Service service(property); 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. .. tabs:: .. group-tab:: |RTI_ROUTINGSERVICE| .. code-block:: xml ... ... .. group-tab:: |RTI_RECS| .. code-block:: xml ... ... .. group-tab:: |RTI_CDS| .. code-block:: xml ... ... You can run the configuration for ``Service1`` as follows: .. tabs:: .. group-tab:: Shipped Executable Use the ``-cfgName`` option. For example, on Linux systems: .. tabs:: .. group-tab:: |RTI_ROUTINGSERVICE| .. code-block:: console $NDDSHOME/bin/rtiroutingservice -cfgFile MyService.xml -cfgName Service1 .. group-tab:: |RTI_RECS| .. code-block:: console $NDDSHOME/bin/rtirecordingservice -cfgFile MyService.xml -cfgName Service1 .. group-tab:: |RTI_CDS| .. code-block:: console $NDDSHOME/bin/rticlouddiscoveryservice -cfgFile MyService.xml -cfgName Service1 .. group-tab:: Service API Set the ``ServiceProperty::cfg_name`` member. For example in C++: .. code-block:: C++ :emphasize-lines: 3 ServiceProperty property; property.cfg_file("MyService.xml"); property.cfg_name("Service1"); ... Service service(property); .. _section-Default-Files: Default Files ------------- In addition to manually providing input XML files, |RTI_SERVICEs| also attempt to automatically load a set of files from predefined locations: .. list-table:: |RTI_SERVICEs_HEADING| Default Files :name: TableDefaultFiles :widths: 60 40 :header-rows: 1 :class: longtable * - 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_ROUTINGSERVICE| - ``RECORDING_SERVICE`` for |RTI_RECS| - ``CLOUD_DISCOVERY_SERVICE`` for |RTI_CDS| These files are loaded only if present. You can disable the loading of default files by using the proper option: .. tabs:: .. group-tab:: Shipped Executable Use the ``-skipDefaultFiles`` option. .. group-tab:: Service API Set the ``ServiceProperty::skip_default_files`` member to true. .. _section-Common-XmlValidation: 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 :link_xml_spec:`the Extensible Markup Language standard <>`. - It shall use UTF-8 character encoding for XML elements and values. - It shall use ```` 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_CDS|: .. code-block:: console 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: .. tabs:: .. group-tab:: Shipped Executable Use the ``-ignoreXsdValidation`` option. .. group-tab:: Service API 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_ROUTINGSERVICE| - ``recording_service`` for |RTI_RECS| - ``cloud_discovery_service`` for |RTI_CDS| To include a reference to the XSD document in your XML file, use the attribute ``xsi:noNamespaceSchemaLocation`` in the ```` tag. For example: .. code-block:: xml .. 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. 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: .. tabs:: .. group-tab:: |RTI_ROUTINGSERVICE| .. code-block:: console 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 .. group-tab:: |RTI_CDS| .. code-block:: console 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 ```` tag if present. This operation lists all the configurations detected from the specified input XML document from all the locations and files. 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: .. code-block:: console $(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. .. code-block:: xml my expanded $(VAR_TEXT) The possible ways a variable can be expanded are listed below in precedence order: #. Process environment. .. code-block:: console export VAR_NAME=my_value #. Using a specific option when running the service. .. tabs:: .. group-tab:: Shipped Executable Use the ``-DVAR_NAME=VALUE`` option .. code-block:: console $ ... -DVAR_NAME=my_value where ```` is one of ``rtiroutingservice``, ``rtirecordingservice`` or ``rticlouddiscoveryservice``. .. group-tab:: Service API Set the ``ServiceProperty::user_environment`` member .. code-block:: C++ ServiceProperty property; property.user_environment()["VAR_NAME"] = "var_value"; ... #. ```` section, which represents an unbounded list of variable name-variable value pairs. .. code-block:: xml VAR_NAME var_value ... 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: .. code-block:: console export VAR_ATTR=expanded_attr ... -DVAR_TEXT=expanded_text where ```` is one of ``rtiroutingservice``, ``rtirecordingservice`` or ``rticlouddiscoveryservice``, will result in the following actual parsed XML with the expanded variables: .. code-block:: xml my expanded expanded_text 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_ROUTINGSERVICE|: .. code-block:: console [/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 ... .. _section-Common-Config-DefaultQos: How to Load Default QoS Profiles ================================ Generally, loading a default QoS profile follows the same mechanism as |CONNEXT| applications. The details on how to specify default QoS profiles in XML is explained in the section :link_connext_users_man_up_5_s:`Overwriting Default QoS ` in the |RTI_CONNEXT| *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 :ref:`section-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. .. _section-Common-Config-Logging: How to Set Logging Properties ============================= You can configure different aspects of the logging infrastructure that is part of |RTI_SERVICEs| and |CONNEXT|. This section describes different ways to set these logging properties. 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|. - ``-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. 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_ROUTINGSERVICE|. For other services change the preceding ``rti::routing`` prefix to match the |RTI_SERVICE| you are working with. .. code-block:: C++ rti::routing::Logger::instance().service_verbosity( rti::config::Verbosity::WARNING); To configure the |CONNEXT|\-level verbosity (for logs generated by the DDS libraries), you can use the |CONNEXT| configuration logger API. For example, the following sets ``WARNING`` level for the |CONNEXT| logs: .. code-block:: C++ 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| configuration logger API. For example, to redirect the logging to an output file: .. code-block:: C++ rti::config::Logger::instance().output_file(my_service_logs.txt); 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 :link_connext_users_man_up_5_s:`LOGGING QosPolicy (DDS Extension) ` in the |RTI_CONNEXT| *Core Libraries User's Manual*. The Logging QoS is configured within the ```` that is part of a QoS profile. Since multiple profiles can be present in the loaded XML document, to tell |CONNEXT| 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 :ref:`section-Common-Config-DefaultQos` 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: .. code-block:: xml ALL ENTITIES MAXIMAL LoggerOutput1.txt .. seealso:: :link_connext_users_man_up_5_s:`Controlling Messages from Connext DDS ` Describes the types of logging messages and how to use the logger to enable them. :link_connext_users_man_up_5_s:`Identifying Threads used by Connext DDS ` Describes the logging messages that provide thread-context information. .. _section-Common-Config-Deamon: 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. 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_ROUTINGSERVICE|: .. code-block:: C++ :emphasize-lines: 8 #include #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. 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 |RS| you can run: .. code-block:: console nssm install myRouterService "-cfgName default" The above command will install a service named ``myRouterService`` on your Windows system that runs |RS| 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: .. code-block:: console nssm set myRouterService AppDirectory 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 |DPs| 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*. .. _section-Common-HowToUseLicenseFile-RTIServices: How to use a License File with |RTI_SERVICEs_HEADING| ===================================================== If your |RTI_CONNEXT| distribution requires a license file, you will receive one from RTI via email. To install the license file, follow the instructions in :link_connext_ig_install_up_5:`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: #. 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: .. code-block:: console export RTI_LICENSE_FILE=/home/username/my_rti_license.dat #. The file ``rti_license.dat`` in the current working directory. #. The file ``rti_license.dat`` in the directory specified by the environment variable ``NDDSHOME``. Key Terms ========= .. glossary:: XML document The input XML contained within the ```` 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.