50.2.3 QoS Profile Inheritance and Composition
An individual QoS Profile or Entity QoS (e.g., <datawriter_qos>) can inherit values from other QoS Profiles, and/or be composed out of QoS Snippets. In inheritance, a base_name attribute is used to inherit from a single, previously loaded QoS Profile. With composition, a <base_name> tag is used to specify a list of one or more QoS Snippets to overlay upon the base profile, creating a new composed profile. The following sections describe how these methods can be used, including best practices. See also 50.6 XML File Syntax.
50.2.3.1 QoS Profile Inheritance
An individual QoS Profile can inherit values from other QoS Profiles described in the XML file by using the attribute base_name.
A QoS Profile may also inherit values from other QoS Profiles described in different XML files. A QoS Profile can only inherit from other QoS Profiles that have already been loaded. The order in which XML resources are loaded is described in 50.5 How to Load XML-Specified QoS Settings.
The following examples show how to inherit from other profiles:
Inheritance Example 1:
<qos_library name=”Library”>
<qos_profile name="BaseProfile"> <datawriter_qos> ... </datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile>
<!-- use the base_name attribute to inherit from another profile -->
<qos_profile name="DerivedProfile" base_name="BaseProfile"> <datawriter_qos> <batch>
<enable>true</enable>
<max_samples>100</max_samples>
<max_data_bytes>LENGTH_UNLIMITED</max_data_bytes>
</batch>
</datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile> </qos_library>
In this example, the QoS Profile called DerivedProfile is constructed via inheritance from the QoS Profile BaseProfile. The profile DerivedProfile inherits BaseProfile by referencing the base profile in the <qos_profile> attribute base_name="BaseProfile". This means that the <datawriter_qos> and <datareader_qos> in DerivedProfile inherit their values from the corresponding <datawriter_qos> and <datareader_qos> in BaseProfile. The QoS Profile DerivedProfile first initializes all its QoS policies with the values obtained from BaseProfile. Then it applies any QoS policies explicitly listed in its own definition to override the initialized values. In this example, DerivedProfile only modifies the BatchQos policy on the DataWriter QoS.
If a QoS Profile definition does not specify the base_name attribute, then it is initialized from the builtin defaults provided by Connext. See 50.2.1 Built-in QoS Profiles.
Inheritance Example 2:
<qos_library name=”Library”> <qos_profile name="Profile1"> <datawriter_qos name="BaseWriterQoS"> ... </datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile> <qos_profile name="Profile2"> <datawriter_qos name="DerivedWriterQos" base_name="Profile1::BaseWriterQos"> ... </datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile> </qos_library>
The <datawriter_qos> in Profile2 inherits its values from the <datawriter_qos> in Profile1. The <datareader_qos> in Profile2 will not inherit the values from the corresponding QoS in Profile1. Since Profile2 doesn’t inherit from any other QoS Profile, the <datareader_qos> values will be taken from the builtin defaults. See 50.2.1 Built-in QoS Profiles.
Inheritance Example 3:
<qos_library name=”Library”> <qos_profile name="Profile1"> <datawriter_qos> ... </datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile> <qos_profile name="Profile2"> <datawriter_qos name="BaseWriterQoS"> ... </datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile> <qos_profile name="Profile3" base_name="Profile1"> <datawriter_qos name="DerivedWriterQos" base_name="Profile2::BaseWriterQos"> ... </datawriter_qos> <datareader_qos> ... </datareader_qos> </qos_profile> </qos_library>
The <datawriter_qos> in Profile3 inherits its values from the <datawriter_qos> in Profile2. The <datareader_qos> in Profile3 inherits its values from the <datareader_qos> in Profile1.
<qos_library name=”Library”>
<qos_profile name="Profile1">
<datawriter_qos name="BaseWriterQos1">
...
</datawriter_qos>
<datawriter_qos name="BaseWriterQos2">
...
</datawriter_qos>
</qos_profile>
<qos_profile name="Profile2">
<datawriter_qos name="DerivedWriterQos" base_name="Profile1">
...
</datawriter_qos>
</qos_profile>
</qos_library>
The <datawriter_qos> in Profile2 inherits its values from the <datawriter_qos> in Profile1 called BaseWriterQos1 because, when parsing the <datawriter_qos> DerivedWriterQos, Connext inherits values from the first matching <datawriter_qos> tag contained in Profile1. BaseWriterQos1 is chosen over BaseWriterQos2 to inherit values from, since it occurs first in the order within Profile1. See 50.2.3.2 QoS Profile Inheritance Rules.
Inheritance Example 5:
Global_QoS.xml
<qos_library name="GlobalLibrary">
<qos_profile name="GlobalProfileA">
</qos_profile
</qos_library>
Component_QoS.xml
<qos_library name="ComponentLibrary">
<qos_profile name="ComponentProfileA" basename="GlobalLibrary::GlobalProfileA">
</qos_profile
</qos_library>
In this example, a QoS Profile inherits values from another QoS Profile defined in a separate QoS Library, in another file. This is a typical use case where QoSes are constructed by separating them into multiple files. In this example, Global_QoS.xml has to be loaded before Component_QoS.xml.
To learn more about how to load multiple files in your application, see 50.5 How to Load XML-Specified QoS Settings.
50.2.3.2 QoS Profile Inheritance Rules
Connext enforces certain rules when deriving values in XML. For example, a <domain_participant_qos> cannot derive values from a <datawriter_qos> tag. Connext will display error messages if you do not follow these inheritance rules:
- Tags of the same kind can always inherit from each other. For example, a <datawriter_qos> can always inherit values from another <datawriter_qos>.
- <datawriter_qos> and <datareader_qos> can inherit from <topic_qos>. This is a special case that allows the sharing of common QoS policies between the DataWriter and DataReader operating on the same Topic.
- Any <xxx_qos> tag can inherit from a <qos_profile>. Connext searches through the children of the <qos_profile> and derives values from the first matching tag for <xxx_qos>. To identify the match, both of the above rules are applied. See Inheritance Example 4: above for an example.
50.2.3.3 Limitations of QoS Profile Inheritance
While useful, initializing a QoS Profile from a single base QoS Profile can also be limiting. For example, assume you have the configuration shown in Figure 50.1: Single Inheritance Example
Figure 50.1: Single Inheritance Example
If you wanted to incorporate monitoring into the QoS Profiles app_1 and app_2, the only option with inheritance would be to create two new QoS Profiles, each inheriting from app_1 and app_2 respectively, and to copy the monitoring XML configuration into each of the two new QoS Profiles as shown in Figure 50.2: Duplication of Configuration in Inheritance. This results in significant XML code duplication and leads to maintainability issues.
Figure 50.2: Duplication of Configuration in Inheritance
The following section describes how to handle the above scenario using QoS Profile composition.
50.2.3.4 QoS Profile Composition
QoS Profile composition uses QoS Snippets to more easily update profiles that you use or inherit. QoS Snippets are small pieces of well-formed, reusable XML QoS that configure a single aspect of QoS, such as enabling monitoring or security.
In the previous example, you could add the monitoring configuration to the new QoS Profiles app_mon_1 and app_mon_2 by referring to a QoS Snippet that configures monitoring.
Figure 50.3: One Reusable Configuration Snippet
QoS Snippets are intended to be composed into other QoS Snippets and QoS Profiles. As shown in the example below, the syntax used to define a QoS Snippet is the same as that of a QoS Profile, but the intent and usage are different.
The following is an example of the syntax used to define and use QoS Snippets.
Composition Example 1:
<!-- This is a QoS Snippet -->
<qos_profile name="Snippet1">
<datareader_qos>
<reliability>
<kind>RELIABLE_RELIABILITY</kind>
</reliability>
</datareader_qos>
</qos_profile>
<!-- This is a QoS Snippet -->
<qos_profile name="Snippet2">
<datareader_qos>
<durability>
<kind>TRANSIENT_LOCAL_DURABILITY</kind>
</durability>
</datareader_qos>
</qos_profile>
<qos_profile name="Profile1">
<datawriter_qos>
<publication_name>
<name>SampleDataWriter_A</name>
</publication_name>
</datawriter_qos>
</qos_profile>
<!-- This QoS Profile definition uses the Snippets -->
<qos_profile name="MyDerivedAndComposedProfile" base_name="Profile1">
<base_name>
<element>Snippet1</element>
<element>Snippet2</element>
</base_name>
<datareader_qos>
<history>
<kind>KEEP_LAST_HISTORY_QOS</kind>
<depth>6</depth>
</history>
</datareader_qos>
</qos_profile>
In this example, a QoS Profile inherits from another QoS Profile and uses composition to weave in policies from two QoS Snippets. Specifically, MyDerivedAndComposedProfile is constructed by inheriting from Profile1, then by overlaying Snippet1 and Snippet2. Finally, MyDerivedAndComposedProfile applies its own QoS policies, which overwrite any others. See also 50.2.3.4.2 Order and Precedence of Inheritance.
It is recommended to use fully qualified names in the element tag if there is ambiguity in the QoS Profile or QoS Snippet names you have loaded in your application.
50.2.3.4.1 How Inheritance and Composition Work Together
The process of inheriting QoS Profiles and composing from QoS Snippets works as follows:
- The QoS policies are initialized from those in the base profile, using the base_name attribute of the <qos_profile> tag. If the base_name attribute is not present, then the policies are initialized from the builtin defaults defined by Connext.
- The policies are overridden with those defined in the QoS Snippets listed inside the <base_name> XML tag. The QoS Snippets are applied in the order in which they appear. So the first QoS Snippet (Snippet1 in the example above) overrides the policies that were set from the inherited base QoS Profile (Profile1 in the example), the second QoS Snippet (Snippet2 in the example) overrides whatever was the result of applying Snippet1, and so on.
- The policies that appear explicitly as elements in the QoS Profile are applied. These override the policies set by the base QoS Profile and the QoS Snippets. In this example, a KEEP_LAST_HISTORY_DEPTH of 6 overrides whatever was set by the base QoS Profile and the QoS Snippets.
You inherit a QoS Profile, but overlay one or more Qos Snippets. Inherit a QoS Profile because you want to subsume the complete definition of the QoS policies for a particular use case. Overlay QoS Snippets onto a QoS Profile so that you override only a single aspect of QoS: for instance, only what is logically associated with monitoring.
50.2.3.4.2 Order and Precedence of Inheritance
Values are inherited from the specified elements in the <base_name> tag, in order from top to bottom. Values inherited from elements lower in the order (Snippet2 in the examples) will overwrite the same values (if present) from elements higher up (Snippet1 in the examples). Remember that the QoS, QoS Profile, or QoS Snippet should already be loaded as a part of your XML file. (See 50.5 How to Load XML-Specified QoS Settings.)
In the following example, MyDerivedAndComposedProfile inherits from Profile1, keeping Profile1's SampleDataWriter_A but getting <durability> and <reliability> from the Snippets rather than from Profile1. Finally, MyDerivedAndComposedProfile applies its own local <history> policies.
Composition Example 2:
<!-- This is a QoS Snippet -->
<qos_profile name="Snippet1">
<datareader_qos>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
</reliability>
</datareader_qos>
</qos_profile>
<!-- This is a QoS Snippet -->
<qos_profile name="Snippet2">
<datareader_qos>
<durability>
<kind>TRANSIENT_LOCAL_DURABILITY_QOS</kind>
</durability>
</datareader_qos>
</qos_profile>
<qos_profile name="Profile1">
<datawriter_qos>
<publication_name>
<name>SampleDataWriter_A</name>
</publication_name>
</datawriter_qos>
<datareader_qos>
<durability>
<kind>VOLATILE_DURABILITY_QOS</kind>
</durability>
<reliability>
<kind>BEST_EFFORT_RELIABILITY_QOS</kind>
</reliability>
</datareader_qos>
</qos_profile>
<!-- This QoS Profile definition uses the Snippets -->
<qos_profile name="MyDerivedAndComposedProfile" base_name="Profile1">
<base_name>
<element>Snippet1</element>
<element>Snippet2</element>
</base_name>
<datareader_qos>
<history>
<kind>KEEP_LAST_HISTORY_QOS</kind>
<depth>6</depth>
</history>
</datareader_qos>
</qos_profile>
The final values in MyDerivedAndComposedProfile will be as follows (map the colors in the example to what actually gets used), as shown here:
<qos_profile name="MyDerivedAndComposedProfile">
<datareader_qos>
<reliability>
<kind>RELIABLE_RELIABILITY</kind>
</reliability>
<history>
<kind>KEEP_LAST_HISTORY_QOS</kind>
<depth>6</depth>
</history>
<durability>
<kind>TRANSIENT_LOCAL_DURABILITY</kind>
</durability>
</datareader_qos>
<datawriter_qos>
<publication_name>
<name>SampleDataWriter_A</name>
</publication_name>
</datawriter_qos>
</qos_profile>
Composition Example 3
Imagine that Example 2 had the following Snippets instead:
<!-- This is a QoS Snippet -->
<qos_profile name="Snippet1">
<datawriter_qos>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
<max_blocking_time>
<sec>5</sec>
<nanosec>0</nanosec>
</max_blocking_time>
</reliability>
</datawriter_qos>
</qos_profile>
<!-- This is a QoS Snippet -->
<qos_profile name="Snippet2">
<datawriter_qos>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
<max_blocking_time>
<nanosec>1000000</nanosec>
</max_blocking_time>
</reliability>
</datawriter_qos>
</qos_profile>
<!-- This QoS Profile definition uses the Snippets -->
<qos_profile name="MyDerivedAndComposedProfile" base_name="Profile1">
<base_name>
<element>Snippet1</element>
<element>Snippet2</element>
</base_name>
</qos_profile>
In this example, Snippet2's nanosec overwrites Snippet1's. But since Snippet2 does not specify a sec, Snippet1's sec is used. The resultant QoS is a combination of the two reliability policies:
<!-- The above example combines the reliability settings because one QoS Snippet is overlaid on the other -->
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
<max_blocking_time>
<sec>5</sec>
<nanosec>1000000</nanosec>
</max_blocking_time>
</reliability>
Imagine now that the QoS Snippets in the above example were reversed, and Snippet2 was listed first in the file. Snippet2 would apply a nanosec of 1000000; then Snippet1 would overwrite that with 0 and apply its sec of 5. The result would be a max_blocking_time of 5 seconds and 0 nanoseconds.
You can use the rtixmloutpututility utility to see what the final QoS values will be in your system when composition and inheritance complete their derivations. See 50.2.3.7 Viewing Resolved QoS Values.
Composition Example 4:
If you specify <base_name> for a QoS Profile and also specify <base_name> for a QoS within it, the <base_name> tag or attribute in the QoS will take precedence. That is, <base_name> from the QoS Profile will be ignored for the QoS specifying its own <base_name>.
The following example illustrates this concept:
<dds>
<qos_library>
<qos_profile name=”ParentProfile”>
<base_name>
<element>A</element>
<element>B</element>
</base_name>
...
<datawriter_qos name=”DW_QoS”>
<base_name>
<element>C</element>
<element>D</element>
</base_name>
</datawriter_qos>
</qos_profile>
</qos_library>
</dds>
In this example, since DW_QoS has its own list for the <base_name> tag, DW_QoS will only inherit values from C and D. It will NOT inherit anything from A and B specified as a part of ParentProfile, since its own <base_name> tag overrides it.
50.2.3.5 Best Practices for Inheritance and Composition
XML QoS Profile inheritance and composition provide a powerful way to define configurations, allowing flexibility and reusability. It is important to understand the underlying mechanics and follow the best practices described below to maximize usability and avoid unexpected results.
- Differentiate between QoS Profiles and QoS Snippets.
- Think of QoS Profiles as complete definitions of all QoS policies for a particular use case. Construct QoS Profiles so that all aspects of the use case are covered.
- Think of QoS Snippets as small, generic, orthogonal chunks of QoS policies. Construct QoS Snippets to configure a single aspect of a configuration, such as monitoring or security.
- Use QoS Profiles for inheritance only, never composition. Use a QoS Profile in a base_name attribute, never inside a <base_name> element.
- Use QoS Snippets for composition, never inheritance. Use a QoS Snippet inside a <base_name> element, never in a base_name attribute.
- Use QoS Profiles, not QoS Snippets, to create DDS Entities. Do not pass a QoS Snippet name to the DDS operations create_<entity>_with_profile(), get_<entity>_qos_from_profile(), set_qos_with_profile(), or set_default_profile().
- Keep QoS Snippets generic and reusable. Never use the <topic_filter> element in a QoS Snippet.
These best practices are illustrated in the following figure and further described in the sections that follow.
Figure 50.4: Best Practices for Inheritance and Composition
In Figure 50.4: Best Practices for Inheritance and Composition, imagine the results produced by the dotted box, as already illustrated in the previous examples. These results are inherited by QoS Profile 3. QoS Profile 3's snippets are then applied. (QoS Snippet 5 inherits from two other snippets first.) Finally, any policies in QoS Profile 3 that differ from the results produced by the inheritance from profiles 1 and 2 are applied.
Another way to look at Figure 50.4: Best Practices for Inheritance and Composition is as a tree whose nodes are applied in this order, where "QP" refers to the QoS Profiles in the figure and "QS" refers to the QoS Snippets in the figure:
- QP1 (because inheritance says we start all the way back at the first inherited profile)
- QS1, then QS2 (because snippets are overlaid next)
- QP2 (because it may have deltas that overwrite what has been composed so far)
- QS3, then QS4 (because QS5 inherits from QS3 and QS4 first)
- QS5 (because it may have deltas that overwrite QS3 and QS4)
- QP3 (because it may have deltas that overwrite everything composed so far)
50.2.3.5.1 Differentiate between QoS Profiles and QoS Snippets
When defining a QoS Profile, decide whether you are:
- Creating a QoS Profile intended to create DDS Entities and/or fully define their QoS.
- Creating a QoS Snippet intended as a reusable block to be composed in the definition of QoS Profiles and other QoS Snippets.
These two options are fundamentally different.
A QoS Profile is intended to define the QoS policies used to create a DDS Entity. Therefore, it should match a specific application use case (e.g., sending alarms or streaming periodic data). Moreover, because the QoS Profile will be used to create a DDS Entity, it implicitly defines values for all the QoS Policies that apply to the entity.
When defining a QoS Profile, choose the builtin QoS Profile that most closely matches your use case. Use that builtin QoS Profile as a base profile. For example:
<qos_profile name="MyProfile" base_name="BuiltinQosLibExp::Pattern.AlarmEvent">
<!-- modify the profile by composing with QoS Snippets -->
<!-- modify the profile by overriding the QoS policies explicitly -->
</qos_profile>
Give the QoS Profile a name that makes clear its intended use, as well as the fact that it is a QoS Profile (instead of a QoS Snippet). For example, use “Profile” as a suffix in the name of the QoS Profile or some other consistent naming convention.
A QoS Snippet is intended as a generic block of QoS policies for composition into QoS Profiles and other QoS Snippets. For example, configuring monitoring, configuring Security, and configuring a FlowController are good uses for QoS Snippets.
QoS Snippets should focus on a single aspect of QoS policy and try not to set unrelated policies. This maximizes composability, avoiding interfering with policies set by other QoS Snippets.
QoS Snippets should be generic and reusable across systems and deployments. Therefore, it does not make sense to constrain their applicability using the <topic_filter> element within their definition. Doing so may also result in conflict with topic filters set on QoS Profiles that use those QoS Snippets.
Give the QoS Snippet a name that makes clear its intended use, as well as the fact that it is a QoS Snippet (not a regular QoS Profile). For example, use “Snippet” as a suffix in the name of the QoS Snippet or some other consistent naming convention.
50.2.3.5.2 Use QoS Profiles for inheritance only, never composition
Aside from its use for creating DDS Entities, a QoS Profile may be used as the base definition of another QoS Profile. For example:
<qos_profile name="MyDerivedProfile" base_name="MyBaseProfile">
...
</qos_profile>
When used for inheritance, the derived profile is initialized with the policies of the base profile.
A profile should never be used for composition. That is, it should not be referenced within the <base_name> element:
<qos_profile name="MyDerivedProfile">
<base_name>
<element>MyBaseProfile</element> <!-- never do this -->
</base_name>
</qos_profile>
Because a QoS Profile implicitly defines all the QoS policies, using it for composition would have the unintended effect of potentially overriding all the policies.
50.2.3.5.3 Use QoS Snippets for composition, never inheritance
QoS Snippets are small pieces of well-formed XML QoS intended to configure a single aspect of a QoS. The proper way to use them is for the composition of other QoS Profiles and QoS Snippets. Therefore, they must only appear within the <base_name> tag "element." For example:
<qos_profile name="MyComposedProfile" base_name="MyBaseProfile">
<base_name>
<element>Snippet1</element>
<element>Snippet2</element>
<element>Snippet3</element>
</base_name>
...
</qos_profile>
<qos_profile name="MyComposedSnippet">
<base_name>
<element>Snippet1</element>
<element>Snippet2</element>
<element>Snippet3</element>
</base_name>
...
</qos_profile>
Do not use a QoS Snippet for inheritance. For example
<!-- do not do this -->
<qos_profile name="MyComposedProfile" base_name="Snippet1">
<base_name>
<element>Snippet2</element>
<element>Snippet3</element>
</base_name>
...
</qos_profile>
If you use a QoS Snippet for inheritance (i.e., for initializing another Qos Profile), you are using something that was not intended to be a full definition; thus, it may overlook the proper configuration of certain policies for your system.
50.2.3.5.4 Use QoS Profiles, not QoS Snippets, to create DDS Entities
The QoS configuration of DDS Entities can be specified using QoS Profiles. This is a convenient mechanism that allows separation of configuration from the functional logic of your application.
The Connext API contains several operations that reference QoS Profiles by name, such as create_participant_with_profile() and create_topic_with_profile(). These operations are used to either create DDS Entities with the QoS policies referenced by the profile name, or to initialize the Entity QoS structure with the QoS policies referenced by the profile. Either way, these operations should not be called using a QoS Snippet name as the reference.
50.2.3.5.5 Keep QoS Snippets generic and reusable
QoS Snippets should be developed with reuse in mind and should not use the <topic_filter> element within the definition of the QoS Snippet.
<!-- do not do this -->
<qos_profile name="MySnippet">
<datawriter_qos topic_filter="Alarm">
<reliability>
<kind>RELIABLE_RELIABILITY</kind>
</reliability>
</datawriter_qos>
<datawriter_qos topic_filter="SensorUpdate">
<reliability>
<kind>BEST_EFFORTS_RELIABILITY</kind>
</reliability>
</datawriter_qos>
...
</qos_profile>
The <topic_filter> element conditionally defines the QoS Profile depending on the Topic name associated with the Entity being created or configured. Since the QoS Snippet is not intended to create or configure DDS Entities directly, it does not make sense to use the <topic_filter> element in its definition.
50.2.3.6 Enforcement of QoS Profile and QoS Snippet Conventions
Connext uses the same syntax for the creation of QoS Profiles and QoS Snippets. Therefore, it does not enforce the conventions described here. Although Connext will not detect or prevent violation of these conventions (e.g., if you use a QoS Profile for composition), following these conventions is strongly encouraged to avoid unexpected results. Furthermore, future versions of Connext may introduce different syntax that allows differentiating QoS Profiles from QoS Snippets and enforces the conventions. If you follow these conventions now, you can continue using them without violating future syntax.
50.2.3.7 Viewing Resolved QoS Values
The final value for a QoS configuration, especially when using inheritance and QoS Snippet composition, can be visualized at runtime in a variety of ways:
- Locally in your application, the QoS to_string functions allow Entity QoS objects to be converted into strings and printed, so that you can see the current QoS being used. Entity QoS types are DataReaderQos, DataWriterQos, PublisherQos, SubscriberQos, TopicQos, DomainParticipantQos and DomainParticipantFactoryQos.
- Additionally, when an entity is created, or when the set_qos operation is called on an entity, the QoS settings it is using are output to the log, if logging is configured with a verbosity of NDDS_CONFIG_LOG_VERBOSITY_STATUS_LOCAL and category of NDDS_CONFIG_LOG_CATEGORY_API. (See 54.2 Configuring Connext Logging.) If the DDS_EntityNameQosPolicy is set, the names will be printed as part of a header to help associate logged QoS settings with the appropriate entities. Connext automatically prints the QoSes of these entities to the log in XML format. Note it is not required that your QoS was configured in XML, it will always be logged in XML format to the log.
The logged QoS when using logging, or the to_string functions, will show only the QoS settings that are different from the documented default (several to_string overloads can override this behavior). The documented default refers to the default value of a policy as specified by the API reference HTML documentation.
- Remotely, using RTI Monitor.
- Remotely, using RTI Admin Console. Note that when visualizing the QoS using Admin Console, only a subset of the QoS are shown. Only QoS policies that are required for matching are propagated to Admin Console.
Here is an example of a to_string function in the Modern C++ API:
using namespace rti::all;
DataWriterQos the_qos = writer.qos();
// Obtain a string representation of the DataWriterQos object
// Only differences with respect to the documented default will be included
std::string the_string = to_string(the_qos);
// Create another DataWriterQos object and change some policies
DataWriterQos other_qos;
other_qos << Reliability::BestEffort();
// The differences with respect to the other_qos object will now be stored to the string
the_string = to_string(the_qos, other_qos);
// Finally, we can print the entire QoS object (not just differences)
the_string = to_string(the_qos, rti::core::qos_print_all);
For older releases, or where code change/recompilation isn't possible, you can use rtixmloutpututility to visualize the end result of your QoS settings at entity creation time.
rtixmloutpututility allows you to see the final QoS values your entities will receive after inheritance and composition are resolved. Here is an example usage of this utility:
$ ./rtixmloutpututility
-qosFile '/home/xxx/Documents/Tests/CORE-9446/USER_QOS_PROFILES.xml;/home/xxx/Documents/Tests/CORE-1375/USER_QOS_PROFILES.xml'
-profilePath Data_Library::Data_Profile
-outputFile Dummy.txt
-qosTag domain_participant_qos/property
To get this utility, including more information about its options and usage, please see: https://github.com/rticommunity/rticonnextdds-xml-output-utility.