![Abstract composition of orange triangles and scattered points on white background (no text or symbols)](.vortex-opensplice-rmi-user-guide/cc0144649d238698e53a2c2b8916e09ad2535c7100cee5fa9dd187d58ee54afb.jpg)

# VORTEX

# OPENSPLICE

# RMI User Guide

# Release 6.x

# Contents

# 1 Preface 1

1.1 About the RMI User Guide
1.2 Conventions

# 2 Introduction 2

2.1 Features . 2
2.2 Benefits 3

# 3 Vortex OpenSplice RMI over DDS 4

3.1 Key components 5
3.2 Binding Languages 5

# 4 Building an RMI Application 6

4.1 About RMI Applications . . 6
4.2 Services description 6
4.3 QoS policies description 7
4.4 RMI compilation 8
4.5 Application implementation 9
4.6 Using a specific DDS domain 16
4.7 Server Threading and Scheduling policies . 17

# 5 Language mapping for Vortex OpenSplice RMI 20

5.1 Mapping for interfaces 20
5.2 Mapping for operations 21
5.3 Mapping for basic types 21

# 6 RMI Interface to DDS topics mapping rules 22

# 7 RMI Runtime Configuration Options 24

7.1 RMIClientThreadingModel option . . 24
7.2 RMIServiceDiscoveryTimeout option 24
7.3 RMIServerThreadingModel option 24
7.4 RMIServerSchedulingModel option 24
7.5 RMIDurability option 25
7.6 RMIClientSchedulingModel option 25
7.7 RMILegacyTopicNames option 25

# 8 QoS policies XML schema 26

# 9 Contacts & Notices 31

9.1 Contacts 31
9.2 Notices 31

# 1

# Preface

# 1.1 About the RMI User Guide

The Vortex OpenSplice RMI User Guide is intended to explain the steps required to take advantage of the client/server interaction paradigm provided by Vortex OpenSplice RMI layered over the publish/subscribe paradigm of Vortex OpenSplice.

# Intended Audience

This Vortex OpenSplice RMI User Guide is for developers using remote invocations in DDS applications.

# Organisation

The first two chapters give a general introduction to RMI over DDS.

Building an RMI Application describes the steps involved in building applications using RMI over DDS.

Language mapping for Vortex OpenSplice RMI gives the ‘C++ and Java’ mapping of the IDL types that can be declared in the RMI services description file.

RMI Interface to DDS topics mapping rules shows how IDL declarations of RMI interfaces are mapped into IDL declarations of the implied DDS topics.

RMI Runtime Configuration Options describes the command-line options available when starting the RMI runtime.

QoS policies XML schema contains the XML schema for reference.

# 1.2 Conventions

The icons shown below are used to help readers to quickly identify information relevant to their specific use of Vortex.

<table><tr><td>Icon</td><td>Meaning</td></tr><tr><td>&lt;img src="images/82083c6641fb3edf8c7b949e9d0cdc1c9e2eb7411d1990a447f07dab2b3d1f81.jpg"/&gt;</td><td>Item of special significance or where caution needs to be taken.</td></tr><tr><td>&lt;img src="images/012fc837760b520b3af5b93e94997a6bef812b15ec1f71f9a5ad38c5c8049d42.jpg"/&gt;</td><td>Item contains helpful hint or special information.</td></tr><tr><td>&lt;img src="images/30e0468a00dd76c711208e0840a4cdcd7859ed39b798085899f1ba9801f8b0b8.jpg"/&gt;</td><td>Information applies to Windows (e.g. XP, 2003, Windows 7) only.</td></tr><tr><td>&lt;img src="images/a12c63c249684ff4aee30acde9b76821d8a2f59327250728f6d67f0a564f7425.jpg"/&gt;</td><td>Information applies to Unix-based systems (e.g. Solaris) only.</td></tr><tr><td>&lt;img src="images/c1ac88478b29892c883f2968835ece14e145971f89a4be58527b76298073a5ee.jpg"/&gt;</td><td>Information applies to Linux-based systems (e.g. Ubuntu) only.</td></tr><tr><td>&lt;img src="images/e6af7c2687dddea06456cf3bf6e12a468c0d389509989ef6539c2d918de6fa41.jpg"/&gt;</td><td>C language specific.</td></tr><tr><td>&lt;img src="images/bdc58d61168c0c3993680cd9a4732be2e111cb15f97838e7ac34c8fa1a35cb4f.jpg"/&gt;</td><td>C++ language specific.</td></tr><tr><td>&lt;img src="images/c4c60650e3b1bf7c3b01070639c012b84eed6c7412b9c902eba1990bdb68614b.jpg"/&gt;</td><td>C# language specific.</td></tr><tr><td>&lt;img src="images/7daced8187d8d5eb2be579b8838654816a487adb103a46939968ea8253b9b298.jpg"/&gt;</td><td>Java language specific.</td></tr></table>

# 2

# Introduction

# 2.1 Features

Vortex OpenSplice RMI provides an implementation of the general concept of invoking a remote method over DDS. It enhances Vortex OpenSplice with a service-oriented interaction pattern that can be used with combination with the native data-centric pattern. Vortex OpenSplice RMI is a service invocation framework on top of DDS DCPS that uses DDS mechanisms to export, find and invoke services. It maps all the application-exchanged requests/replies into DDS data exchanges, and gives the ability to configure the associated QoS policies according to the application needs. Finally, Vortex OpenSplice RMI enables the definition of a distributed services space over a DDS data space with all the known DDS benefits, such as discovery, fault tolerance, performance and real-time features.

![**Labeled Blocks:**\n*   **Client** (appears 3 times: top-left, middle-left, bottom-left)\n*   **Server 1** (top-right)\n*   **Server 2** (middle-right)\n*   **Server 3** (bottom-right)\n*   **Server 4** (bottom-center)\n*   **DDS data space** (central blue ellipse)\n*   **Request Topic** (appears 2 times: top-left, top-right)\n*   **Reply Topic** (appears 2 times: top-left, top-right)\n\n**Connections:**\n*   **Direct Communication (Top):**\n    *   A dashed orange arrow points from **Client** to **Server 1** labeled 'request'.\n    *   A dashed purple arrow points from **Server 1** to **Client** labeled 'reply'.\n*   **Topic-Based Communication (Top Cluster):**\n    *   **Client Side (Publishing):** An orange arrow points from **Client** to **Request Topic**, and another orange arrow points from **Request Topic** to **DDS data space**.\n    *   **Client Side (Subscribing):** A purple arrow points from **DDS data space** to **Reply Topic**, and another purple arrow points from **Reply Topic** to **Client**.\n    *   **Server 1 Side (Subscribing):** An orange arrow points from **DDS data space** to **Request Topic**, and another orange arrow points from **Request Topic** to **Server 1**.\n    *   **Server 1 Side (Publishing):** A purple arrow points from **Server 1** to **Reply Topic**, and another purple arrow points from **Reply Topic** to **DDS data space**.\n*   **Peripheral Connections:**\n    *   Solid lines connect the peripheral **Client** nodes and the peripheral **Server** nodes (**Server 2**, **Server 3**, **Server 4**) to the central **DDS data space**.](.vortex-opensplice-rmi-user-guide/ab88fa15d65a192c03240c52b6dc970c83ea7d0d4246c17c842ecbd019987a4c.jpg)

# RMI Communication Scheme

Vortex OpenSplice RMI targets service-oriented applications needing a request/reply communication scheme while they need to have a very fine control over the data and the underlying network quality of service. Typically, Vortex OpenSplice RMI can be used in systems to issue commands. Commands are a kind of stimulus that express the ability of the system to do something. As commands have the ‘do-something’ connotation, it is often useful to be informed synchronously that the command has been executed. Thanks to the various DDS QoSs, applications can associate expiration time, prioritities, persistency and so on to those commands.

# 2.2 Benefits

As a complementary paradigm to data centricity, Vortex OpenSplice RMI provides these benefits:

• A more productive and higher abstraction level than can be achieved manually through topic exchanges and applications synchronization.
• A unique middleware technology for mixing Global Services and Data Spaces with an easy and dynamic services registration, data declaration, and the same discovery mechanisms.
• Enables data-centric applications to use RMI without the burden of an additional middleware technology (e.g. CORBA).
• Strong services location transparency. Thanks to the connectionless nature of DDS, service identities do not need to include any network-related information. In Vortex OpenSplice RMI, a service is identified by a simple name. Services’ identities are exported naturally via a DDS publication on specific topics. Services can even move from one location to another without any impact on client applications.
• Simple API.
• Easy deployment process.

# 3

# Vortex OpenSplice RMI over DDS

As in traditional service-oriented applications, communication from client to server is performed through a welldefined service model. The RMI module enables a user to build a service model with remote method invocation capabilities and completely hides the DDS DCPS API. Of course, using RMI does not prevent the application from using the DDS API as shown by the following figure:

![The diagram displays a layered architecture consisting of three main horizontal sections stacked vertically, with specific labels within the middle section.\n\n**Labeled Blocks:**\n*   **APPLICATION**: An orange rectangular block at the very top.\n*   **RMI**: A label inside a smaller rectangular border within the upper-left portion of the middle section.\n*   **DDS**: A label situated directly below 'RMI' within the middle section.\n*   **OS**: A yellow rectangular block at the very bottom.\n\n**Connections and Layout:**\n*   The **APPLICATION** block rests on top of the middle section.\n*   The middle section is a large light blue rectangular area. Inside this area, on the left side, **RMI** and **DDS** are stacked vertically. The light blue background extends to the right of both 'RMI' and 'DDS'.\n*   The **OS** block sits at the bottom, supporting the middle section.](.vortex-opensplice-rmi-user-guide/1e176c8239b427a28de0ebd89fa6570a05d8947f33fd70701bdc6e0e3c52d145.jpg)

# RMI Relationship to DDS

A service model is defined by one or more object-oriented interfaces. A DDS RMI interface is an IDL interface having a name and a set of operations. Each operation has a fixed set of typed parameters. The RMI module provides:

• A service invocation framework that maps the different services operations onto a set of DDS topics that hold the operation’s invocation requests and replies. A set of mapping rules have been defined for this purpose. At runtime, this framework sets up the underlying DDS environment and handles the remote interface invocations using the basic DDS read/write operations.
• A simple and intuitive programming model for both the server application side implementing the interface, and the client application side invoking that interface. The server programming model is as simple as implementing an interface, and the client programming model is as simple as calling a local interface.
• A powerful feature to enable tuning of the invocation request and reply QoS by setting their corresponding DDS QoS policies. This feature enables developers to improve the invocations quality with real-time and high-performance features. For instance, priorities and validity durations (lifespan) could be set on the different operation requests/replies.
• Synchronous, asynchronous and oneway invocation modes. The synchronous mode is the invocation mode that blocks the client thread until the reply is sent back to him by the server. The asynchronous mode is similar to the CORBA Asynchronous Messaging Interface (AMI) callback model. It is a non-blocking mode where the client does not wait for the reply from the server, but rather provides a callback object that will be invoked by the middleware to deliver the request return values when they are received. Finally, the oneway mode is a fire-and-forget invocation mode where the client does not care about the success or failure of the invocation. A oneway method cannot return values and no reply message will ever return to the client once the request is sent to the server.
• ‘C++ and Java’ implementation.

# 3.1 Key components

The Vortex OpenSplice RMI module includes the following components:

RMI Pre-processor (rmipp) Generates the interface-type-specific requests/replies topics and invocation handling classes.

Core library Provides the runtime setup operations and a generic invocation framework.

# 3.2 Binding Languages

The Vortex OpenSplice RMI module is available for both Java and C++ languages.

# 4

# Building an RMI Application

# 4.1 About RMI Applications

The process of building an Vortex OpenSplice RMI application is shown in Steps Building Applications with RMI below. The different steps are described in the following subsections.

![This flowchart illustrates a software compilation pipeline divided into four phases at the bottom: 'Service description', 'RMI Compilation', 'DDS Compilation', and 'Application Implementation'.\n\n**Blocks and Connections:**\n\n1.  **Inputs:** Two blocks on the far left, **'Interfaces definition (*.idl)'** and **'DDS qos policies definition (*.xml)'**, are grouped by a curly brace. An arrow points from this group to a yellow block labeled **'rmipp pre-processor'**.\n2.  **rmipp pre-processor outputs:**\n    *   An arrow points from **'rmipp pre-processor'** to a yellow block labeled **'DDS Topics Definition (*.idl)'**.\n    *   A curved arrow points downward from **'rmipp pre-processor'** to a yellow block labeled **'RMI generated source code'**.\n3.  **idlp pre-processor inputs:** A block labeled **'Interfaces definition (*.idl)'** sits above the **'DDS Topics Definition (*.idl)'** block. A curly brace groups these two together. An arrow points from this group to an orange block labeled **'idlp pre-processor'**.\n4.  **idlp pre-processor outputs:**\n    *   A curved arrow points downward from **'idlp pre-processor'** to an orange block labeled **'DDS generated source code'**.\n    *   A thick grey arrow points to the right from the **'idlp pre-processor'** area towards a yellow block labeled **'Application logic implementation'**.\n5.  **Final Step:** A curved arrow points downward from **'Application logic implementation'** to a yellow block labeled **'Client and Server source code'**.](.vortex-opensplice-rmi-user-guide/7b3628fe05c51610471339fce398a77620e4999efae625576e0f9c8f2070cd31.jpg)

Steps Building Applications with RMI

# 4.2 Services description

The first step in building an RMI application is the definition of its provided services in terms of interfaces. The application interfaces should be declared using the OMG IDL language. The operations parameters can be either of basic (short, long, ...) or complex (struct, sequence, string, ...) types. However, the following restrictions should be respected:

• the Any and the valuetype IDL types are not supported because they are not supported by the underlying DDS DCPS layer. Union type is also not supported.
• Exceptions are not supported at this time.
• Each interface must extend DDS\_RMI::Services base interface to indicate that it is invocable over DDS. This interface is defined in the file dds\_rmi.idl, which must be included.
• Each interface must be declared ‘local’.
• Oneway operations are supported. The semantics of oneway operations is the same as for the OMG CORBA interfaces. A oneway operation must not contain any output parameter and must return a void type.

The following IDL snippet shows an example of a service data description:

```cpp
#include "dds_rmi.idl"
module HelloWorld
{
    // interface definition
local interface HelloService : ::DDS_RMI::Services
{
    string greet();
};
```

# 4.3 QoS policies description

The Vortex OpenSplice RMI module provides the ability to tune the quality of service of the services invocations (requests and/or replies), if needed, by setting the underlying DDS QoS policies. By default, the DDS RMI module uses the default values of the DDS QoS policies except for the reliability QoS policy which is set to RELIABLE.

If needed, the application designer can define the QoS policies to be set on the invocations in an XML file. This file must respect the XML schema given in QoS policies XML schema.

Note that setting the DDS QoS policies requires a good knowledge of the rules for mapping the specified interfaces onto the DDS topics description (please refer to RMI Interface to DDS topics mapping rules).

The following XML snippet shows an example:

```xml
&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
&lt;dcps xmlns="http://www.omg.org/dds/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/dds/DCPS.xsd"&gt;

&lt;domain id=""&gt;
    &lt;topic name="greet_req"
idltype="::HelloWorld::HelloService::greet_request" idlfile=""&gt;
    &lt;topic_qos&gt;
    &lt;destinationOrderQosPolicy&gt;
    &lt;destinationOrderKind&gt;
    BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS
    &lt;/destinationOrderKind&gt;
    &lt;/destinationOrderQosPolicy&gt;

    &lt;durabilityQosPolicy&gt;
    &lt;durabilityKind&gt;
    PERSISTENT_DURABILITY_QOS
    &lt;/durabilityKind&gt;
    &lt;/durabilityQosPolicy&gt;

    &lt;latencyBudgetQosPolicy&gt;
    &lt;duration&gt;
    &lt;nanosec&gt;10000000&lt;/nanosec&gt;
    &lt;sec&gt;0&lt;/sec&gt;
    &lt;/duration&gt;
    &lt;/latencyBudgetQosPolicy&gt;

    &lt;reliabilityQosPolicy&gt;
    &lt;duration&gt;
    &lt;nanosec&gt;100000000&lt;/nanosec&gt;
    &lt;sec&gt;0&lt;/sec&gt;
    &lt;/duration&gt;
    &lt;reliabilityKind&gt;
    RELIABLE_RELIABILITY_QOS
```

# 4.3. QoS policies description

```xml
&lt;/reliabilityKind&gt;
&lt;/reliabilityQosPolicy&gt;
&lt;/topic_qos&gt;
&lt;/topic&gt;
&lt;/domain&gt;
&lt;/dcps&gt;
```

This example specifies the QoS policies to be applied on the topic invocation request of the greet operation of the interface HelloWorld::HelloService. Note that the invocation request topic is named greet\_req and its IDL type is HelloWorld::HelloService::greet\_request.

# 4.4 RMI compilation

Once the application has defined its services and (optionally) its QoS settings, these definitions are compiled to generate type-specific code for the application services invocation.

The RMI compilation is done using the rmipp pre-processor applied on the interfaces definition file and the QoS file if it exists. The rmipp usage is:

```txt
rmipp [-l (java | c++)] [-I &lt;path&gt;] [-d &lt;directory&gt;] [-topics &lt;qos_file&gt;] [-P dll_macro_name[,&lt;header-file&gt;]] &lt;interfaces_file&gt;
```

The parameters are:

-l (java | c++) Define the target language. The C++ language is the default.

-I &lt;path&gt; Define the include path directives.

-d &lt;directory&gt; Define the location to place the generated files.

-topics &lt;qos\_file&gt; Define the XML file including the QoS policies settings.

-P dll\_macro\_name[,&lt;header-file&gt;] Only applicable to C and C++. Sets export macro that will be prefixed to all functions in the generated code. This allows creating DLLs from generated code. Optionally a header file can be given that will be included in each generated file.

&lt;interfaces\_file&gt; The IDL file including the interfaces definition.

The rmipp compilation will generate a set of Java or C++ source files as well as an IDL file including the mapping of the provided interfaces onto the DDS topics. The generated IDL file name is the interfaces file name with “\_topics” concatenated.

Rmipp follows the mapping rules described in Language mapping for Vortex OpenSplice RMI.

Example usage:

```batch
rmipp -d generated HelloService.idl
```

The generated directory will include:

```txt
HelloService_topics.idl
HelloService_Interface.h
HelloService_Interface.cpp
HelloService_InterfaceProxy.h
HelloService_InterfaceProxy.cpp
```

In addition, the rmipp compiler performs a DDS compilation to generate the DDS/DCPS code that is required to support the requests/replies transport over DDS.

# 4.4. RMI compilation

# 4.5 Application implementation

As mentioned before, the target applications have a client/server design. A typical application includes a server part that implements the provided interfaces, and a client part that invokes these interfaces. This section describes the programming model of both parts.

# 4.5.1 Runtime starting and stopping

Any DDS RMI application process must initialize the RMI runtime prior to any other operation, regardless of whether it is a client and/or a server process. The runtime initialization sets up the underlying DDS infrastructure and configures it to make the services invocable and the clients capable of invoking the services. It is also important to stop the runtime when the application is no longer using RMI.

The following code snippets show the runtime initialisation and stopping procedure in C++ and Java.

C++
RMI runtime starting and stopping in C++
```cpp
#include "ddsrmi.hpp"
using namespace org::opensplice::DDS_RMI;
int main (int argc, char * argv[])
{
    CRuntime_ref runtime = CRuntime::getDefaultRuntime();
    if (runtime.get() == NULL)
    {
    std::cout &lt;&lt; "Failed to get the Runtime " &lt;&lt; std::endl;
    exit(1);
    }

    // starting the runtime
    bool result = runtime-&gt;start(argc, argv);
    if (result != true)
    {
    std::cout &lt;&lt; "Failed to start the Runtime " &lt;&lt; std::endl;
    exit(1);
    }
    ...
    // stopping the runtime
    result = runtime-&gt;stop();
    if (result != true)
    {
    std::cout &lt;&lt; "Failed to stop the Runtime " &lt;&lt; std::endl;
    exit(1);
    }
}
```

Comments below refer to line numbers in the sample code above:

1 Include the OpenSplice RMI library header file. Any OpenSplice RMI application should include this file.
3 Declare the usage of the OpenSplice RMI library namespace.
7-12 Get the default DDS runtime. This selects the default DDS domain as the data space where all subsequent RMI requests and replies will be exchanged.
15-20 Initialize the created runtime. This creates all the needed DDS entities. A set of configuration options can be passed to the start operation via argc and argv parameters. This latter is a string array including possible option names and values, and argc is the length of this array. Note that these parameters are

# 4.5. Application implementation

typically the same parameters that were passed to the main program so that the RMI options can be specified on the command line, each following the format ‘--option=value‘. All of the supported options are described in the section RMI Runtime Configuration Options.

24-28 Stop the created runtime. This removes all the created DDS entities and releases the RMI-allocated resources. It is strongly recommended to stop the runtime when it no longer needed.

The Java code below works in a similar way.

# Java

RMI runtime starting and stopping in Java
```txt
import org.opensplice.DDS_RMI;

static void main (String[] args)
{
    CRuntime runtime = CRuntime.getDefaultRuntime();
    if (null == runtime)
    {
    System.out.println();
    System.exit(1);
    }

    // starting the runtime
    boolean result = runtime.start(args);
    if (!result)
    {
    System.out.println("Failed to start the Runtime");
    System.exit(1);
    }
    ...
    // stopping the runtime
    result = runtime.stop();
    if (!result)
    {
    System.out.println("Failed to stop the Runtime");
    System.exit(1);
    }
}
```

# 4.5.2 Server programming model

At the server side of the application, each provided interface should be implemented, then instantiated and finally registered to be invocable via Vortex OpenSplice.

To define an implementation, the application developer must write an implementation class including public methods corresponding to the operations of the related IDL interface. The rmipp compilation generates for each interface a skeleton class, named ::DDS\_RMI::HelloWorld::HelloServiceInterface, that must be extended by the application-supplied implementation class. The language mapping rules of the RMI IDL interfaces are given in Language mapping for Vortex OpenSplice RMI.

To make an interface invocable over DDS, it must be registered within the RMI framework, then activated. The registration process requires the following information:

• the implementation class object
• the server name, as well as a unique id identifying that interface inside the server.

The services activation makes the RMI runtime wait for incoming requests for all the registered services.

The following code snippets show the server programming model in C++ and Java.

# 4.5. Application implementation

# C++

C++ RMI interface implementation
```cpp
class HelloService_impl :
    public virtual DDS_RMI::HelloWorld::HelloServiceInterface
{
public:
    HelloService_impl();
    ~ HelloService_impl();

    virtual DDS::String greet();
}
```

# Java

Java RMI interface implementation
```txt
public class HelloService_impl :
DDS_RMI.HelloWorld.myInterfaceInterface {
    public String greet ()
    {
    // operation implementation
    }
}
```

# C++

C++ RMI server
```cpp
#include "ddsrmi.hpp"
#include "HelloService_Interface.hpp"

using namespace org::opensplice::DDS_RMI;

int main (int argc, char * argv[])
{
    // Runtime starting
    ...
    // implementation class instantiation
    shared_ptr&lt;HelloService_impl&gt; impl (new HelloService_impl());
    //interface registration
    bool res = DDS_Service::register_interface&lt;
    ::DDS_RMI::HelloWorld::HelloServiceInterface, HelloService_impl&gt;
    (
    impl, //implementation class
    "HelloServer", // server name
    1 // unique server id
    );

    if(!res)
    {
    std::cout &lt;&lt; "Failed to register the
    HelloWorld::HelloService interface");
    System.exit(1);
    }
    //services activation
    runtime-&gt;run()
    // Runtime stopping
    ...
```

# 4.5. Application implementation

```txt
32 }
```

Comments below refer to line numbers in the sample code above:

1-2 Include the OpenSplice RMI library header file as well as the generated interface skeleton header file.
4 Declare the usage of the OpenSplice RMI library namespace.
10 Start the DDS runtime.
13 Instantiate the implementation class of the HelloService interface and assign it to a smart pointer. The OpenSplice RMI library provides an implementation of smart pointers via the shared\_ptr template class.
16-27 Register the HelloService interface in the default DDS domain. The register\_interface function is a template function requiring the interface skeleton class and the interface implementation class as template parameters.
28 Activates all the registered services including the HelloServer service. This is a blocking call that makes the server runtime wait for incoming requests. To shut down the server runtime the shutdown() operation must be called.
31 Stop the DDS runtime.

The Java code below works in a similar way.

# Java

Java RMI server
```txt
static void main (String[] args)
{
    // Runtime starting
    ...
    // implementation class instantiation
    HelloService_impl impl = new HelloService_impl();

    // interface registration
    boolean res = org.opensource.DDS_RMI.DDS_Service.register_interface
    (
    impl, // implementation class
    "HelloServer", // server name
    1, // unique server id
    DDS_RMI.HelloWorld.HelloServiceInterface.class // Interface java Class
    );

    if(!res)
    {
    System.out.println("Failed to register the
    HelloWorld::HelloService interface");
    System.exit(1);
    }
    runtime.run();
    // Runtime stopping
    ...
}
```

# 4.5.3 Client programming model

As mentioned before, OpenSplice RMI supports synchronous, asynchronous and oneway invocation modes. The following subsections present the synchronous and asynchronous programming model. The oneway programming model is similar to the synchronous one but, of course, with a different behaviour.

# 4.5. Application implementation

# Synchronous invocation mode

The client part of the RMI application is as simple as calling a local class. Note that these calls block until the server-side responds or an internal timeout expires. Typically, in case of failure, the call will block until the timeout expiration. This timeout value is set by default to 10 minutes, but it may be configured via the interface proxy object. This object is a generated object, named ::DDS\_RMI::HelloWorld::HelloServiceInterfaceProxy, that is the local representative of the RMI interface. This object is mainly used to call the RMI services, as shown in the following client code examples.

C++

C++ RMI client
```cpp
01 #include "ddsrmi.hpp"
02 #include "HelloService_InterfaceProxy.hpp"
03
04 using namespace org::opensplice::DDS_RMI;
05
06 int main (int argc, char * argv[])
07 {
08
09    // Runtime starting
10    ...
11
12    // Getting the interface proxy
13    shared_ptr&lt;::DDS_RMI::HelloWorld::HelloServiceInterfaceProxy&gt; proxy;
14    bool ret = DDS_Service::getServerProxy&lt;
15    ::DDS_RMI::HelloWorld::HelloServiceInterfaceProxy&gt;
16    (
17    "HelloServer", //server name
18    1, //unique proxy instance id
19    proxy // proxy reference
20    );
21    // Calling the services
22    proxy->greet();
23
24    // Runtime stopping
25    ...
26
27 }
```

Comments below refer to line numbers in the sample code above:

1-2 Include the RMI library header file as well as the generated interface proxy header file.

4 Declare the usage of the OpenSplice RMI library namespace.

10 Start the DDS runtime.

13 Declare a smart pointer of the HelloService interface proxy type.

13-19 Get the HelloServer service proxy. The getServerProxy function is a template function requiring the proxy class type as a template parameter. This function accepts the service name, a proxy instance id and the smart pointer to the proxy object as parameters. In case of success, the smart pointer is set to the created proxy object. The proxy instance id is a unique identifier that refers to the created proxy. It is important to ensure the uniqueness of the identifiers of all the proxies of the same service. If the client application intends to use the same proxy in different threads, the MultiThreaded mode must be set (see MultiThreaded Client later in this chapter). If the requested service is not found, the getServerProxy operation will raise an org::opensplice::DDS\_RMI::SERVICE\_NOT\_FOUND exception.

22 Invoke the greet operation synchronously using the created proxy.

25 Stop the runtime.

# 4.5. Application implementation

The Java code below works in a similar way.

# Java

Java RMI client
```groovy
import org.opensplice.DDS_RMI.*;

static void main (String[] args) {

    // Runtime starting
    ...

    // Getting the interface proxy
    try {
    DDS_RMI.HelloWorld.HelloServiceInterfaceProxy proxy =
    DDS_Service.getServerProxy (
    "HelloServer", //server name
    1, //unique proxy instance id
    DDS_RMI.HelloWorld.HelloServiceInterfaceProxy.class // proxy java Class
    );

    // Calling the services
    proxy.greet();
    } catch (SERVICE_NOT_FOUND e) {
    // error
    }
    // Runtime stopping
    ...
}
```

# Asynchronous invocation mode

To invoke asynchronously a given non-oneway operation, such as the greet operation in the examples shown here, the client application must:

• Implement a specific reply handler class to handle the operation out/inout/return parameters if any. This handler must extend a base reply handler class that is generated for each operation and implement the greetReply callback function or method whose parameters are the out/inout/return parameters of the related IDL operation.
• Use the generated asynchronous function or method that maps to the IDL operation whose name is the concatenation of ‘async\_’ and the IDL operation name. This operation is a void operation that accepts only the in and inout IDL parameters, in addition to the eference of the implemented reply handler.

Note that the reply handler class is not re-entrant in the current implementation. It cannot handle concurrent replies. It means that if two successive asynchronous calls are made with the same reply handler instance, this latter will reject the second reply if it has not finished dispatching the first one. In this case the asynchronous call will raise a BAD\_PARAM exception.

![The image displays a standard warning symbol consisting of a red triangle with a black exclamation point centered inside on a white background.](.vortex-opensplice-rmi-user-guide/23ac9dab5f22efa6144a2f66fa689c0ef4f080ec668dc138aa8ca1aa543d776f.jpg)

IMPORTANT: It is strongly recommended not to mix synchronous and asynchronous calls of the same operation without proper synchronization. The application should ensure that the asynchronous call has received its reply before requesting a synchronous one.

# C++

C++ RMI Client with asynchronous invocation
```cpp
01 #include "ddsrmi.hpp"
02 #include "HelloService_InterfaceProxy.hpp"
03
```

# 4.5. Application implementation

```cpp
using namespace org::opensplice::DDS_RMI;

/**
 * Reply Handler of the 'async_greet' operation
 *
 */
class MyGreetReplyHandler :
    public virtual HelloWorld_HelloService_greet_Reply_Handler
    {
    void greet_Reply(DDS::String ret)
    {
    std::cout &lt;&lt; "Reply received: " &lt;&lt; ret &lt;&lt; std::endl;
    }
    }

int main (int argc, char * argv[])
{
    // Runtime starting
    ...
    // Getting the interface proxy
shared_ptr&lt;::DDS_RMI::HelloWorld::HelloServiceInterfaceProxy&gt; proxy;
bool ret = DDS_Service::getServerProxy&lt;
    ::DDS_RMI::HelloWorld::HelloServiceInterfaceProxy&gt;
    (
    "HelloServer", //server name
    1, // proxy instance id
    proxy // proxy reference
    );

    // instantiating a reply handler
MyGreetReplyHandler handler;

    // Calling the services asynchronously
proxy->async_greet(&handler);
    ...

    // Runtime stopping
    ...
}
```

Comments below refer to line numbers in the sample code above:

10-16 Provide the implementation class of the greet operation reply handler.
21 Start the DDS runtime.
24-31 Get the HelloServer service proxy as for the synchronous mode.
34 Instantiate the greet reply handler class.
37 Invoke the async\_greet() operation by providing the reply handler. This call is a non-blocking call. The application steps immediately to the next instruction. The invocation reply will be delivered to the application by invoking the greet\_Reply operation of the reply handler. Note that this operation will be invoked in a middleware-provided thread.
41 Stop the runtime. Note that some synchronization may be needed to avoid exiting before the async\_greet reply is delivered to the application.

The Java code below works in a similar way.

Java

# 4.5. Application implementation

Java RMI Client with asynchronous invocation
```groovy
import org.opensplice.DDS_RMI.*;

/**
 * Reply Handler of the 'async_greet' operation
 *
 */
class MyGreetReplyHandler extends
    DDS_RMI.HelloWorld.HelloServiceInterfaceProxy.greet_Reply_Handler {
    public void greet_Reply(String ret) {
    System.out.println("async_greet returns: " + ret);
    }
};

static void main (String[] args) {

    // Runtime starting
    ...

try {
    // Getting the interface proxy
    DDS_RMI.HelloWorld.HelloServiceInterfaceProxy proxy =
    DDS_Service.getServerProxy (
    "HelloServer", //server name
    1, //server instance id
    DDS_RMI.HelloWorld.HelloServiceInterfaceProxy.class // proxy java Class
    );

    // Calling the services asynchronously
    proxy.asynch_greet();
} catch(SERVICE_NOT_FOUND e) {
    System.out.println("HelloServer' service not found !");
}

// Runtime stopping
...
}
```

# MultiThreaded Client

The default threading model of a client application is single threaded. It means that, by default, a service proxy may not be used by multiple concurrent threads to perform service invocations. To enable or disable the multithreaded mode for clients, a configuration option must be specified in the command line as follows:

```lua
--RMIClientThreadingModel=[ST|MT]
```

# 4.6 Using a specific DDS domain

Using the default RMI CRuntime implies that all the RMI invocations will be performed within the default DDS domain. The default domain id is the one specified by the current Vortex OpenSplice configuration, specifically in the Domain Service section of the related XML file. The default Vortex OpenSplice configuration files set the domain id to 0. For more information on configuring Vortex OpenSplice please refer to the Vortex OpenSplice Deployment Guide.

If the RMI application operates with a user-defined domain id, using the default CRuntime enables RMI interactions within that domain. In case of an application operating in multiple domains, it should create a CRuntime object for the targeted domain id and get a DDS\_ServiceInterface object from that CRuntime.

The DDS\_ServiceInterface object provides all the convenient methods for server applications to register/unregister services and for client applications to get service proxies on the relevant domain id. These methods are the same as the DDS\_Service object ones. The following code snippets show this in C++ and Java.

# C++

Getting DDS\_ServiceInterface in C++
```cpp
// Getting a CRuntime on my specific domain
CRuntime_ref runtime = CRuntime::getRuntime(my_domain_id);
// Getting a DDS_ServiceInterface object
DDS_ServiceInterface_ref dds_service = runtime->getDDS_ServiceInterface();
```

# Java

Getting DDS\_ServiceInterface in Java
```txt
// Getting a CRuntime on my specific domain
CRuntime runtime = CRuntime.getRuntime(my_domain_id);
// Getting a DDS_ServiceInterface object
DDS_ServiceInterface dds_service = runtime.getDDS_ServiceInterface();
```

# 4.7 Server Threading and Scheduling policies

OpenSplice RMI allows configuration of the threading and the scheduling models of the RMI server applications by enabling a set of policies that control how the server allocates threads to handle service invocations and how these threads are scheduled with regard to the others. Hence developers may enhance the responsiveness of their services by choosing a multi-threaded execution model, or may protect a non-thread-safe service implementation by choosing a single thread execution model.

# 4.7.1 Threading policies

OpenSplice RMI provides three threading policies that apply on a single RMI runtime at the server side. The RMI runtime uses a thread pool that hosts a number of threads to execute the services incoming requests. This number defines the thread pool size and depends on the specified threading policy.

1 – Single Thread (ST) policy This policy allocates a single thread to process all the services’ incoming requests within the server process. The requests are processed one by one in the order that they are received. It guarantees that no two threads will execute concurrently the different services calls within that server. In this case, the RMI runtime creates a single thread pool. This policy is the default threading policy. The ST policy ensures thread safety to all the services within the server process, but with the drawback that services with long-running tasks will block the others.
2 – Thread Per Service (TPS) policy This policy allocates a single thread to each service, up to the number specified as the thread pool size. All the requests coming to one service are processed in sequence by a single thread borrowed from the thread pool, but different services requests are processed in parallel, within the limit of the thread pool size. The thread pool size is defined by the user application. The TPS policy ensures that services having long-running requests won’t block the others, but concurrent calls are not possible for one single service.
3 – Multi Thread (MT) policy This policy allows for a full multi-threaded environment. All the incoming requests are processed concurrently in different threads whatever the targeted services, within the limit of the thread pool size. The service implementation should take care of that and ensure thread safety. The thread pool size is user-defined.

# Scheduling policies

These policies specify the scheduling parameters that will be used for the threads created by the RMI runtime for a RMI server.

A RMI scheduling policy is defined by a scheduling priority and a scheduling class. The scheduling priority specifies the priority that will be assigned to all the threads that are spawned by the RMI runtime. The scheduling class may be SCHEDULE\_DEFAULT, SCHEDULE\_TIMESHARING, or SCHEDULE\_REALTIME. These scheduling classes depend on the underlying operating system. A SCHEDULE\_DEFAULT class is the default OS scheduling algorithm.

In general, the Timesharing class attempts to distribute the processor resources fairly among the threads. In a Realtime class a thread normally runs until completion but can be pre-empted by higher-priority threads. Both Timesharing and Realtime scheduling classes are priority-based, so the scheduling priority is meaningful for both classes.

![The image displays a standard warning sign featuring a red triangle with a white interior and a black exclamation mark in the center.](.vortex-opensplice-rmi-user-guide/e11f75c76ccfb04c856e3dbebc3db26a1e579eabf86484b718ae0f5570317172.jpg)

Note that some scheduling classes may not be supported by the underlying operating system, or that you may need special privileges to select particular settings.

![This image displays a standard triangular warning sign. It features a red border surrounding a white background. In the center is a large black exclamation mark (!).](.vortex-opensplice-rmi-user-guide/dd8222cfd350d074e77b6a750a5d480ebb266e1a5aa3c622218c39c3ba531411.jpg)

[Java Note that the Java platform does not define a scheduling model for threads but defers to the underlying thread implementation. As a result, only the scheduling priority is usable for the Java RMI applications. In fact, there is a notion of priority in the Java threading model, but this is only a hint to the scheduler. The way in which the JVM maps these hints to the underlying OS scheduler varies from JVM to JVM and even from platform to platform for a given JVM.

# Service priority

OpenSplice RMI allows priorities to be assigned to the services registered in a RMI runtime within a server process. It defines the business importance of each service relative to the others. It allows incoming requests to be handled in order of priority if not enough threads are available to handle them concurrently. The service priority is exploited by the OpenSplice RMI framework to decide which service request a thread should be assigned to first, whereas the scheduling priority is exploited by the OS scheduler itself to decide which thread should run first.

By default, each RMI service has priority set to 0.

# Programming model

Threading and scheduling policies may be passed either by command line, or programmatically at runtime. The command line options are described in RMI Runtime Configuration Options; this section shows the related APIs only.

# Java

Setting the threading/sceduling policies in Java
```txt
// getting and starting the default runtime
CRuntime runtime = Cruntime.getDefaultRuntime();
boolean res = runtime.start(argv);

// setting a MT threading policy with a thread pool size set to 5
ServerThreadingPolicy t_policy = new ServerThreadingPolicy
(ThreadingPolicyKind.MT, 5);
runtime.setServerThreadingPolicy(t_policy);

// setting a scheduling priority and keeping the scheduling
// class to the default
SchedulingPolicy s_policy = runtime.getServerSchedulingPolicy();
s_policy.schedulingPriority = 10;
runtime.setServerSchedulingPolicy(s_policy);
```

# 4.7. Server Threading and Scheduling policies

```txt
//registering a set of services
HelloService_impl impl = new HelloService_impl();
res = DDS_Service.register_interface(impl, "HelloServer", 1,
    DDS_RMI.HelloWorld.HelloServiceInterface.class);
// registering other services
// making HelloServer service the highest priority service
impl.setPriority(2);
//running the runtime
runtime.run();
```

![The image displays a triangular warning sign with a thick red border and a white background. In the center is a single black exclamation point.](.vortex-opensplice-rmi-user-guide/4389e3bc75df98eaea6ec0ba40745a4407dee308405a877bc45e56e3fad326c0.jpg)

Note that setting the thread pool size on java is done asynchronously. This means that there could be more server threads (and thus parallel calls) then expected when reducing the thread pool size.

C++

Setting the threading/sceduling policies in C++
```cpp
// getting and starting the default runtime
CRuntime_ref runtime = Cruntime::getDefaultRuntime();
bool res = runtime.start(argc, argv);

//setting a MT threading policy with a thread pool size set to 5
ServerThreadingPolicy t_policy = runtime->getServerThreadingPolicy();
t_policy.kind = MT;
t_policy.threadPoolSize = 5;
runtime->setServerThreadingPolicy(t_policy);

// setting a scheduling priority and keeping the scheduling
// class to the default
SchedulingPolicy s_policy = runtime->getServerSchedulingPolicy();
s_policy.schedulingPriority = 10;
runtime.setServerSchedulingPolicy(s_policy);

//registering a set of services
shared_ptr&lt;HelloService_impl&gt; impl (new HelloService_impl());
res = DDS_Service::register_interface&lt;DDS_RMI::HelloWorld::HelloServiceInterface, HelloService_impl&gt; (impl, "HelloServer", 1);
// registering other services

// making HelloServer service the highest priority service
impl->set_priority(2);

//running the runtime
runtime->run();
```

![The image displays a standard warning sign. It features a red triangle with a thick red border and a white interior. Centered inside the triangle is a large black exclamation mark.](.vortex-opensplice-rmi-user-guide/0458a9e0b728928e2e603a15e409e3076d2e827a550894ec3571774148bef9b6.jpg)

Note that the threading policy may only be changed as long as the runtime is not run. Once run, only the thread pool size may be changed.

# 5

# Language mapping for Vortex OpenSplice RMI

Rmipp compilation follows a set of mapping rules to generate language-specific source code. Most of these rules come from the standard OMG IDL-to-C++ and IDL-to-Java mapping specifications but with some specific differences. This chapter focuses on specific parts of this mapping. For more information, please refer to the relevant OMG specifications.

The following figure shows the language mapping of the HelloService IDL interface previously defined.

![The diagram illustrates a code generation process, likely for a service interface.\n\n**Top Block:**\n*   Labeled `(IDL interface)`, titled `HelloService`, containing the method `string greet()`.\n\n**Connection:**\n*   An arrow labeled `rmipp` and `compilation` points downward from the top block.\n\n**Left Branch:**\n*   **Block 1:** Labeled `(class)`, titled `HelloServiceInterfaceProxy`, containing methods `greet () : DDS::String` and `async_greet (handler) : void`.\n*   **Block 2:** Labeled `(abstract)`, titled `greet_Reply_Handler`, containing the method `greet_Reply(DDS::String ret)`.\n*   **Connection:** A diamond-headed arrow points upward from Block 2 to Block 1.\n*   **Block 3:** Dashed brackets enclose the text `user-defined handler implementation`. An arrow points upward from this block to Block 2 (`greet_Reply_Handler`).\n\n**Right Branch:**\n*   **Block 1:** Labeled `(abstract)`, titled `HelloServiceInterface`, containing the method `greet () : DDS::String`.\n*   **Block 2:** Dashed brackets enclose the text `user-defined Interface implementation`. An arrow points upward from this block to the `HelloServiceInterface` block.](.vortex-opensplice-rmi-user-guide/8a382db10f02756ad35a858ad452903fc8f0f112d41b670cb607c7dee4029445.jpg)

# IDL Interface Mapping

# 5.1 Mapping for interfaces

An interface is mapped to two C++ (or Java) classes that contain public definitions of the operations defined in the interface.

The HelloServiceInterface abstract class is the base class of the HelloService implementation class. The HelloServiceInterfaceProxy class is the proxy object that represents locally the remote service. The client application should get a reference to this class to be able to invoke the remote service.

# 5.2 Mapping for operations

Each IDL operation, if not oneway, is mapped to two C++ functions (Java methods). The first one, having the same name as the IDL operation, is used for synchronous invocations. The second one, having async\_ concatenated to the IDL operation, is used for asynchronous invocations. A oneway operation maps only to the synchronous form of the operations.

The operations parameters and return types obey the same parameter passing rules as for the standard OMG IDL-to-C++ and IDL-to-Java mapping. The asynchronous functions (methods) will return void and take only the in/inout parameters of the IDL operation, as well as a callback object used as a reply handler. This handler class is also generated for each non-void operation as an inner abstract class of the proxy class as depicted in the diagram with the greet\_Reply\_Handler class. This latter should be implemented by the user to handle the asynchronous invocation reply. Hence, the greet\_Reply function (method) provides all the inout/out/return parameters of the corresponding IDL operation.

# 5.3 Mapping for basic types

The table below shows the ‘C++ and Java’ mapping of the IDL types that can be declared in the RMI services description file.

IDL sequences are mapped as specified by the DDS standard.

Mapping for basic types

<table><tr><td>IDL type</td><td>C++</td><td>Java</td></tr><tr><td>boolean</td><td>DDS::Boolean</td><td>boolean</td></tr><tr><td>char</td><td>DDS::Char</td><td>char</td></tr><tr><td>octet</td><td>DDS::Octet</td><td>byte</td></tr><tr><td>short</td><td>DDS::Short</td><td>short</td></tr><tr><td>unsigned short</td><td>DDS::UShort</td><td>short</td></tr><tr><td>long</td><td>DDS::Long</td><td>int</td></tr><tr><td>unsigned long</td><td>DDS::ULong</td><td>int</td></tr><tr><td>long long</td><td>DDS::LongLong</td><td>long</td></tr><tr><td>unsigned long long</td><td>DDS::ULongLong</td><td>long</td></tr><tr><td>float</td><td>DDS::Float</td><td>float</td></tr><tr><td>double</td><td>DDS::Double</td><td>double</td></tr><tr><td>string</td><td>DDS::String</td><td>String</td></tr></table>

![The image shows a standard warning sign featuring a red equilateral triangle with a black outline. Inside the triangle, centered against a white background, is a black exclamation mark.](.vortex-opensplice-rmi-user-guide/48fcc780e6234e901c29341f6d2b95cbf88bce17240adc2ee1d590ff38e53920.jpg)

![The image displays a white rectangular box with a teal border containing the black text 'C++' in a bold, sans-serif font.](.vortex-opensplice-rmi-user-guide/9976421ad822a661e7bb81b9562a8aff08a3a1072bcec8ae708093a6048ee74a.jpg)

Please be aware that the RMI middleware assumes ownership of any DDS::String that is provided to it (either by an in/inout argument or return value). This also means that it’ll free the given string. This can cause issues when the application keeps using the provided string after the RMI call or if RMI is called with a const string literal. It is advised to apply DDS::string\_dup(str) when using strings in conjunction with RMI. This is also applicable to sequences of strings.

# 6

# RMI Interface to DDS topics mapping rules

This chapter demonstrates the mapping rules driving the transformation of the IDL declarations of the RMI interfaces into the IDL declarations of the implied DDS topics.

• For each &lt;InterfaceName&gt;, a new module is created with the same name and scope in the module DDS\_RMI, where all the topics associated with the interface operations will be made.
• Each &lt;InterfaceName&gt;.&lt;operation name&gt; creates two data structures, suffixed respectively with \_request for the data structure that handles the request, and \_reply for the data structure that handles the reply.
• The &lt;operation name&gt;\_request data struct will gather all [in] or [inout] parameters.
• The &lt;operation name&gt;\_reply data struct will gather the return value and all [inout] or [out] parameters.
• req\_info is used to enable the client service handler to pick the reply it is waiting for.

```cpp
module HelloWorld {
    local interface HelloService : ::DDS_RMI::Services
    {
    void op1 (in string p1, inout short p2, out long p3);
    };
};
```

# rmipp

```txt
module DDS_RMI {
    module HelloWorld {
    module HelloService {

    struct op1_request {
    DDS_RMI::Request_Header req_info;
    string p1;
    short p2;
    };
    #pragma keylist op1_request req_info.client_id.client_impl
    req_info.client_id.client_instance

    struct op1_reply {
    DDS_RMI::Request_Header req_info;
    short p2;
    long p3;
    };
    #pragma keylist op1_reply req_info.client_id.client_impl
    req_info.client_id.client_instance
```

```txt
};
};
```

# 7

# RMI Runtime Configuration Options

The RMI runtime can be configured by a set of command line options. These options are passed directly to the runtime start operation as described in the section Runtime starting and stopping.

This chapter describes the set of supported options.

# 7.1 RMIClientThreadingModel option

```lua
--RMIClientThreadingModel = [ST | MT]
```

This option specifies the threading model of a given client. The ST and MT option values set respectively the Single-Threaded and Multi-Threaded models.

# 7.2 RMIServiceDiscoveryTimeout option

```txt
--RMIServiceDiscoveryTimeout = &lt;seconds&gt;
```

This is a client-side option that specifies the maximum duration (in seconds) that a client application can wait to find services. It influences the execution time of the DDS\_Service.getServerProxy operation that is used to find a given service. The default value is set to 10 seconds. The need to set this value may come from some specific deployment environements with bad communication conditions.

# 7.3 RMIServerThreadingModel option

```txt
--RMIServerThreadingModel=ST | MT | TPS [,&lt;thread-pool-size&gt;]
```

This is a server-side option that specifies the threading policy of the server runtime including the threading policy name and the thread pool size.

ST selects Single Threaded policy.

MT selects Multi Thread policy.

TPS selects Thread Per Service policy.

These policies are described in detail in the section Server Threading and Scheduling policies.

# 7.4 RMIServerSchedulingModel option

```txt
--RMIServerSchedulingModel=&lt;priority&gt;
```

This is a server-side option that specifies the scheduling policy of a Java server RMI runtime.

# 7.5 RMIDurability option

Note: The RMIDurability option is currently only implemented for C++.

[++

--RMIDurability = yes | no

This is a client-side and server-side option that indicates whether the underlying DDS middleware support the non-default durability Qos policies (TRANSIENT\_LOCAL and above) or not.

By default, this option value is yes.

RMI servers uses non-volatile topics for services advertising to allow late-joining clients to discover them. This option is useful for adapting services registration and discovery mechanisms when the durability support is missing in the underlying DDS middleware.

A Note that this feature must be either enabled or disabled for all of the RMI applications in a given DDS domain. It means that durability-\*en\*abled (option value is yes) RMI applications cannot be deployed with durability-\*dis\*abled (option value is no) RMI applications in the same DDS domain.

# 7.6 RMIClientSchedulingModel option

A Note: The RMIClientSchedulingModel option is currently only implemented for Java.

[ava

--RMIClientSchedulingModel=&lt;priority&gt;

This is a client-side option that specifies the priority of all the threads created by OpenSplice RMI at the client side, including the AsyncWaiter thread, which is the one that waits for asynchronous replies.

# 7.7 RMILegacyTopicNames option

△ Note: The RMILegacyTopicNames option applies only to C++.

C++

--RMILegacyTopicNames = yes | no

This client- and server-side option allows to switch topic names between a legacy-mode and a Java-compatible mode.

In legacy-mode, topics are named DDS\_ServiceDefinition and DDS\_ServiceIdentification. In this mode, a C++ RMI client or server is compatible with previous releases of C++ RMI. Since Java RMI uses different topic names, a C++ RMI client cannot communicate with a Java RMI server (or vice-versa). This is the default behaviour.

When legacy-mode is disabled, topics are named DDS\_RMIDefinition and DDS\_RMIIdentification. This enables compatibility with Java RMI which has always used these topic names, but unfortunately doesn’t allow communication with older versions of C++ RMI that don’t support this option.

# 8

# QoS policies XML schema

```xml
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.omg.org/dds/"
xmlns="http://www.omg.org/dds/"
elementFormDefault="qualified"&gt;
&lt;xsd:element name="dcps"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="domain" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name="domain"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element ref="topic" minOccurs="1" maxOccurs="unbounded"/&gt;
&lt;/xsd:sequence&gt;
&lt;xsd:attribute name="id" type="xsd:string" use="required"/&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name="topic"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="keylist" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element ref="topic_qos" minOccurs="0" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;xsd:attribute name="name" type="xsd:string" use="required"/&gt;
&lt;xsd:attribute name="idltype" type="xsd:string" use="required"/&gt;
&lt;xsd:attribute name="idlfile" type="xsd:string" use="required"/&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="keylist"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:sequence&gt;
&lt;xsd:element ref="keyMember" minOccurs="0" maxOccurs="unbounded"/&gt;
&lt;/xsd:sequence&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name="keyMember" type="xsd:string"/&gt;

&lt;xsd:element name="topic_qos"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="topicDataQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="deadlineQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="durabilityQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="durabilityServiceQosPolicy" minOccurs="0"
maxOccurs="1"/&gt;
&lt;xsd:element ref="latencyBudgetQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
```

```asp
&lt;xsd:element ref="livelinessQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="reliabilityQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="destinationOrderQosPolicy" minOccurs="0"
maxOccurs="1"/&gt;
&lt;xsd:element ref="historyQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="resourceLimitsQosPolicy" minOccurs="0"
maxOccurs="1"/&gt;
&lt;xsd:element ref="transportPriorityQosPolicy" minOccurs="0"
maxOccurs="1"/&gt;
&lt;xsd:element ref="lifespanQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="ownershipQosPolicy" minOccurs="0" maxOccurs="1"/&gt;
&lt;xsd:element ref="timeBasedFilterQosPolicy" minOccurs="0"
maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="deadlineQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="timeBasedFilterQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="topicDataQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element name="value" type="xsd:base64Binary" minOccurs="1"
maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="duration"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element name="sec" type="xsd:string" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="nanosec" type="xsd:string" minOccurs="1"
maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="durabilityQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="durabilityKind" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="durabilityKind"&gt;
&lt;xsd:simpleType&gt;
&lt;xsd:restriction base="xsd:string"&gt;
```

```xml
&lt;xsd:enumeration value="VOLATILE_DURABILITY_QOS"/&gt;
&lt;xsd:enumeration value="TRANSIENT_LOCAL_DURABILITY_QOS"/&gt;
&lt;xsd:enumeration value="TRANSIENT_DURABILITY_QOS"/&gt;
&lt;xsd:enumeration value="PERSISTENT_DURABILITY_QOS"/&gt;
&lt;/xsd:restriction&gt;
&lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="durabilityServiceQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element ref="historyKind" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="history_depth" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="max_samples" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="max_instances" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="max_samples_per_instance" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="historyKind"&gt;
&lt;xsd:simpleType&gt;
&lt;xsd:restriction base="xsd:string"&gt;
&lt;xsd:enumeration value="KEEP_LAST_HISTORY_QOS"/&gt;
&lt;xsd:enumeration value="KEEP_ALL_HISTORY_QOS"/&gt;
&lt;/xsd:restriction&gt;
&lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="latencyBudgetQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;
&lt;xsd:element name="livelinessQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element ref="livelinessKind" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="reliabilityQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="reliabilityKind" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="reliabilityKind"&gt;
&lt;xsd:simpleType&gt;
&lt;xsd:restriction base="xsd:string"&gt;
&lt;xsd:enumeration value="BEST_EFFORT_RELIABILITY_QOS"/&gt;
```

```xml
&lt;xsd:enumeration value="RELIABLE_RELIABILITY_QOS"/&gt;
&lt;/xsd:restriction&gt;
&lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="destinationOrderQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="destinationOrderKind" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="destinationOrderKind"&gt;
&lt;xsd:simpleType&gt;
&lt;xsd:restriction base="xsd:string"&gt;
&lt;xsd:enumeration value="BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS"/&gt;
&lt;xsd:enumeration value="BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS"/&gt;
&lt;/xsd:restriction&gt;
&lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="livelinessKind"&gt;
&lt;xsd:simpleType&gt;
&lt;xsd:restriction base="xsd:string"&gt;
&lt;xsd:enumeration value="AUTOMATIC_LIVELINESS_QOS"/&gt;
&lt;xsd:enumeration value="MANUAL_BY_PARTICIPANT_LIVELINESS_QOS"/&gt;
&lt;xsd:enumeration value="MANUAL_BY_TOPIC_LIVELINESS_QOS"/&gt;
&lt;/xsd:restriction&gt;
&lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="historyQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element ref="historyKind" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="depth" type="xsd:positiveInteger" default="1" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="resourceLimitsQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
&lt;xsd:element name="max_samples" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="max_instances" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="max_samples_per_instance" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="initial_samples" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;xsd:element name="initial_instances" type="xsd:positiveInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="transportPriorityQosPolicy"&gt;
&lt;xsd:complexType&gt;
&lt;xsd:all&gt;
```

```xml
&lt;xsd:element name="value" type="xsd:nonNegativeInteger" minOccurs="1" maxOccurs="1"/&gt;
&lt;/xsd:all&gt;
&lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="lifespanQosPolicy"&gt;
    &lt;xsd:complexType&gt;
    &lt;xsd:all&gt;
    &lt;xsd:element ref="duration" minOccurs="1" maxOccurs="1"/&gt;
    &lt;/xsd:all&gt;
    &lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="ownershipQosPolicy"&gt;
    &lt;xsd:complexType&gt;
    &lt;xsd:all&gt;
    &lt;xsd:element ref="ownershipKind" minOccurs="1" maxOccurs="1"/&gt;
    &lt;/xsd:all&gt;
    &lt;/xsd:complexType&gt;
&lt;/xsd:element&gt;

&lt;xsd:element name="ownershipKind"&gt;
    &lt;xsd:simpleType&gt;
    &lt;xsd:restriction base="xsd:string"&gt;
    &lt;xsd:enumeration value="SHARED_OWNERSHIP_QOS"/&gt;
    &lt;xsd:enumeration value="EXCLUSIVE_OWNERSHIP_QOS"/&gt;
    &lt;/xsd:restriction&gt;
    &lt;/xsd:simpleType&gt;
&lt;/xsd:element&gt;
&lt;/xsd:schema&gt;
```

# 9

# Contacts & Notices

# 9.1 Contacts

# ADLINK Technology Corporation

400 TradeCenter

Suite 5900

Woburn, MA

01801

USA

Tel: +1 781 569 5819

# ADLINK Technology Limited

The Edge

5th Avenue

Team Valley

Gateshead

NE11 0XA

UK

Tel: +44 (0)191 497 9900

# ADLINK Technology SARL

28 rue Jean Rostand

91400 Orsay

France

Tel: +33 (1) 69 015354

Web: http://ist.adlinktech.com/

Contact: http://ist.adlinktech.com

E-mail: ist\_info@adlinktech.com

LinkedIn: https://www.linkedin.com/company/79111/

Twitter: https://twitter.com/ADLINKTech\_usa

Facebook: https://www.facebook.com/ADLINKTECH

# 9.2 Notices

Copyright © 2018 ADLINK Technology Limited. All rights reserved.

This document may be reproduced in whole but not in part. The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of ADLINK Technology Limited. All trademarks acknowledged.
[🔗 Link to the original document](.vortex-opensplice-rmi-user-guide/vortex-opensplice-rmi-user-guide.pdf)
