UMDS User Guide
UMDS Client

UMDS includes the UMDS API, which is a library of Ultra Messaging functions for use by desktop applications. UMDS Clients communicate with the UMDS Server with TCP connections. You cannot use UDP to connect a UMDS Client to a UMDS Server.


UMDS API  <-

The UMDS API is a more compact version of the Ultra Messaging API, intended to provide an easier and more consistent implementation of Ultra Messaging across enterprise desktops. The API is fully implemented for Java and .NET.


Server Connection  <-

A UMDS Client application can create multiple server connections, which can be to the same UMDS Server or different UMDS Servers.

  1. UMDS Client application creates a UMDSServerConnection object.

  2. UMDS Client application sets configuration options using the setProperty() method of the UMDSServerConnection object. At a minimum, the server-list property must be supplied. See Client Configuration Properties for the full list of properties.

  3. UMDS Client initiates the TCP connection using the start() method of the server connection object.

  4. UMDS Client logs into the server and receives configuration parameters. The application detects completion using the isAuthenticated() method of the server connection object.

  5. UMDS Client application creates sources (UMDSSource objects). and/or receivers (UMDSReceiver objects). Messages are sent and/or received using those objects.

  6. After it no longer needs the sources and/or receivers, the objects must be closed (using the "close()" API). The UMDS Server acknowledges those closings. The application should not simply let those objects become "garbage".

  7. When finished with all messaging, the UMDS Client closes the server connection using the close() method of the server connection object.

For a subscriber example application, see umdsreceive.java or umdsreceive.cs. For a publisher example application, see umdssend.java or umdssend.cs.


UMDS Server List  <-

The UMDS client must be configured with a server list using the server-list connection property. This property can be configured with one or more servers.

Having more than one server in the list accomplishes two things:

  • Load Sharing. When a UMDS client first initializes, it chooses a random server in the server list to initially connect to. Thus, if many clients are configured for the same list of servers, they will distribute themselves uniformly across the active servers.

  • Redundancy. If the currently-connected server fails, the UMDS client will automatically fail over to the next server on the list, wrapping to the start if it reaches the end.

Note that a client is never connected to more than one of these servers at the same time.

Contrast this with Connecting to Multiple Servers.

There is one more interesting use case related to the server list. Most client connection properties can be overridden by the server. Those overrides can be on an application or even a user basis. In particular, the server list can be overridden to redirect a client to another server.

You might have a UMDS Server that is used as the initial connection for all UMDS clients. The whole purpose of that server is to identify the application and user of the client, and override the server list property with a server (or server list) appropriate for that client. If a client's server list is overridden, the client will disconnect from that server and then reconnect to a server chosen from the new list.


Connecting to Multiple Servers  <-

A UMDS client can create multiple connections to different UMDS Servers. This involves creating more than one UMDSServerConnection object, and configuring each one with different server lists. These connections are independent; a receiver or source created in one does not imply that the same receiver or source is automatically created in the other. This technique is not used to provide redundancy or load sharing (see UMDS Server List).

Instead, the following use cases are reasons for creating multiple server connections:

  • Multiple, Unconnected UM TRDs. Although rare, some users have multiple instances of UM which are not interconnected. Each instance consists a TRD, or multiple TRDs connected with DROs. But the instances themselves are not routed to each other. No communication happens between these instances.

    For a client to exchange messages with both instances, separate UMDS Servers must be deployed in each instance. A UMDS client can create separate connection objects and connect to each of them.

  • Streaming and Persistence. A UMDS Server can be configured either for streaming (the default) or for persistence. When configured for steaming, the UMDS Server can receive messages from both streaming and persistent sources. However, when receiving from persistent sources, the persistence functionality is not used.

    A UMDS Server configured for persistence will implement the limited UMDS persistence functionality. However, this server cannot receive messages from streaming sources.

    For a UMDS client to get persistence functionality for persisted sources, and still be able to receive messages from streaming sources, two UMDS Servers need to be deployed. The UMDS client can create two connection objects and connect separately to the two servers.

    Note that streaming and persisted sources should not use the same topic names. UMDS is not designed for use cases where streaming and persisted sources share the same topics.

    For more information, see UMDS Persistence Differences.


Client Configuration Properties  <-

The UMDS Server connection object, class UMDSServerConnection, has properties that can be set by the client application. Unlike Ultra Messaging, the UMDS client does not read a file containing configuration options. Instead, the application must set properties using the setProperty() method of the UMDSServerConnection object.

Properties should be set after the UMDSServerConnection object is created but before it is connected (with UMDSServerConnection.start()).

Note that most of these properties represent client requests to set an operating parameter. The UMDS Server's configuration might restrict the client's ability to set these properties. See the child elements for the servers configuration element <client>. In the list below, those properties that can be controlled by the server are indicated by a link to the server's corresponding configuration element. Those properties without a link are purely controlled by the client.

Here are the UMDSServerConnection properties that can be set:

Property Description

Default

server-list

Comma-separated list of IP:Port addresses for one or more UMDS Servers for the client to initially connect to. Using multiple servers provides redundancy. If the currently-connected server fails, the UMDS client will connect to another server in the list.

See UMDS Server List for more information.

Note that the UMDS Server is able to overwrite this after connection. See the server's configuration element <server-list>.
EXAMPLE: serverConn.setProperty("server-list", "10.29.0.1:12000,10.29.1.1:12000");

(none, must be specified)

user User name for authentication. See Authenticating Applications and Users.

(none)

password Password for authentication. This is not a secure password. See Authenticating Applications and Users.

(none)

appl-name Application name for authentication. See Authenticating Applications and Users.

(none)

server-ka-interval Time in milliseconds between keepalive messages from the server. See the server's configuration element <server-ka-interval>.

2000 (2 sec)

server-ka-threshold Number of milliseconds of silence to wait before connection is declared dead. See the server's configuration element <server-ka-threshold>.

11000 (11 sec)

server-rcvbuf Specify the UMDS Server's TCP's SO_RCVBUF (receive-side socket buffer size) in its connection to the client. See the server's configuration element <server-rcvbuf>.

65536 (bytes)

server-sndbuf Specify the UMDS Server's TCP's SO_SNDBUF (send-side socket buffer size) in its connection to the client. <server-sndbuf>.

65536 (bytes)

server-nodelay Specify if the UMDS Server's TCP connection to the client should set the TCP_NODELAY socket option, which disables Nagle's algorithm. See the server's configuration element <server-nodelay>.

0 (Nagle is enabled)

server-reconnect Indicates whether the client should attempt to reconnect to the server if the connection fails. See the server's configuration element <server-reconnect>.

1 (enable auto reconnect)

client-ka-interval Milliseconds between keep-alive messages from the client. See the server's configuration element <client-ka-interval>.

3000 (3 sec)

client-ka-threshold Number of milliseconds of silence to wait before connection is declared dead. See the server's configuration element <client-ka-threshold>.

10000 (10 sec)

client-rcvbuf Specify the UMDS client's TCP's SO_RCVBUF (receive-side socket buffer size) in its connection to the server. See the server's configuration element <client-rcvbuf>.

65536 (bytes)

client-sndbuf Specify the UMDS client's TCP's SO_SNDBUF (send-side socket buffer size) in its connection to the server. See the server's configuration element <client-sndbuf>.

65536 (bytes)

client-nodelay Specify if the UMDS client's TCP connection to the server should set the TCP_NODELAY socket option, which disables Nagle's algorithm.

1 (Nagle disabled)

use-tls Direct the UMDS client to connect to the server using encryption. See Using UMDS Client Encryption.

0 (no encryption).

truststore Name of custom trust store file. If omitted, the operating system's default trust store is used. Java only; not supported for .NET.

(none)

truststore-password Password for trust store. If omitted, no password will be applied when accessing the trust store. (none)


Authenticating Applications and Users  <-

You can authenticate either UMDS Client applications or individual desktop users when they connect to the server. By default, UMDS automatically authenticates all clients during the connection phase.

Warning
The UMDS authentication system is for identification purposes only. The password is intended to prevent accidental misidentification. It NOT intended to provide security. By default, passwords are transmitted across the network in cleartext, and the server stores passwords in cleartext. See the Using UMDS Client Encryption feature if you need a secure connection.

You can embed user passwords in a UMDS Client application or provide users with a login prompt. UMDS does not provide a login prompt facility. If you choose to authenticate applications or users, the application must supply a password property using the setProperty() method of the UMDSServerConnection object. For an example, view the example application umdssend.java and search for svrconn.setProperty("password", password).

If an application or desktop user requires authentication upon connection to the UMDS Server, set the application name, user name, and password in a Basic Authentication File. UMDS formats and transmits these parameters when requesting a connection.


Assigning Different Client Settings to Your Application  <-

If your application requires different operating parameters from the UMDS Server, set the application name and parameters in a Basic Authentication File. UMDS formats and transmits these parameters when requesting a connection.


Application Name  <-

UMDS Server administrators use the application name to identify the client applications connected to the server. Application developers should coordinate their application names with the server administrator to ensure proper connections and authentication.


Receiving  <-

A UMDS Client application uses the UMDSReceiver. class to start a receiver object and subscribe to a topic. This creates a UMS proxy receiver object at the UMDS Server to listen for topic messages from other Ultra Messaging applications, including other UMDS client applications. As the UMDS Server receives messages for that topic, the UMDS Server routes the message to the proper UMDS Client applications.

In the following figure, a UMDS Client application subscribes to a topic. The UMDS Client application then receives a message on the topic from a remote Ultra Messaging sending application.

UMDS-rcv.png
  1. The UMDS Client application creates a UMDS receiver object. The UMDS client library tells the server, including the subscribed topic.
  2. The UMDS Server creates a UM "proxy" receiver facing the UM backbone, and acknowledges the receiver creation to the client.
  3. The server's UM proxy receiver receives messages, which the server forwards to the client.


Sending  <-

A UMDS Client application uses UMDSSource.send(). to send messages on a topic to the UMDS Server. The UMDS Server then uses a proxy source to stream these messages.

The following figure shows a UMDS Client application sending a message to all receivers listening on the topic.

UMDS_Send.png

A UMDS Client send performs the following steps.

  1. UMDS Client application uses UMDSSource.send(). to send a message to the UMDS Server.
  2. UMDS Server multicasts the message to the Ultra Messaging Backbone.
  3. UMDS Server uses Ultra Messaging to send the message to other UMDS Client applications subscribed to the topic.

Clients use nonblocking sends to send messages. If the send results in an EWOULDBLOCK, the UMDS Server temporarily disables the UMDS Client send socket, which applies back pressure to the client application. The UMDS Server automatically resends the message when the Ultra Messaging source transport unblocks.

You can also write UMDS Client applications that send Immediate Messages.


Request and Response Capability  <-

UMDS clients can issue requests, and can send and receive responses, by using the UMDS client interface. UMDS clients can exchange requests and responses with other UMDS clients or with non-UMDS Ultra Messaging sources and receivers.

You cannot explicitly cancel a request issued by a UMDS client. UMDS client requests automatically time out after a server-configured period. The server-configured period applies to all clients.

The following figure shows UMDS requests and responses:

request_response_capability.png

The following table describes the request and response operations shown in the preceding figure:

Operation Description

C# and Java Method

Request The sending application sends a request through a UMDS source object. The request_id parameter must be a 32-bit integer.

request()

Send Request The UMDS Server forwards the request across the UM network.

Request Callback The receiver object issues a callback to the receiving application. The receipt of the callback indicates the receipt of a request.

onRequest()

Response(s) The receiver sends zero or more responses.

respond()

Send Response(s) The UMDS Server forwards the response across the UM network.

n/a

Response Callback(s) The source object that sent the request issues one or more callbacks to the sending application. The receipt of the callbacks indicates the receipt of a response.

onResponse()

Request Timeout

Each request has its own timeout period. When the configured timeout expires on the UMDS Server, the UMDS Server sends a request timeout notification to the sending client's onEvent callback. The timeout notification indicates that the request is closed, and that the source will deliver no more responses for that particular request. Requests always time out regardless of the number of responses received. A sending client must send new requests if it is dissatisfied with the number of responses.

The server sends timeout notification messages to the sending client. Therefore, if the client disconnects from the server, the client cannot receive timeout notifications. When a client disconnects, the UMDS Server cancels all outstanding requests without notification. If the client reconnects, the server does not send to the client any responses or timeout notifications for the requests that the client issued before it disconnected.

onEvent()


Using UMDS Late Join  <-

The UMDS Server can provide a "Late Join" service to UMDS clients. The Late Join feature allows a new subscriber to a topic to receive previously-sent messages prior to receiving "live" messages from the topic's sources. The UMDS Late Join feature is a simplification of the Ultra Messaging Late Join feature (see UMDS Late Join Differences).

Note
This section describes the "streaming receiver" Late Join feature, not "persistence". By default, UMDS does not participate in Persistence. If desired, UMDS can be configured to participate in Persistence; see Using UMDS Persistence. However, note that UMDS Late Join and UMDS Persistence cannot both be enabled. UMDS Late Join is a streaming feature, and a UMDS Server configured for persistence does not work with streaming sources.
UMDS_LJ_flow.png

With Late Join enabled, the first application that subscribes to a topic causes the UMDS Server to create a UM "proxy" receiver for that topic, which initiates a Late Join request to the UM source(s) for that topic. The UMDS Server also creates a message cache for the topic and stores all received messages there. The cache is a fixed size; once it fills, new messages will push out the oldest messages. The purpose of the cache is to provide efficient Late Join service to subsequent UMDS clients.

During the initial late joining from the source, recovered messages will be forwarded to the UMDS client with the message's recovered flag set to true, indicating that the message is not "live". When the server's UM proxy receiver switches to live messages, those will be forwarded to the UMDS client with "recovered" set to false.

The amount of recovery data made available to UMDS clients is normally limited by the smaller of:

When a second UMDS Client application subscribes to the same topic, it receives Late Join recovery from the UMDS Server message cache, not from the source's retention buffer. Those recovered messages will be forwarded to the UMDS client with the message's recovered flag set to true, indicating that the message is not "live". When the server switches to live messages, those will be forwarded to the UMDS client with "recovered" set to false.

Note that if the UM source's retention size limit holds fewer messages than the UMDS Server's message cache size, live messages from the source will populate the additional space in the server's message cache. Thus, subsequent UMDS receivers for the topic can recover more messages than are retained in the source's retention buffer.

If there are multiple UM sources for the topic, the UMDS Server will add messages from all sources to the same message cache. Thus, the number of recovered messages from a given source can be smaller than the message cache size.

By default, Late Join is disabled for UMDS Client receive applications. To configure UMDS Client receiving applications to use Late Join, you must at a minimum set the "use-late-join" option in the UMDS Receiver Topic Options to 1, and set the "message-cache-size" option of the UMDS Receiver Topic Options.

The following example shows part of a UMDS Server Configuration File that sets the options related to a UMDS Client receiving application that uses Late Join on topic orderAW.

<topic pattern="orderAW" type="direct">
  <umds-attributes>
    <option type="umds-receiver" name="use-late-join" value="1" />
    <option type="umds-receiver" name="message-cache-size" value="10" />
    <option type="lbm-receiver" name="use_late_join" value="1" />
    <option type="lbm-receiver" name="late_join_info_request_interval"
          value="1000" />
    <option type="lbm-receiver" name="late_join_info_request_maximum"
          value="60" />
    <option type="lbm-receiver" name="retransmit_initial_sequence_number_request"
          value="1" />
    <option type="lbm-receiver" name="retransmit_message_caching_proximity"
          value="2147483647" />
    <option type="lbm-receiver" name="retransmit_request_interval"
          value="500" />
    <option type="lbm-receiver" name="retransmit_request_message_timeout"
          value="10000" />
  </umds-attributes>
</topic>
Note
To use the Late Join feature, the message cache type is configured to "normal" (the default). See <server>'s "message-cache-type" attribute.


UMDS Late Join Differences  <-

UMDS Late Join is a simplification of the UM Late Join. Be aware of these differences:

  • UMDS's message cache is sized in units of messages. Thus, the amount of memory consumed by the message cache can vary, depending on the sizes of application messages.
    In contrast, the UM late join retention buffer is sized in units of bytes. Thus, a UM source's retention buffer will hold different numbers of application messages, depending on the sizes of those messages.

  • A given topic's UMDS Server's message cache is populated from all sources for that topic. The number of messages from a given source will depend on the message rates of the other sources for the same topic. A very active source can, in effect, monopolize the cache, resulting in few, if any, messages from other less-active sources.
    In contrast, the UM late join retention buffer is implemented at each UM source, guaranteeing a certain amount of recoverable message data from each UM source.

  • The first UMDS subscriber for a given topic will receive its late join recovery messages directly from the server's UM proxy receiver. The amount of recovered data will depend on the UM sources' configured late join retention buffer sizes. This could significantly exceed the configured message cache size ("message-cache-size" option in the UMDS Receiver Topic Options).
    In contrast, subsequent UMDS subscribers for the same topic will receive their late join recovery messages from the server's message cache. The amount of recovered data will not exceed the configured message cache size.


Late Join UMDS Sources  <-

You can enable Late Join for UMDS sources in the same manner as for standard Ultra Messaging sources. This must be done on the UMDS Server via its configuration file. The following example excerpt from a UMDS Server Configuration File shows how to enable Late Join for topic orderAW. The example also shows other relevant source Late Join options.

<topic pattern="orderAW" type="direct">
  <umds-attributes>
    <option type="lbm-source" name="late_join" value="1" />
    <option type="lbm-source" name="retransmit_retention_age_threshold"
          value="0" />
    <option type="lbm-source" name="retransmit_retention_size_limit"
          value="25165824" />
    <option type="lbm-source" name="retransmit_retention_size_threshold"
          value="100" />
  </umds-attributes>
</topic>

For more information about Late Join source configuration options, see the Ultra Messaging Configuration Guide.


Using UMDS Persistence  <-

UMDS can be configured to participate in Persistence. Note that UMDS's persistence semantics are simplified from native UM's persistence.

Also note that UMDS Persistence functionality is similar to UMDS Late Join functionality. But there are important differences between these features:

  • UMDS recovery data is saved in a message cache that is specific to individual sources.
    In contrast, UMDS Late Join uses a single message cache for all sources to a particular topic.
    UMDS clients can control the starting point for recovery.
    In contrast, UMDS Late Join always attempts to recover a full message cache.

Because of these differences, it is not possible to enable both UMDS Late Join and UMDS Persistence at the same time.

Note
Only Source-Paced Persistence (SPP) persistence is supported. UM's Receiver-Paced Persistence (RPP) persistence should not be used. See persistence modes in Persistence Concepts.
UMDS_Persist_flow.png

With Persistence enabled, the first application that subscribes to a topic causes the UMDS Server to create a UM "proxy" receiver for that topic, which registers with the UM Stores and starts a recovery operation of previously-sent messages. The UMDS Server also creates a message cache for the topic/session ID, and stores all received messages there. The cache is a fixed size; once it fills, new messages will push out the oldest messages. The purpose of the cache is to provide efficient recovery service to subsequent UMDS clients.

During the initial persistence recovery from the Store, recovered messages will be forwarded to the UMDS client with the message's recovered flag set to true, indicating that the message is not "live". When the server's UM proxy receiver switches to live messages, those will be forwarded to the UMDS client with "recovered" set to false.

When a second UMDS Client application subscribes to the same topic, it receives recovery data from the UMDS Server message cache, not from the Store. Those recovered messages will be forwarded to the UMDS client with the message's recovered flag set to true, indicating that the message is not "live". When the server switches to live messages, those will be forwarded to the UMDS client with "recovered" set to false.

Central to UMDS's support for persistence is its use of message caches. This is very similar to the message caches used by UMSD's Late Join functionality (see Using UMDS Late Join), but with an important difference: UMDS creates multiple caches for a given receiver corresponding to the different persistent sources joined. For example, if there are two persistent sources for topic "ABC", the UMDS Server will create two independent message caches, one for each source. A persisted source's session ID is used as the key to differentiate it from other persisted sources for the same topic.

To use UMDS Persistence, the UMDS Server must be configured for persistence and the UMDS client must create persistent receivers using the class UMDSPersistentReceiver. If an application needs to receive some persisted messages and some streaming messages, it will need to connect to two different UMDS Servers, one configured for persistence and the other not.

The steps in receiving a persisted message are largely the same as receiving a non-persisted message. See Server Connection. However, instead of creating a UMDSReceiver object, the client creates a UMDSPersistentReceiver object.

After the UMDSPersistentReceiver object is created, UMDS invokes an application callback (using the UMDSReceiverRecoveryInfoCallback object) when the receiver is associated with a persistent source. That callback provides persistence information related to that source, and allows the application to control recovery. If there is more than one persisted source for a receiver's topic, the callback will be invoked multiple times, once for each source. Each source can have different persistence information (session ID, low sequence number, etc.).

The primary job of the application's recovery callback is to decide which messages should be recovered. Unlike UM persistent receivers, UMDS does not attempt to remember where persistent receivers left off. Instead, the application is told the earliest sequence number available in the Store's message cache, and the application can override it to define where message recovery starts.

See the example application umdspersistentreceive.java or umdspersistentreceive.cs.


UMDS Persistence uses Session IDs  <-

With UM persistence, publishers can use either session IDs or registration IDs. To be compatible with UMDS persistence, UM publishers must use session IDs. See Managing RegIDs with Session IDs.

UMDS uses the sources' session IDs to:

  • Manage multiple message caches per topic, one cache per source. The source's session ID is used to route to the proper message cache.
  • Manage recovery information callbacks to the UDMS client application. The application access persistence information by session ID.
  • As messages are received, the UMDSMessage class contains the public member source_session_id that indicates which source it came from. The application is responsible for keeping track of processed message sequence numbers (using the seqnum public member) on a topic/session_id basis.


Configuring UMDS Server for Persistence  <-

An instance (process) of the UMDS Server can be configured to participate in UM persistence. If so, that server will not receive messages from a non-persisted source.

On the other hand, if the UMDS Server is configured for normal operation (not persistence), that server will be able to receive messages from both persisted and non-persisted sources. However, for persisted sources, the UMDS Server will not "participate" in the persistence. I.e. the server will not be able to recover missed messages. A persisted source will be treated the same as a non-persisted source.

If a client application needs to participate in persistence for some topics, but also wants to receive messages from non-persisted sources for other topics, two instances of the UMDS Servers will need to be available: one configured for persistence and the other not.

To configure a server for persistence, do the following:

  • Set the "message-cache-type" attribute of the UMDS Element "<server>" to "source-session-id". For example:

    <server message-cache-type="source-session-id" ... />
    

  • Set the "use-late-join" option in the UMDS Receiver Topic Options to 1. For example:

    <topics>
      <topic ...>
        <umds-attributes>
          <option type="umds-receiver" name="use-late-join" value="1" />
    ...
    

  • Set the "message-cache-size" option in the UMDS Receiver Topic Options to the number of messages that should be cached. For example:

    <topics>
      <topic ...>
        <umds-attributes>
          <option type="umds-receiver" name="message-cache-size" value="100" />
    ...
    

  • Set the "message-cache-deletion-delay" option in the UMDS Receiver Topic Options to the number of milliseconds a message cache should be maintained after all UMDS clients delete their persistent receivers for that topic. For example, to set the deletion timer to 1 hour:
    <topics>
      <topic ...>
        <umds-attributes>
          <option type="umds-receiver" name="message-cache-deletion-delay" value="3600000" />
    ...
    
    The purpose for not deleting the message cache immediate when all client receivers are deleted is to be more efficient if a short time later a client reconnects and re-creates the receiver, as with the Transient Receivers use case.

See UMDS Server Configuration for full details.


Transient Receivers  <-

A common use case for UMDS persistence is called "transient receivers." In this use case, an application does not stay connected to the UMDS Server for long periods of time. Instead, an application might connect to the server, create sources and persistent receivers, perform a limited set of transactions, and then disconnect. Many seconds or minutes might pass between connections.

In this use case, the application remembers the sequence number of the last message it received during its previous connection, and uses that to control recovery.

Here is a sequence that describes the use case. Let's assume that the UMDS Server is configured to hold 50 messages in its message cache.

  1. The last time the client application was connected, it last received message number 100. At this point, the UMDS Server's message cache contains 51-100.

  2. While the client application is disconnected, the source sends messages 101-110. At this point, the UMDS Server's message cache contains 61-110.

  3. The client application reconnects. When UMDS invokes the UMDSReceiverRecoveryInfoCallback object, the application learns that the low sequence number in the message cache is 61. But the application remembers that its last received message was 100. So it overrides the low sequence number to 101.

  4. The Server delivers messages 101-110 to the client application, followed by any live messages sent by the source while the application is connected.

Note that if there is more than one persistent source for a subscribed topic, each one will have its own independent sequence number. Each received message is delivered in a UMDSMessage object. The source_session_id public member indicates which source it came from. The application is responsible for keeping track of processed message sequence numbers (using the seqnum public member) on a topic/session_id basis. This allows the client to disconnect and reconnect and specify the starting point for recovery when the UMDSReceiverRecoveryInfoCallback is invoked.

If the client application exits and restarts with no knowledge of its last received message, it can leave the low sequence number unchanged, and the server will deliver all messages stored in its message cache.

The "message-cache-deletion-delay" option in the UMDS Receiver Topic Options should be set to the maximum number of milliseconds that a transient receiver is expected to remain disconnected. If a server has no persistent client receivers for a given message cache for more than that time, UMDS will delete the message cache.

If a UMDS client application subsequently creates a persistent receiver for that topic, the UMDS Server will need to re-create the message cache, re-register with the UM Store, and recover messages from UM's persistence. This is not an error condition, but it introduces delays and inefficiency.


Persistence and Server Failover  <-

The UMDS persistence feature is also useful for recovering messages that were sent when a UMDS Server fails and a client needs to switch to an alternate server. (Both servers must be configured for persistence.)

When a UMDS client detects that its currently connected server has failed, it can fail over to a different configured server (see UMDS Server List). As with Transient Receivers, the application keeps track of its last received message from each source. When it re-creates its proxy receiver, that new server will use UM's persistence to recover data from the UM Store. Then, a new set of recovery callbacks are made. The application should supply the next expected sequence number for each session ID, and the UMDS Server will recover any missed messages.


UMDS Persistence Differences  <-

Users of UM persistence will see some differences in how UMDS persistent receivers behave. This section outlines some differences and limitations of UMDS persistence.

  • A UMDS client can only create persistent receivers. Persistent publishing is not supported by UMDS.

  • A UMDS Server configured for persistence must be used only for persistent sources using a session ID. A UM source that is not persisted with a session ID will generate an error and no messages will be accepted (see UMDS Persistence uses Session IDs). A UMDS client that creates a non-persistent receiver will be rejected (disconnected).
    (In contrast, a UM receiver can be configured to accept both persistent and non-persistent sources.)

  • Only UM's SPP persistence (the default) is supported. RPP should not be used.

  • A UMDS client that creates a persistent receiver but connects to a non-persistent server will be rejected (disconnected).

  • The amount of recovery data made available to UMDS clients is normally limited by the smaller of:

    • The Store's UM Persistent Store's disk repository size,
    • The UMDS Server's message cache size - see "message-cache-size" option of the UMDS Receiver Topic Options. Note that a Store's disk repository can typically be made much larger than the UMDS Server's message cache, since the latter is stored in memory. Thus, the server's message cache size is typically the limiting factor for the number of messages that can be recovered by UMDS persistent receivers.

  • Whereas an Ultra Messaging persistent subscriber acknowledges consumption of received message, the UMDS persistent subscriber does not. Thus, the UMDS Server does not remember which message a subscriber last consumed. No attempt is made by UMDS to inform a restarted receiver the sequence number it should recover from. Instead, the receiver is informed of the oldest sequence number available in the Server.

  • When a UMDS client creates a persistent receiver, a series of one or more handshakes is made with the UMDS Server to associate the receiver with UM persistent sources of the desired topic. The application is informed of the oldest (lowest) sequence number stored in the server's message cache for each unique UM persisted source, and the application has the option of overriding that sequence number as its recovery starting place.

    However, due to the time required to handshake the sequence number, it is possible that the desired recovery starting sequence number is no longer in the server's message cache.

  • UM Persistence leverages the UM Late Join functionality. UM persistent sources and receivers must be enabled for Late Join. In fact, if a UMDS Server is configured for persistence, the UM proxy receiver in the server must be configured for Late Join.

    However, the UMDS persistence and Late Join features are implemented differently, and are not compatible with each other. UMDS Late Join is a streaming feature, and a UMDS Server configured for persistence does not work with streaming sources.

  • UMDS's message cache lifetime is not coordinated with the UM Store's source repository lifetime. With UM persistence, when a persisted source exits, the Store will maintain the sources previously-sent messages until either the source returns, or until the repository's state lifetime expires. If the source does not return and the state lifetime expires, subsequent persistent receivers will not be able to recover messages sent by that source.

    However, the UMDS message cache lifetime is associated with UMDS client receiver interest. So long as at least one UMDS client has a receiver for a persisted topic, the UMDS Server will maintain the message cache(s) for that topic's sources, even if those sources exit and their UM Store's state lifetimes expire.


Using UMDS Client Encryption  <-

UMDS supports encrypting the connection between the UMDS Server and client. It makes use of TLS (Transport Layer Security), sometimes known by its older designation SSL (Secure Sockets Layer), which is a family of standard protocols and algorithms for securing TCP communication between a client and a server. TLS supports secure authentication (through certificates), data confidentiality (through encryption), and data integrity (ensuring data are not changed, removed, or added-to).

The implementation of UMDS's TLS leverages the UM feature Encrypted TCP, but with some important differences:

  • Whereas UM requires an entire Topic Resolution Domain to be configured for encryption, UMDS's encryption is on a server basis. If a UMDS Server is configured for encryption, all connecting clients must also be configured for encryption.

  • Whereas UM only encrypts the data transports, leaving topic resolution in cleartext, UMDS encrypts its entire client/server connection. All traffic, both user data and internal control messages, are encrypted.

Note that enabling UMDS client encryption does not enable encryption of the server's UM context. Both can be enabled, but they are independent. See Encrypted TCP for UM context encryption.

UMDS client encryption is enabled using configuration; no encryption APIs are needed. When the UMDS Server is configure for encryption, all clients that connect to it must also be configured for encryption. Conversely, if the UMDS Server is not configured for encryption, none of the clients may be configured for it.

As with UM encryption, UMDS encryption is certificate based. Both the client and server must have a valid TLS certificate, and each must have the other's public key in its list of valid certificates.

Note
The Client Compression feature is not compatible with encryption. If you enable encryption, do not enable compression.


UMDS TLS Authentication  <-

TLS authentication uses X.509 digital certificates. Certificate creation and management is the responsibility of the user. Ultra Messaging's usage of OpenSSL expects PEM encoded certificates. There are a variety of generally available tools for converting certificates between different encodings. Since user infrastructures vary widely, the UM package does not include tools for creation, formatting, or management of certificates.

A detailed discussion of certificate usage is beyond the scope of the Ultra Messaging documentation. However, you can find a step-by-step procedure for creating a self-signed X.509 security certificate here: https://kb.informatica.com/howto/6/Pages/18/432752.aspx

Note
The TLS authentication feature is separate and unrelated to the UMDS user/password authentication feature. TLS authentication is primarily intended to secure the connecting hosts, not to identify individual users. By keeping private keys secure, TLS will prevent an unauthorized host from connecting to a UMDS client or server.

Identification of users and applications should still use the UMDS application/user authentication feature, described in Authenticating Applications and Users. As explained in that section, the password mechanism implemented there is not a secure password, and is intended to prevent accidental misidentification.


Configuring Encryption on Client  <-

To use the TLS encryption feature, both the client and the server must be configured for TLS.

To configure the client, setProperty() set the property use-tls to 1 using the method of the UMDSServerConnection object. For example: serverConn.setProperty("use-tls", "1");

If you are using Java and have a custom key store, you may specify it with the truststore property.

If your trust store is password protected, you can supply the password with the truststore-password property.


Configuring Encryption on Server  <-

To use the TLS encryption feature, both the client and the server must be configured for TLS.

To configure the server, refer to:


Client Compression  <-

UMDS supports compressing the connection between the UMDS Server and client. The primary purpose of compression is to reduce the bandwidth requirement, not to improve latency.

  • Compression is configured on a UMDS Server basis. I.e. a server is either configured for compression or not (default is not).
  • If a server is configured for compression, all clients must support compression, and must therefore be UMDS version 6.14 or above.
  • If a server is not configured for compression, it can interoperate with UMDS clients running earlier versions of the UMDS client library. For example a 6.14 server not configured for compression can service UMDS 6.13.1 clients.
  • A server configured for compression should not enable encryption; the features are not compatible.

See UMDS Element "<compression>" for configuration information.


Log Handling  <-

By default, the UMDS Server's log file grows without bound for as long as it is running. If the server is restarted, it opens the log file in "append" mode and writes new logs to the end of the file. Thus, over time, the log file can become very large. (This "open with append" behavior is new as of UMDS version 6.14; see Special Upgrade Instructions for 6.14.)

The "frequency" and "size" attributes for the UMDS Element "<log>" can be used to control the log file length. It does this by "rolling" the log file - closing the current one and creating a new one with a different name.

With no log rolling, the log file created is exactly as specified by the <log> element. However, if any of the log rolling attributes are specified, the configured log file name is always appended by a numeric date/time stamp of the form: ".yyyy-mm-dd.hh.mm.dd". For example, the configuration:

<log type="file" frequency="hourly">umds.log</log>

will create a log file line like this:

umds.log.2024-01-20.09-08-09

This indicates that the log file was created on January 20, 2024 at 9:08:09.

Note
UM log file rolling does not delete old log files. It is still the user's responsibility to delete old log files that are no longer needed. Informatica recommends retaining at least a week's worth of log files.


Size-Based Log Rolling  <-

By using the "size" attribute to the UMDS Element "<log>" the UMDS Server will close the current log file and start a new one automatically when it has written the specified number of megabytes (1,000,000 bytes) to the log file. The new log file will be named according to the date/time that the server creates the new log file.


Time-Based Log Rolling  <-

By using the "frequency" attribute to the UMDS Element "<log>" the UMDS Server will close the current log file and start a new one automatically at the specified interval. There are three valid values for the "frequency" attribute:

  • disable - do not roll the log file based on time (default).
  • hourly - Roll log file when the UMDS Server has been running for a multiple of 60 minutes since it was started.
  • daily - Roll log file when the UMDS Server has been running for a multiple of 24 hours since it was started.

Note that the log file rolling does not happen at the start of the hour/day. For example, let's say your server's configuration contains:

<log type="file" frequency="hourly">umds.log</log>

and it is started on January 1, 2024 at 9:08:09 AM. The initial log file will be named:

umds.log.2024-01-20.09-08-09

Then, 60 minutes later, the server will be ready to roll the log file (close the current and create a new one).

However, the server will not actually roll the log file until the server generates its next log message. Let's say a client connects at 10:28:03, which generates a log message. This will trigger the UMDS Server to close the "umds.log.2024-01-20.09-08-09" file and create "umds.log.2024-01-20.10-28-03".

Note that you can even have instances where one or more time periods contain no log files at all. In the above example, the server will be ready to roll the log file at 11:28:03. However, if the UMDS Server has nothing to log for three hours, there will be no log file for the 11 o-clock hour or the 12 o-clock hour. log would be at 11:28:03.


Combined Log Rolling  <-

By using both the "size" and "frequency" attributes of the UMDS Element "<log>" the UMDS Server will close the current log file and start a new one automatically when it has written the specified number of megabytes (1,000,000 bytes) to the log file or at the specified interval. The new log file will be named according to the date/time that the server creates the new log file.

For example, let's say your server's configuration contains:

<log type="file" size="1" frequency="hourly">umds.log</log>

and it is started on January 1, 2024 at 9:08:09 AM. The initial log file will be named:

umds.log.2024-01-20.09-08-09

For a quickly-growing log file, the file will roll each time 1 megabyte of log messages are written. For a slowly-growing log file, the file will roll after the hourly interval.