2. Ultra Messaging JMS Overview

This section discusses the following topics.

2.1. The JMS Specification

The Oracle JMS Specification 1.0.2b provides requirements and guidelines for developing JMS-based Java messaging applications. The specification provides for two models: Publish/Subscribe, and Point-To-Point. Both models are supported by Ultra Messaging JMS.

Ultra Messaging JMS also supports Oracle JMS Specification 1.1, which unifies the class hierarchies of the Point-To-Point and Pub/Sub domains, but is fully backward compatible.

2.2. Publish/Subscribe Model

With the JMS publish/subscribe model, a JMS user (or client) publishes messages to a topic. Other clients then subscribe to the topic and are thus able to receive the published messages. The JMS model supports the concept of topic being an unadministered object (defined simply by its name), which directly correlates to the Ultra Messaging® model. You can configure Ultra Messaging JMS to use either the streaming or persistence features.

Figure 1. JMS Publish/Subscribe

Note: The maximum topic length is 246 bytes.

2.3. Point-To-Point Model

The Point-To-Point model differs from the Publish/Subscribe model mainly in that it employs a message queue and that the sending and receiving clients are aware of each other. Receiving clients extract messages from the queue and notifies it that the messages have been consumed. The queue retains messages until they are consumed or time out. Ultra Messaging JMS employs UM's queue provided by UMQ.

Figure 2. JMS Point To Point

Note: Ultra Messaging JMS supports a pull-based (or polling-based) implementation of this model, where the receiving application requests messages from the queue (as opposed to the queue automatically pushing messages). However, the underlying queue, as provided by UMQ, uses a push model.

2.4. JMS Messages

The JMS message generally consists of a header and body (data payload). You can set a JMS body type programatically and optionally identify the body type in a header field. JMS Messages can be of the types shown below. (Numeric values are used in the UM message property LBMMessageType.)

2.4.1. Message Components

When a JMS message passes through UM layers, its message properties are preserved as UM message properties. Also, header fields are translated into additional message properties.

Figure 3. Message Structure

A JMS message header consists of the following fields. In the UM layers, their information becomes UM message properties. Note that there is not always a one-to-one correlation between UM message properties and JMS properties/header fields.

  • JMSDestination

  • JMSDeliveryMode

  • JMSMessageID

  • JMSTimestamp

  • JMSCorrelationID

  • JMSReplyTo

  • JMSRedelivered

  • JMSType

  • JMSExpiration

  • JMSPriority

2.4.2. Message Properties

Message properties are defined by unique names and can be assigned values. UM supports all JMS message properties, which come in three categories.

JMS defined properties - The JMS Specification defines these properties (with prefix "JMSX") and reserves the use of their names.

Provider-specific properties - These are properties defined and reserved for UM, and include:

  • LBMMessageType (JMS message body types)

  • JMSTopicType (string, UMS/UMP/UMQ)

  • JMSReplyToName (string, topic name)

  • JMSReplyToWildcard (boolean)

  • JMSReplyToType (string, UMS/UMP/UMQ)

User properties - These are properties that you defined for your applications. A typical use for these is as Message Selectors.

2.5. JMS Implementation

The Ultra Messaging JMS API serves as a wrapper, allowing JMS clients access to UM functionality. This section describes in more detail the relationship between the Ultra Messaging JMS and UM layers.

2.5.1. JMS Architecture

The following diagram shows how Ultra Messaging JMS relates to the UM core middleware. When creating connections and sessions, you typically use JNDI (Java Naming and Directory Interface) to look up administered objects in Ultra Messaging Manager (UMM).

Figure 4. Ultra Messaging JMS Architecture

The store (UMP) can be used with Publish/Subscribe applications, and the UMQ queue is needed for use with Point-To-Point applications.

2.5.2. JMS-To-UM Object Mapping

From the JMS API layer to the Java API layer, there is a functional mapping of objects, as shown in the following diagram.

Figure 5. JMS-To-UM Mapping

ConnectionFactory - One of the two objects that are administered (the other being Destination). A client uses the ConnectionFactory to create a connection with a provider.

Connection - A connection to the provider can be either a queue connection or a topic connection, and creates session objects.

Session - The session is the factory for producing producers and consumers. The ConnectionFactory, Connection, and Session combine to functionally map to a UM context, though you can reuse a context for multiple ConnectionFactories/connections.

Producer - The producer maps directly to a UM source.

Consumer - The consumer maps directly to a UM receiver. The JMS concept of a durable consumer and persistent delivery employ UMP receivers and UMP persistent stores.

Destination - A client uses a destination to specify the target of messages it produces and/or the source of messages it consumes.

Message - The JMS and UM message are variations on each other, with the primary difference being that JMS message header fields are message properties in the UM message.

2.6. Ultra Messaging JMS Programming Architecture

The general JMS programming model is shown in the following figure. Life Cycle of an Ultra Messaging JMS Application offers details for developing producer and consumer applications.

Figure 6. JMS Programming Model

2.7. Quality of Service

Ultra Messaging JMS uses UMP and UMQ to provide the desired QoS based on the type of destination configured in JMSConfig.xml.

MessageProducer

MessageConsumer

2.8. Interoperability

In general, it is possible for JMS producers to send messages to UM receivers, or UM sources to send to JMS consumers. This is typically successful with default settings and message body types of TextMessage or BytesMessage. Such interoperability scenarios are also possible with non-default JMS or UM settings if you carefully select and test compatible configurations.

A JMS application can communicate with a UM application on a limited basis, with the proper attention paid to mapping with JMS headers and message properties. A UM application can receive and process the data of a JMS message the same way as when it receives standard UM messages.

2.8.1. Native Source

For a UM application sending to a JMS application, we recommend you send message data in byte or text format to avoid the risk of unrecognized data formatting. At the JMS application, set the DEFAULT_MESSAGE_TYPE attribute in FactoryAttributes to match this format. If you need to use more than one message type, at the UM source use the LBMMessageType property to manage this on a per-message basis.

2.8.2. Native Receiver

Native receiver applications can receive messages from a JMS producer. These messages contain all JMS message properties and JMS header information within their own UM message properties objects.

2.8.3. Request/Reply Example

The JMS Request/Reply feature employs the JMSReplyTo and JMSCorrelationID header fields to ensure that the correct receiver/consumer receives a reply and knows which request it pertains to. Consider the Request/Reply case where a native application issues a request to a JMS client (see the figure below).

Figure 7. Interoperation Example

In this scenario, the UM application sends a request that the JMS client receives, and the JMS application responds by sending a reply. The following sequence of events provides more detail about this scenario. Note that code excerpts are from a C-sharp UM application and a Java JMS application, and example classes may not be part of any UM API.

  1. The UM application creates a source, which sends a message on topic AAA. The application has set several message properties to identify the topic type, message type, who to reply to, and a unique message identifier.

                    LBMSourceSendExInfo exinfo = new LBMSourceSendExInfo();
    
                    /* We want JMS to reply via the JMSReplyTo */
                    LBMMessageProperties props = new LBMMessageProperties();
                    props.set("JMSReplyToName", replyTopicString);
                    props.set("JMSReplyToWildcard", false);
                    props.set("JMSReplyToType", "LBM");
                    props.set("JMSTopicType", "topic");
                    props.set("LBMMessageType", 0); // Indicates to JMS that the message payload will be a text message
                    exinfo.setMessageProperties(props);
                    exinfo.setFlags(LBM.SRC_SEND_EX_FLAG_PROPERTIES);
    
                    /* Added sequence number info flag to print out the expected JMSCorrelationID */
                    exinfo.setFlags(exinfo.flags() | LBM.SRC_SEND_EX_FLAG_SEQUENCE_NUMBER_INFO | LBM.SRC_SEND_EX_FLAG_UMQ_MESSAGE_ID_INFO);
    
                    src.send(message, msglen, block ? 0 : LBM.SRC_NONBLOCK, exinfo);
               
    
  2. The UM application also creates a receiver for the anticipated reply.

            private static string replyTopicString = "REPLY_" + Guid.NewGuid().ToString();
               
    

    The key here is that the source sends replyTopicString as a message property to provide a "return address". The application then creates a receiver that listens on this topic for the reply.

                SampleJMSRequestReceiver rcv = new SampleJMSRequestReceiver(verbose);
                LBMReceiverAttributes rattr = new LBMReceiverAttributes();
                LBMTopic replyTopic = ctx.lookupTopic(replyTopicString, rattr);
                
                LBMReceiver lbmrcv = new LBMReceiver(ctx, replyTopic, rcv.onReceive, null);
               
    
  3. The network passes the message to the JMS application, which converts message properties to JMS header field values and JMS properties, and confirms message type.

  4. The JMS application has a consumer that is listening on AAA. It receives the message.

  5. Using the JMS header fields, the JMS application's producer sends its reply message to the receiver, getting its reply destination extracted from the JMSReplyTo field. The native application's UM receiver already listening on this topic then receives the reply.

        public void onMessage(Message message) {
            try {
                TextMessage requestMessage = (TextMessage) message;
                String contents = requestMessage.getText();
                System.out.println("Got Message: " + contents);
                // get the reply to destination
                Destination replyDestination = requestMessage.getJMSReplyTo();
                
                TextMessage replyMessage = session.createTextMessage();
                contents = "Re:" + contents;
                replyMessage.setText(contents);
    
                replyMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
                System.out.println("Sending reply of: " + contents);
                
                replyProducer.send(replyDestination, replyMessage);
            } catch (Exception e) {
                System.err.println("Exception occurred: " + e.getMessage());
                System.exit(-1);
            }
        }
               
    
  6. The network again passes the reply message to the UM application, which converts JMS header field values and JMS properties to UM message properties usable by the receiver. The UM application uses the JMSCorrelationID to match the reply to its original request.

This example conveniently illustrates both native source and native receiver scenarios. Note that the key to successful interoperation is the correct exchange of information between UM message properties and JMS headers/properties.

2.8.4. Native Application Notes

When a native source or receiver accesses message property JMSDeliveryMode, the property must be an integer type, with a value of 1 (NON_PERSISTENT) or 2 (PERSISTENT). For example (in C language):

int delivery_mode = 1;
lbm_msg_properties_set(properties, "JMSDeliveryMode", &delivery_mode, LBM_MSG_PROPERTY_INT,
sizeof(int));
       

2.8.5. Compatibility With Other UM Features

Please note that while most UM features are compatible with Ultra Messaging JMS, some are not. Following is a table of features and their compatibilities with Ultra Messaging JMS.

UM Feature UM JMS Notes
Acceleration - DBL No  
Acceleration - UD No  
Hot Failover (HF) No  
Hot Failover Across Contexts (HFX) No  
Late Join Yes  
Message Batching Yes  
Monitoring/Statistics Yes  
Multicast Immediate Messaging (MIM) No  
Multi-Transport Threads No  
Off-Transport Recovery (OTR) Yes  
Ordered Delivery Yes  
Pre-Defined Messaging (PDM) Yes Must use BytesMessage
Request/Response No  
Self-Describing Messaging (SDM) Yes Must use BytesMessage
Source Side Filtering No  
Transport LBT-IPC Yes  
Transport LBT-RDMA Yes  
Transport LBT-RM Yes  
Transport LBT-RU Yes  
Transport TCP Yes  
Transport TCP-LB Yes  
UM Gateway No  
UM Spectrum No  
Wildcard Receivers Yes Cannot use wildcard and non-wildcard receivers simultaneously
Zero Object Delivery (ZOD) No  
UMP Implicit/Explicit Acknowledgements Yes  
UMP Persistent Store Yes  
UMP Proxy Sources Yes  
UMP Quorum Consensus Yes  
UMP Receiver-Paced Persistence (RPP) Yes  
UMP Registration ID/Session Management Yes  
UMP Round Robin Yes Not recommended
UMP Store Failover Yes Via umestored configuration
UMQ Application Sets Yes  
UMQ Parallel Queue Dissemination (PQD) Yes  
UMQ Queue Browser Yes  
UMQ Queue Failover Yes Via umestored configuration
UMQ Queue Redundancy Yes Via umestored configuration
UMQ Registration ID/Session Management Yes  
UMQ Serial Queue Dissemination (SQD) Yes  
UMQ Source Dissemination (SD) Yes  
UMQ Ultra Load Balancing (ULB) No Not inhibited
Ultra Messaging Desktop Services (UMDS) No  
Ultra Messaging Manager (UMM) Yes  
UM SNMP Agent Yes  
UMCache No  

2.9. Unsupported JMS Specifications

The Ultra Messaging JMS does not currently support the following JMS specifications.

Copyright (c) 2004 - 2014 Informatica Corporation. All rights reserved.