##### QoS Provider

- Introduction
- API reference
- - Introduction
  - constructor
  - get_participant_qos
  - get_topic_qos
  - get_subscriber_qos
  - get_datareader_qos
  - get_publisher_qos
  - get_datawriter_qos
- XML file syntax
- Example
- Known limitations

## Introduction

This note provides information on using the QoS provider API of Vortex OpenSplice. The QoS provider API allows users to specify the QoS settings of their DCPS entities outside of application code in XML. The following sections explain the API in a language independent manner and explain how to build QoS Profiles in XML.

## API reference - Introduction

The QosProvider is delivered as part of the DCPS API of Vortex OpenSplice and has no factory. It is created as an object directly by the natural means in each language binding (e.g., using "new" in C#, C++ or Java and "DDS_QosProvider__alloc" in C). This is because it is not necessarily associated with a single DomainParticipant. Below you'll find an overview of the available operations, which are explained in detail in the following subsections.

    module DDS {
        local interface QosProviderInterface {
            //constructor (
            //   in string uri,
            //   in string profile);

            ReturnCode_t
            get_participant_qos (
                inout DomainParticipantQos a_participant_qos,
                in string id);

            ReturnCode_t
            get_topic_qos (
                inout TopicQos a_topic_qos,
                in string id);

            ReturnCode_t
            get_subscriber_qos (
                inout SubscriberQos a_subscriber_qos,
                in string id);

            ReturnCode_t
            get_datareader_qos (
                inout DataReaderQos a_datareader_qos,
                in string id);

            ReturnCode_t
            get_publisher_qos (
                inout PublisherQos a_publisher_qos,
                in string id);

            ReturnCode_t
            get_datawriter_qos (
                inout DataWriterQos a_datawriter_qos,
                in string id);
        };
    };

## API reference - constructor

        /**
          * Constructs a new QosProvider based on the provided uri and profile.
          *
          * The QosProvider is delivered as part of the DCPS API of
          * Vortex OpenSplice and has no factory. It is created as an object
          * directly by the natural means in each language binding (e.g., using
          * "new" in C#, C++ or Java and "DDS_QosProvider__alloc" in C)
          *
          * @param uri     A Uniform Resource Identifier (URI that points to the
          *                location where the QoS profile needs to be loaded
          *                from. Currently only URI's with a "file" scheme that
          *                point to an XML file are supported. If profiles
          *                and/or QoS settings are not uniquely identifiable by
          *                name within the resource pointed to by the uri, a random
          *                one of them will be stored.
          *
          * @param profile The name of the QoS profile that serves as the default
          *                QoS profile for the get_*_qos operations.
          *
          * @return        A QosProvider instance that is instantiated with all
          *                profiles and/or QoS-ses loaded from the location
          *                specified by the provided uri. Construction of the
          *                QosProvider will fail under the following conditions:
          *                - No uri is provided.
          *                - The resource pointed to by uri cannot be found.
          *                - The content of the resource pointed to by uri is
          *                  malformed (e.g. malformed XML).
          */
        constructor (
           in string uri,
           in string profile);

## API reference - get_participant_qos

        /**
          * Resolves the DomainParticipantQos identified by the id from the
          * uri the QosProvider is associated with.
          *
          * @param a_qos The DomainParticipantQos which is initialized by the
          *              operation if the DomainParticipantQos identified by the id
          *              parameter can be found and no other errors have occurred.
          *              If and only if the operation returns OK, this parameter
          *              will be initialized properly after the operation.
          *
          * @param id    The fully-qualified name that identifies a QoS within the
          *              uri associated with the QosProvider or a name that
          *              identifies a QoS within the uri associated with the
          *              QosProvider instance relative to its default QoS profile.
          *              Id's starting with "::" are interpreted as fully-qualified
          *              names and all others are interpreted as names relative to
          *              the default QoS profile of the QosProvider instance. A
          *              nil id is interpreted as a non-named QoS within the
          *              default QoS profile associated with the QosProvider.
          *
          * @return      OK                    - if a_qos has been initialized
          *                                      successfully.
          *
          *              NO_DATA               - if no DomainParticipantQos that
          *                                      matches the provided id can be
          *                                      found within the uri associated
          *                                      with the QosProvider.
          *
          *              BAD_PARAMETER         - if a_qos is nil.
          *
          *              PRE_CONDITION_NOT_MET - if the QosProvider instance is not
          *                                      properly initialized.
          *
          *              OUT_OF_RESOURCES      - if not enough memory is available
          *                                      to perform the operation.
          *
          *              ERROR                 - if an internal error occurred.
          */
          ReturnCode_t
          get_participant_qos (
              inout DomainParticipantQos a_qos,
              in string id);

## API reference - get_topic_qos

        /**
          * Resolves the TopicQos identified by the id from the
          * uri the QosProvider is associated with.
          *
          * @param a_qos The TopicQos which is initialized by the
          *              operation if the TopicQos identified by the id
          *              parameter can be found and no other errors have occurred.
          *              If and only if the operation returns OK, this parameter
          *              will be initialized properly after the operation.
          *
          * @param id    The fully-qualified name that identifies a QoS within the
          *              uri associated with the QosProvider or a name that
          *              identifies a QoS within the uri associated with the
          *              QosProvider instance relative to its default QoS profile.
          *              Id's starting with "::" are interpreted as fully-qualified
          *              names and all others are interpreted as names relative to
          *              the default QoS profile of the QosProvider instance. A
          *              nil id is interpreted as a non-named QoS within the
          *              default QoS profile associated with the QosProvider.
          *
          * @return      OK                    - if a_qos has been initialized
          *                                      successfully.
          *
          *              NO_DATA               - if no TopicQos that
          *                                      matches the provided id can be
          *                                      found within the uri associated
          *                                      with the QosProvider.
          *
          *              BAD_PARAMETER         - if a_qos is nil.
          *
          *              PRE_CONDITION_NOT_MET - if the QosProvider instance is not
          *                                      properly initialized.
          *
          *              OUT_OF_RESOURCES      - if not enough memory is available
          *                                      to perform the operation.
          *
          *              ERROR                 - if an internal error occurred.
          */
          ReturnCode_t
          get_topic_qos (
              inout TopicQos a_qos,
              in string id);

## API reference - get_subscriber_qos

        /**
          * Resolves the SubscriberQos identified by the id from the
          * uri the QosProvider is associated with.
          *
          * @param a_qos The SubscriberQos which is initialized by the
          *              operation if the DomainParticipantQos identified by the id
          *              parameter can be found and no other errors have occurred.
          *              If and only if the operation returns OK, this parameter
          *              will be initialized properly after the operation.
          *
          * @param id    The fully-qualified name that identifies a QoS within the
          *              uri associated with the QosProvider or a name that
          *              identifies a QoS within the uri associated with the
          *              QosProvider instance relative to its default QoS profile.
          *              Id's starting with "::" are interpreted as fully-qualified
          *              names and all others are interpreted as names relative to
          *              the default QoS profile of the QosProvider instance. A
          *              nil id is interpreted as a non-named QoS within the
          *              default QoS profile associated with the QosProvider.
          *
          * @return      OK                    - if a_qos has been initialized
          *                                      successfully.
          *
          *              NO_DATA               - if no SubscriberQos that
          *                                      matches the provided id can be
          *                                      found within the uri associated
          *                                      with the QosProvider.
          *
          *              BAD_PARAMETER         - if a_qos is nil.
          *
          *              PRE_CONDITION_NOT_MET - if the QosProvider instance is not
          *                                      properly initialized.
          *
          *              OUT_OF_RESOURCES      - if not enough memory is available
          *                                      to perform the operation.
          *
          *              ERROR                 - if an internal error occurred.
          */
          ReturnCode_t
          get_subscriber_qos (
              inout SubscriberQos a_qos,
              in string id);

## API reference - get_datareader_qos

        /**
          * Resolves the DataReaderQos identified by the id from the
          * uri the QosProvider is associated with.
          *
          * @param a_qos The DataReaderQos which is initialized by the
          *              operation if the DataReaderQos identified by the id
          *              parameter can be found and no other errors have occurred.
          *              If and only if the operation returns OK, this parameter
          *              will be initialized properly after the operation.
          *
          * @param id    The fully-qualified name that identifies a QoS within the
          *              uri associated with the QosProvider or a name that
          *              identifies a QoS within the uri associated with the
          *              QosProvider instance relative to its default QoS profile.
          *              Id's starting with "::" are interpreted as fully-qualified
          *              names and all others are interpreted as names relative to
          *              the default QoS profile of the QosProvider instance. A
          *              nil id is interpreted as a non-named QoS within the
          *              default QoS profile associated with the QosProvider.
          *
          * @return      OK                    - if a_qos has been initialized
          *                                      successfully.
          *
          *              NO_DATA               - if no DataReaderQos that
          *                                      matches the provided id can be
          *                                      found within the uri associated
          *                                      with the QosProvider.
          *
          *              BAD_PARAMETER         - if a_qos is nil.
          *
          *              PRE_CONDITION_NOT_MET - if the QosProvider instance is not
          *                                      properly initialized.
          *
          *              OUT_OF_RESOURCES      - if not enough memory is available
          *                                      to perform the operation.
          *
          *              ERROR                 - if an internal error occurred.
          */
          ReturnCode_t
          get_datareader_qos (
              inout DataReaderQos a_qos,
              in string id);

## API reference - get_publisher_qos

        /**
          * Resolves the PublisherQos identified by the id from the
          * uri the QosProvider is associated with.
          *
          * @param a_qos The PublisherQos which is initialized by the
          *              operation if the PublisherQos identified by the id
          *              parameter can be found and no other errors have occurred.
          *              If and only if the operation returns OK, this parameter
          *              will be initialized properly after the operation.
          *
          * @param id    The fully-qualified name that identifies a QoS within the
          *              uri associated with the QosProvider or a name that
          *              identifies a QoS within the uri associated with the
          *              QosProvider instance relative to its default QoS profile.
          *              Id's starting with "::" are interpreted as fully-qualified
          *              names and all others are interpreted as names relative to
          *              the default QoS profile of the QosProvider instance. A
          *              nil id is interpreted as a non-named QoS within the
          *              default QoS profile associated with the QosProvider.
          *
          * @return      OK                    - if a_qos has been initialized
          *                                      successfully.
          *
          *              NO_DATA               - if no PublisherQos that
          *                                      matches the provided id can be
          *                                      found within the uri associated
          *                                      with the QosProvider.
          *
          *              BAD_PARAMETER         - if a_qos is nil.
          *
          *              PRE_CONDITION_NOT_MET - if the QosProvider instance is not
          *                                      properly initialized.
          *
          *              OUT_OF_RESOURCES      - if not enough memory is available
          *                                      to perform the operation.
          *
          *              ERROR                 - if an internal error occurred.
          */
          ReturnCode_t
          get_publisher_qos (
              inout PublisherQos a_qos,
              in string id);

## API reference - get_datawriter_qos

        /**
          * Resolves the DataWriterQos identified by the id from the
          * uri the QosProvider is associated with.
          *
          * @param a_qos The DataWriterQos which is initialized by the
          *              operation if the DataWriterQos identified by the id
          *              parameter can be found and no other errors have occurred.
          *              If and only if the operation returns OK, this parameter
          *              will be initialized properly after the operation.
          *
          * @param id    The fully-qualified name that identifies a QoS within the
          *              uri associated with the QosProvider or a name that
          *              identifies a QoS within the uri associated with the
          *              QosProvider instance relative to its default QoS profile.
          *              Id's starting with "::" are interpreted as fully-qualified
          *              names and all others are interpreted as names relative to
          *              the default QoS profile of the QosProvider instance. A
          *              nil id is interpreted as a non-named QoS within the
          *              default QoS profile associated with the QosProvider.
          *
          * @return      OK                    - if a_qos has been initialized
          *                                      successfully.
          *
          *              NO_DATA               - if no DataWriterQos that
          *                                      matches the provided id can be
          *                                      found within the uri associated
          *                                      with the QosProvider.
          *
          *              BAD_PARAMETER         - if a_qos is nil.
          *
          *              PRE_CONDITION_NOT_MET - if the QosProvider instance is not
          *                                      properly initialized.
          *
          *              OUT_OF_RESOURCES      - if not enough memory is available
          *                                      to perform the operation.
          *
          *              ERROR                 - if an internal error occurred.
          */
          ReturnCode_t
          get_datawriter_qos (
              inout DataWriterQos a_qos,
              in string id);

## XML file syntax

The XML configuration file must follow these syntax rules:

- The syntax is XML and the character encoding is UTF-8.
- Opening tags are enclosed in <>; closing tags are enclosed in </>.
- A value is a UTF-8 encoded string. Legal values are alphanumeric characters.
- All values are case-sensitive unless otherwise stated.
- Comments are enclosed as follows: <!-- comment -->.
- The root tag of the configuration file must be and end with .

Please also see: OMG DDS4CCM specification for more details on the exact notation.

The primitive types for tag values are specified in the following table:

Type | Format | Notes
--- | --- | ---
Boolean | yes, 1, true or BOOLEAN_TRUE | Not case-sensitive
| no, 0, false or BOOLEAN_FALSE |
Enum | A string. Legal values are the ones defined for QoS Policies in the DCPS IDL of DDS specification. | Must be specified as a string. (Do not use numeric values.)
Long | -2147483648 to 2147483647 or 0x80000000 to 0x7fffffff or LENGTH_UNLIMITED | A 32-bit signed integer
UnsignedLong | 0 to 4294967296 or 0 to 0xffffffff | A 32-bit unsigned integer

## XML file syntax - Entity QoS

To configure the QoS for a DDS Entity using XML, the following tags have to be used:

- <domainparticipant_qos>
- <publisher_qos>
- <subscriber_qos>
- <topic_qos>
- <datawriter_qos>
- <datareader_qos>

Each XML tag with an associated name can be uniquely identified by its fully qualified name in C++ style.

## XML file syntax - Entity QoS - QoS Policies

The fields in a QosPolicy are described in XML using a 1-to-1 mapping with the equivalent IDL representation in the DDS specification. For example, the Reliability QosPolicy is represented with the following structures:

    struct Duration_t {
        long sec;
        unsigned long nanosec;
    };

    struct ReliabilityQosPolicy {
        ReliabilityQosPolicyKind kind;
        Duration_t max_blocking_time;
    };

The equivalent representation in XML is as follows:

    <reliability>
        <kind></kind>
        <max_blocking_time>
            <sec></sec>
            <nanosec></nanosec>
        </max_blocking_time>
    </reliability>

## XML file syntax - Entity QoS - Sequences

In general, the sequences contained in the QoS policies are described with the following XML format:

    <a_sequence_member_name>
        <element>...</element>
        <element>...</element>
        ...
    </a_sequence_member_name>

Each element of the sequence is enclosed in an <element> tag., as shown in the following example:

    <property>
        <value>
            <element>
                <name>my name</name>
                <value>my value</value>
            </element>
            <element>
                <name>my name2</name>
                <value>my value2</value>
            </element>
        </value>
    </property>

A sequence without elements represents a sequence of length 0. For example: <a_sequence_member_name/> As a special case, sequences of octets are represented with a single XML tag enclosing a sequence of decimal/hexadecimal values between 0..255 separated with commas. For example:

    <user_data>
        <value>100,200,0,0,0,223</value>
    </user_data>
    <topic_data>
        <value>0xff,0x00,0x8e,0xEE,0x78</value>
    </topic_data>

## XML file syntax - Entity QoS - Arrays

In general, the arrays contained in the QoS policies are described with the following XML format:

    <an_array_member_name>
        <element>...</element>
        <element>...</element>
        ...
    </an_array_member_name>

Each element of the array is enclosed in an <element> tag. As a special case, arrays of octets are represented with a single XML tag enclosing an array of decimal/hexadecimal values between 0..255 separated with commas. For example:

    <datareader_qos>
        ...
        <user_data>
            <value>100,200,0,0,0,223</value>
        </user_data>
    </datareader_qos>

## XML file syntax - Entity QoS - Enumerations

Enumeration values are represented using their IDL string representation. For example:

    <history>
        <kind>KEEP_ALL_HISTORY_QOS</kind>
    </history>

## XML file syntax - Entity QoS - Time values (Durations)

Following values can be used for fields that require seconds or nanoseconds:

- DURATION_INFINITE_SEC
- DURATION_ZERO_SEC
- DURATION_INFINITE_NSEC
- DURATION_ZERO_NSEC

The following example shows the use of time values:

    <deadline>
        <period>
            <sec>DURATION_INFINITE_SEC</sec>
            <nanosec>DURATION_INFINITE_NSEC</nanosec>
        </period>
    </deadline>

## XML file syntax - QoS profiles

A QoS profile groups a set of related QoS, usually one per entity. For example:

    <qos_profile name="StrictReliableCommunicationProfile">
        <datawriter_qos>
            <history>
                <kind>KEEP_ALL_HISTORY_QOS</kind>
            </history>
            <reliability>
                <kind>RELIABLE_RELIABILITY_QOS</kind>
            </reliability>
        </datawriter_qos>
        <datareader_qos>
            <history>
                <kind>KEEP_ALL_HISTORY_QOS</kind>
            </history>
            <reliability>
                <kind>RELIABLE_RELIABILITY_QOS</kind>
            </reliability>
        </datareader_qos>
    </qos_profile>

## XML file syntax - QoS profiles - QoS Profiles with a Single QoS

The definition of an individual QoS is a shortcut for defining a QoS profile with a single QoS. For example:

    <datawriter_qos name="KeepAllWriter">
        <history>
            <kind>KEEP_ALL_HISTORY_QOS</kind>
        </history>
    </datawriter_qos>

is equivalent to the following:

    <qos_profile name="KeepAllWriter">
        <writer_qos>
            <history>
                <kind>KEEP_ALL_HISTORY_QOS</kind>
            </history>
        </writer_qos>
    </qos_profile>

## Example

consider the following XML file that describes two QoS profiles;

- FooQosProfile
  - DataReaderQos - TransientKeepLast
  - DataWriterQos - Transient
- BarQosProfile
  - DataWriterQos - Persistent

    <dds xmlns="http://www.omg.org/dds/"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="file://DDS_QoSProfile.xsd">
        <qos_profile name="FooQosProfile">
            <datareader_qos name="TransientKeepLast">
                <durability>
                    <kind>TRANSIENT_DURABILITY_QOS</kind>
                </durability>
                <history>
                   <kind>KEEP_LAST_HISTORY_QOS</kind>
                   <depth>5</depth>
                </history>
            </datareader_qos>
            <datawriter_qos name="Transient">
                <durability>
                    <kind>TRANSIENT_DURABILITY_QOS</kind>
                </durability>
            </datawriter_qos>
        </qos_profile>
        <qos_profile name="BarQosProfile">
            <datawriter_qos name="Persistent">
                <durability>
                    <kind>PERSISTENT_DURABILITY_QOS</kind>
                </durability>
            </datawriter_qos>
        </qos_profile>
    </dds>

The following Java application is an example to illustrate how the QoS settings from the above XML could be accessed.

    package org.opensplice.example;

    import DDS.*;

    public class QosProviderExample {

        public static void main(String[] args) {
            QosProvider provider = null;
            DataReaderQosHolder drQosHolder = new DataReaderQosHolder();
            DataWriterQosHolder dwQosHolder = new DataWriterQosHolder();
            DataWriterQosHolder dwBarQosHolder = new DataWriterQosHolder();
            int result;

            try{
                provider = new QosProvider(
                        "file://path/to/file.xml",
                        "FooQosProfile");

                 /* As default QoS profile is "FooQosProfile", requesting
                  * "TransientKeepLast" in this case is equivalent to requesting
                  * "::FooQosProfile::TransientKeepLast".
                  */
                 result = provider.get_datareader_qos(drQosHolder, "TransientKeepLast");

                 if(result != RETCODE_OK.value){
                     System.err.println("Unable to resolve ReaderQos.");
                     System.exit(1);
                 }
                 /* As default QoS profile is "FooQosProfile", requesting
                  * "Transient" would have been equivalent to requesting
                  * "::FooQosProfile::Transient".
                  */
                 result = provider.get_datawriter_qos(dwQosHolder, "::FooQosProfile::Transient");

                 if(result != RETCODE_OK.value){
                     System.err.println("Unable to resolve WriterQos.");
                     System.exit(1);
                 }
                 /* As default QoS profile is "FooQosProfile" it is necessary
                  * to use the fully-qualified name to get access to QoS-ses from
                  * the "BarQosProfile".
                  */
                 result = provider.get_datawriter_qos(dwBarQosHolder, "::BarQosProfile::Persistent");

                 if(result != RETCODE_OK.value){
                     System.err.println("Unable to resolve WriterQos.");
                     System.exit(1);
                 }

                 /* Create DDS DataReader with drQosHolder.value DataReaderQos,
                  * DDS DataWriter with dwQosHolder.value DataWriterQos and
                  * DDS DataWriter with dwBarQosHolder.value DataWriterQos
                  */

            } catch(NullPointerException npe){
                System.err.println("Initialization of QosProvider failed.");
            }
            return;
        }
    }

## Known limitations

- Inheritance of QoS policies and QoS profiles in XML using the "base_name" attribute is not supported yet.
- The "topic_filter" attribute for writer,reader, and topic QoSs to associate a set of topics to a specific QoS when that QoS is part of a DDS profile, is not supported yet.
- All leading and trailing spaces should be removed from the string before it is processed. For example, "<tag> value </tag>" should be the same as "<tag>value</tag>"
- The QosProvider API has been implemented within the DCPS API's for C, (CORBA) C++, (CORBA), ISO C++, Java and C# languages.
- Currently parsing of sequences and arrays only supports sequence of strings