Ultra Messaging JMS Guide

March 2014

Informatica Ultra Messaging

Version 5.3

March 2014

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

This software and documentation contain proprietary information of Informatica Corporation and are provided under a license agreement containing restrictions on use and disclosure and are also protected by copyright law. Reverse engineering of the software is prohibited. No part of this document may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording or otherwise) without prior consent of Informatica Corporation. This Software may be protected by U.S. and/or international Patents and other Patents Pending.

Use, duplication, or disclosure of the Software by the U.S. Government is subject to the restrictions set forth in the applicable software license agreement and as provided in DFARS 227.7202-1(a) and 227.7702-3(a) (1995), DFARS 252.227-7013(c)(1)(ii) (OCT 1988), FAR 12.212(a) (1995), FAR 52.227-19, or FAR 52.227-14 (ALT III), as applicable.

The information in this product or documentation is subject to change without notice. If you find any problems in this product or documentation, please report them to us in writing.

Informatica, Informatica Platform, Informatica Data Services, PowerCenter, PowerCenterRT, PowerCenter Connect, PowerCenter Data Analyzer, PowerExchange, PowerMart, Metadata Manager, Informatica Data Quality, Informatica Data Explorer, Informatica B2B Data Transformation, Informatica B2B Data Exchange Informatica On Demand, Informatica Identity Resolution, Informatica Application Information Lifecycle Management, Informatica Complex Event Processing, Ultra Messaging and Informatica Master Data Management are trademarks or registered trademarks of Informatica Corporation in the United States and in jurisdictions throughout the world. All other company and product names may be trade names or trademarks of their respective owners.

Portions of this software and/or documentation are subject to copyright held by third parties, including without limitation: Copyright DataDirect Technologies. All rights reserved. Copyright (c) Sun Microsystems. All rights reserved. Copyright (c) RSA Security Inc. All Rights Reserved. Copyright (c) Ordinal Technology Corp. All rights reserved.Copyright (c) Aandacht c.v. All rights reserved. Copyright Genivia, Inc. All rights reserved. Copyright Isomorphic Software. All rights reserved. Copyright (c) Meta Integration Technology, Inc. All rights reserved. Copyright (c) Intalio. All rights reserved. Copyright (c) Oracle. All rights reserved. Copyright (c) Adobe Systems Incorporated. All rights reserved. Copyright (c) DataArt, Inc. All rights reserved. Copyright (c) ComponentSource. All rights reserved. Copyright (c) Microsoft Corporation. All rights reserved. Copyright (c) Rogue Wave Software, Inc. All rights reserved. Copyright (c) Teradata Corporation. All rights reserved. Copyright (c) Yahoo! Inc. All rights reserved. Copyright (c) Glyph & Cog, LLC. All rights reserved. Copyright (c) Thinkmap, Inc. All rights reserved. Copyright (c) Clearpace Software Limited. All rights reserved. Copyright (c) Information Builders, Inc. All rights reserved. Copyright (c) OSS Nokalva, Inc. All rights reserved. Copyright Edifecs, Inc. All rights reserved. Copyright Cleo Communications, Inc. All rights reserved. Copyright (c) International Organization for Standardization 1986. All rights reserved. Copyright (c) ej-technologies GmbH. All rights reserved. Copyright (c) Jaspersoft Corporation. All rights reserved. Copyright (c) is International Business Machines Corporation. All rights reserved. Copyright (c) yWorks GmbH. All rights reserved. Copyright (c) Lucent Technologies. All rights reserved. Copyright (c) University of Toronto. All rights reserved. Copyright (c) Daniel Veillard. All rights reserved. Copyright (c) Unicode, Inc. Copyright IBM Corp. All rights reserved. Copyright (c) MicroQuill Software Publishing, Inc. All rights reserved. Copyright (c) PassMark Software Pty Ltd. All rights reserved. Copyright (c) LogiXML, Inc. All rights reserved. Copyright (c) 2003-2010 Lorenzi Davide, All rights reserved. Copyright (c) Red Hat, Inc. All rights reserved. Copyright (c) The Board of Trustees of the Leland Stanford Junior University. All rights reserved. Copyright (c) EMC Corporation. All rights reserved. Copyright (c) Flexera Software. All rights reserved. Copyright (c) Jinfonet Software. All rights reserved. Copyright (c) Apple Inc. All rights reserved. Copyright (c) Telerik Inc. All rights reserved.

This product includes software developed by the Apache Software Foundation (http://www.apache.org/), and/or other software which is licensed under various versions of the Apache License (the "License"). You may obtain a copy of these Licenses at http://www.apache.org/licenses/. Unless required by applicable law or agreed to in writing, software distributed under these Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses.

This product includes software which was developed by Mozilla (http://www.mozilla.org/), software copyright The JBoss Group, LLC, all rights reserved; software copyright (c) 1999-2006 by Bruno Lowagie and Paulo Soares and other software which is licensed under various versions of the GNU Lesser General Public License Agreement, which may be found at http:// www.gnu.org/licenses/lgpl.html. The materials are provided free of charge by Informatica, "as-is", without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose.

The product includes ACE(TM) and TAO(TM) software copyrighted by Douglas C. Schmidt and his research group at Washington University, University of California, Irvine, and Vanderbilt University, Copyright (c) 1993-2006, all rights reserved.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (copyright The OpenSSL Project. All Rights Reserved) and redistribution of this software is subject to terms available at http://www.openssl.org and http://www.openssl.org/source/license.html.

This product includes Curl software which is Copyright 1996-2007, Daniel Stenberg, <daniel@haxx.se>. All Rights Reserved. Permissions and limitations regarding this software are subject to terms available at http://curl.haxx.se/docs/copyright.html. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

The product includes software copyright 2001-2005 (c) MetaStuff, Ltd. All Rights Reserved. Permissions and limitations regarding this software are subject to terms available at http://www.dom4j.org/ license.html.

The product includes software copyright (c) 2004-2007, The Dojo Foundation. All Rights Reserved. Permissions and limitations regarding this software are subject to terms available at http://dojotoolkit.org/license.

This product includes ICU software which is copyright International Business Machines Corporation and others. All rights reserved. Permissions and limitations regarding this software are subject to terms available at http://source.icu-project.org/repos/icu/icu/trunk/license.html.

This product includes software copyright (c) 1996-2006 Per Bothner. All rights reserved. Your right to use such materials is set forth in the license which may be found at http:// www.gnu.org/software/ kawa/Software-License.html.

This product includes OSSP UUID software which is Copyright (c) 2002 Ralf S. Engelschall, Copyright (c) 2002 The OSSP Project Copyright (c) 2002 Cable & Wireless Deutschland. Permissions and limitations regarding this software are subject to terms available at http://www.opensource.org/licenses/mit-license.php.

This product includes software developed by Boost (http://www.boost.org/) or under the Boost software license. Permissions and limitations regarding this software are subject to terms available at http:/ /www.boost.org/LICENSE_1_0.txt.

This product includes software copyright (c) 1997-2007 University of Cambridge. Permissions and limitations regarding this software are subject to terms available at http:// www.pcre.org/license.txt.

This product includes software copyright (c) 2007 The Eclipse Foundation. All Rights Reserved. Permissions and limitations regarding this software are subject to terms available at http:// www.eclipse.org/org/documents/epl-v10.php.

This product includes software licensed under the terms at http://www.tcl.tk/software/tcltk/license.html, http://www.bosrup.com/web/overlib/?License, http://www.stlport.org/doc/ license.html, http:// asm.ow2.org/license.html, http://www.cryptix.org/LICENSE.TXT, http://hsqldb.org/web/hsqlLicense.html, http://httpunit.sourceforge.net/doc/ license.html, http://jung.sourceforge.net/license.txt , http://www.gzip.org/zlib/zlib_license.html, http://www.openldap.org/software/release/license.html, http://www.libssh2.org, http://slf4j.org/license.html, http://www.sente.ch/software/OpenSourceLicense.html, http://fusesource.com/downloads/license-agreements/fuse-message-broker-v-5-3- license-agreement; http://antlr.org/license.html; http://aopalliance.sourceforge.net/; http://www.bouncycastle.org/licence.html; http://www.jgraph.com/jgraphdownload.html; http://www.jcraft.com/jsch/LICENSE.txt; http://jotm.objectweb.org/bsd_license.html; . http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231; http://www.slf4j.org/license.html; http://nanoxml.sourceforge.net/orig/copyright.html; http://www.json.org/license.html; http://forge.ow2.org/projects/javaservice/, http://www.postgresql.org/about/licence.html, http://www.sqlite.org/copyright.html, http://www.tcl.tk/software/tcltk/license.html, http://www.jaxen.org/faq.html, http://www.jdom.org/docs/faq.html, http://www.slf4j.org/license.html; http://www.iodbc.org/dataspace/iodbc/wiki/iODBC/License; http://www.keplerproject.org/md5/license.html; http://www.toedter.com/en/jcalendar/license.html; http://www.edankert.com/bounce/index.html; http://www.net-snmp.org/about/license.html; http://www.openmdx.org/#FAQ; http://www.php.net/license/3_01.txt; http://srp.stanford.edu/license.txt; http://www.schneier.com/blowfish.html; http://www.jmock.org/license.html; http://xsom.java.net; and http://benalman.com/about/license/; https://github.com/CreateJS/EaselJS/blob/master/src/easeljs/display/Bitmap.js; http://www.h2database.com/html/license.html#summary; and http://jsoncpp.sourceforge.net/LICENSE.

This product includes software licensed under the Academic Free License http://www.opensource.org/licenses/afl-3.0.php), the Common Development and Distribution License (http://www.opensource.org/licenses/cddl1.php) the Common Public License (http://www.opensource.org/licenses/cpl1.0.php), the Sun Binary Code License Agreement Supplemental License Terms, the BSD License (http:// www.opensource.org/licenses/bsd-license.php) the MIT License (http://www.opensource.org/licenses/mit-license.php) and the Artistic License (http://www.opensource.org/licenses/artistic-license-1.0).

This product includes software copyright (c) 2003-2006 Joe WaInes, 2006-2007 XStream Committers. All rights reserved. Permissions and limitations regarding this software are subject to terms available at http://xstream.codehaus.org/license.html. This product includes software developed by the Indiana University Extreme! Lab. For further information please visit http://www.extreme.indiana.edu/.

This Software is protected by U.S. Patent Numbers 5,794,246; 6,014,670; 6,016,501; 6,029,178; 6,032,158; 6,035,307; 6,044,374; 6,092,086; 6,208,990; 6,339,775; 6,640,226; 6,789,096; 6,820,077; 6,823,373; 6,850,947; 6,895,471; 7,117,215; 7,162,643; 7,243,110, 7,254,590; 7,281,001; 7,421,458; 7,496,588; 7,523,121; 7,584,422; 7676516; 7,720,842; 7,721,270; and 7,774,791, international Patents and other Patents Pending.

DISCLAIMER: Informatica Corporation provides this documentation "as is" without warranty of any kind, either express or implied, including, but not limited to, the implied warranties of noninfringement, merchantability, or use for a particular purpose. Informatica Corporation does not warrant that this software or documentation is error free. The information provided in this software or documentation may include technical inaccuracies or typographical errors. The information in this software and documentation is subject to change at any time without notice.

NOTICES

This Informatica product (the "Software") includes certain drivers (the "DataDirect Drivers") from DataDirect Technologies, an operating company of Progress Software Corporation ("DataDirect") which are subject to the following terms and conditions:

1. THE DATADIRECT DRIVERS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.

2. IN NO EVENT WILL DATADIRECT OR ITS THIRD PARTY SUPPLIERS BE LIABLE TO THE END-USER CUSTOMER FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR OTHER DAMAGES ARISING OUT OF THE USE OF THE ODBC DRIVERS, WHETHER OR NOT INFORMED OF THE POSSIBILITIES OF DAMAGES IN ADVANCE. THESE LIMITATIONS APPLY TO ALL CAUSES OF ACTION, INCLUDING, WITHOUT LIMITATION, BREACH OF CONTRACT, BREACH OF WARRANTY, NEGLIGENCE, STRICT LIABILITY, MISREPRESENTATION AND OTHER TORTS.


Table of Contents
1. Introduction
2. Ultra Messaging JMS Overview
3. Life Cycle of an Ultra Messaging JMS Application
4. JNDI Administered Objects
5. Ultra Messaging JMS Configuration
6. Asynchronous Message Delivery
7. Message Selectors
8. Session IDs
9. Request/Reply Sample Applications


1. Introduction

The Ultra Messaging® JMS API lets you develop or port Java messaging applications written per the JMS (Java Message Servicea) specification and still utilize much of the flexibility and performance benefits of Ultra Messaging. Ultra Messaging JMS is included with the Ultra Messaging UMQ edition.

This document describes how Ultra Messaging JMS integrates JMS applications with Ultra Messaging, and requires that you have a background in JMS and Ultra Messaging concepts. Please refer to the following:

The following specific issues regarding JMS compliance are not fully supported in the 5.3.6 (or earlier) release of Ultra Messaging JMS.

The following UM features are currently not fully supported in the 5.3.6 (or earlier) release of Ultra Messaging JMS. For information on UM feature support, see Interoperability.

Informatica is aware of the following issues:


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.)

  • TextMessage (0)

  • BytesMessage (1)

  • MapMessage (2)

  • Message (3) (this message type has no body)

  • ObjectMessage (4)

  • StreamMessage (5)


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

  • Persistent - The send method, if using a Destination configured as a UMP-type destination, blocks until the producer receives a Stability Acknowledgement.

  • Non-Persistent - The send method does not block if using a Destination configured as a UMS or UMQ type.

MessageConsumer

  • Consumer - Only receives messages while the application is active.

  • Durable Consumer - Receives all messages for the topic if the MessageConsumer was created with a UMP type destination, including messages sent while the durable consumer application was not running.


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.

  • Message prioritization

  • JMS Application Server Facilities

  • synchronous message consumption/delivery (partial support; see Point-To-Point Model)

  • recover() method (for session recovery)

  • pull model for delivering messages from a queue to a receiver

  • provider-supplied property naming requirement

  • TopicSubscriber NoLocal attribute

  • JMSMessageID passed over the wire from sender to receiver


3. Life Cycle of an Ultra Messaging JMS Application

Using the Ultra Messaging JMS API, you can write end-to-end messaging applications with the programming model shown in Ultra Messaging JMS Programming Architecture. This section discusses the following topics.


3.1. Producer Application

Producer applications take the following actions.

  1. Look-up ConnectionFactory. The Ultra Messaging JMS implementation supports JNDI lookup of a ConnectionFactory.

  2. Create a physical connection. The ConnectionFactory creates the Connection.

  3. Create logical session(s) of a Connection. Sessions are light-weight connections that can multiplex over a single physical Connection. Sessions provide the following.

    1. Concurrent use of the physical Connection across multiple threads (one session per thread) and thus are resource efficient.

    2. Delineation of work between multiple producers.

    3. A factory of producers.

  4. Create a Destination. You can create the destination programmatically or via JNDI lookup. The destination consists of a Topic or Queue name.

  5. Create a producer of a session and provide the destination.

  6. Create Messages. For each Message, set the business data and set the associated routing properties.

  7. Send Messages to the Destination address using the producer.

  8. Close Objects by destroying the Message, Destination(s), producer, session(s), and Connection.

The following simple JMS producer example application demonstrates how to program the above actions.

// Obtain a ConnectionFactory via lookup or direct instantiation
ConnectionFactory factory = (ConnectionFactory)jndiContext.lookup("uJMSConnectionFactory");
 
// Create a connection - assuming no username/password required for UM
Connection connection = factory.createConnection();

// Create a session
Session session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

// Create a topic destination
Destination destination = session.createTopic("TOPIC.1");

// Create a producer
MessageProducer msgProducer = session.createProducer(null);

// create a bytes message
BytesMessage msg = session.createBytesMessage();

byte[] buffer = {1,2,3,4,5};

msg.writeBytes(buffer);

// Publish the message
msgProducer.send(destination, msg);

// close the connection
connection.close();
           

3.2. Consumer Application

Consumer applications normally take the following actions.

  1. Look up ConnectionFactory. The Ultra Messaging JMS implementation supports JNDI lookup of a ConnectionFactory.

  2. Create a physical connection. The ConnectionFactory creates the Connection.

  3. Create logical session(s) of a Connection. Sessions are light-weight connections that can multiplex over a single physical Connection. Sessions provide the following.

    1. Concurrent use of the physical Connection across multiple threads (one session per thread) and thus are resource efficient

    2. Delineation of work between multiple consumers.

    3. A factory of consumers.

  4. Create a Destination. You can create the destination, which consists of a Topic/Queue name, programmatically or via JNDI/UMM lookup. The UMM repository contains a Wildcard designation for a Destination.

  5. Create a consumer of a session, providing the Destination created. If the messages are read asynchronously, register the listener call-back function and exception with the consumer.

  6. Read Messages from the Destination Address. For each destination address (absolute or wildcard), the read could be synchronous, the consumer could register a listener call-back function to asynchronously receive messages, or the consumer could also register a listener call-back exception function to asynchronously receive exceptions, business or technical.

  7. Process messages to access data and properties.

  8. Close Objects by destroying Message; Destination(s), consumer, session(s), Connection.

The following simple JMS consumer example application demonstrates how to program the above actions.

// Obtain a ConnectionFactory via lookup or direct instantiation
 ConnectionFactory factory = (ConnectionFactory)jndiContext.lookup("uJMSConnectionFactory");

// Create a connection - assuming no username/password required for UM
Connection connection = factory.createConnection();

// Create a session
Session session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

// Create a topic destination
Destination destination = session.createTopic("TOPIC.1");

// create the consumer 
MessageConsumer msgConsumer = session.createConsumer(destination);

// start the connection 
connection.start();

// read messages 
while(true)
{
    // receive the message 
        msg = msgConsumer.receive();
    if (msg == null)
        break;
}

// close the connection 
connection.close();
           

4. JNDI Administered Objects

JMS administered objects encapsulate specific behavior so you can write producer and consumer applications without the use of specific constructions. Your applications can use JNDI to look up LBMConnectionFactory and Destination objects. The LBMConnectionFactory encapsulates all of the UM configuration properties for the selected JNDI object and also creates and initializes the UM Context.


4.1. Look Up Administered Objects Using JNDI

The code below shows the typical steps to create an initial context and look up a ConnectionFactory and a Destination using JNDI. The JNDI repository used depends on the values used for providerContextFactory and providerUrl and would typically need to specify a userName and password.

// Import of Sun's JMS interface
import javax.jms.*;

// Imports for JNDI
import javax.naming.*;
import javax.naming.directory.*;

// Create the Context
InitialContext jndiContext = new InitialContext();
// Lookup the objects
ConnectionFactory cf = (ConnectionFactory)jndiContext.lookup("uJMSConnectionFactory");
Destination d = (Destination)jndiContext.lookup("TOPIC1");
           

5. Ultra Messaging JMS Configuration

You configure options/attributes for Ultra Messaging JMS object creation in one of three general ways:

This section discusses the following topics:


5.1. jndi.properties

The /jmsclient/bin/jndi.properties governs from where your JMS applications receive their configuration data. Regardless of which of the three configuration methods you decide to use, you must edit or ensure that this file matches the selected method. The jndi.properties, in its default form, appears below. Note that the file specifies the third configuration method (JMSConfig XML file).

## Use the LBM XML based context factory
#java.naming.factory.initial = com.latencybusters.jms.LBMXmlContextFactory
## where the xml config file is one of
#java.naming.provider.url = classpath:umjms.xml
#java.naming.provider.url = file:C:/umjms.xml
#java.naming.provider.url = file:/home/user1/umjms.xml
 
## Use the UMM based context factory
#java.naming.factory.initial = com.latencybusters.jms.UMMContextFactory
## where the ummd is running at the following url
#java.naming.provider.url = localhost:15701
#java.naming.security.principal = JMSUser
#java.naming.security.credentials = JMSUser
 
## Use Sun's RefFSContextFactory (with .bindings file)
java.naming.factory.initial = com.sun.jndi.fscontext.RefFSContextFactory
## where the .bindings file is
java.naming.provider.url = file:.
   

The next three sections describe how to edit the appropriate sections of this file.


5.2. Configuring Ultra Messaging JMS with a UM XML File

You can create an XML configuration file using an XML editor or by using the UMM GUI. See Using the UMM GUI for details. With this method, the UMM Daemon doesn't have to be running when your Ultra Messaging JMS applications start.

To use this configuration method, edit the jndi.properties file as follows:

  1. Make sure that all lines in the second and third section are commented out.

  2. Un-comment the line, java.naming.factory.initial = com.latencybusters.jms.LBMXmlContextFactory

  3. Un-comment one of the java.naming.provider.url lines and supply the path and filename of your XML configuration file. See also Configuring Ultra Messaging JMS with Ultra Messaging Manager.

  4. Save the jndi.properties file.

The UM XML configuration file has the following high-level structure.

<?xml version="1.0" encoding="UTF-8"?>
<um-configuration version="1.0">
 
<applications>
 <application name="uJMS">
 
  <contexts>
    <context name="uJMSConnectionFactory" template="">
      <sources/>
      <receivers/>
      <wildcard-receivers/>
      <options type="context"> 
    </context>
    <context name="uJMSConnectionFactory-UMS">
      <sources/>
       <receivers/>
       <wildcard-receivers/>
    </context>
    <context name="uJMSConnectionFactory-UMP">
      <sources/>
      <receivers/>
      <wildcard-receivers/>
    </context>
    <context name="uJMSConnectionFactory-UMQ">
      <sources/>
      <receivers/>
      <wildcard-receivers/>
    </context>
  </contexts>
 
  <event-queues>
    <event-queue/>
  </event-queues>
 
  <application-data>
    <ConnectionFactory name="uJMSConnectionFactory">
      <options type="ConnectionFactory">
      </options>
    </ConnectionFactory>
    <Destination name="TempQueue">
      <options type="Destination">
      </options>
    </Destination>
  </application-data>
 
 </application>
</applications>
</um-configuration>
   

Essentially, the structure has two parts. The first part contains the contexts that allow you to specify traditional UM configuration option values. The second part, <application-data>, allows you to specify JMS options to factories and destinations. The following details some of the major sections of the above high-level structure.

  • <context name="uJMSConnectionFactory" template=""> - Accepts general UM configuration option values for the contexts, sources, and receivers used by your applications.

  • <context name="uJMSConnectionFactory-UMS"> - Accepts option values specific to any Streaming activities of your applications.

  • <context name="uJMSConnectionFactory-UMP"> - Accepts option values specific to Persistent activities, such as store configuration options.

  • <context name="uJMSConnectionFactory-UMQ"> - Accepts option values specific to Queueing activities, such as queue configuration options.

  • <ConnectionFactory name="uJMSConnectionFactory"> - Accepts JMS Factory option values such as default_message_type or default_topic_type.

  • <Destination name="TempQueue"> - Accepts JMS destination option values such as type or dest_type .

To see a more complete XML file, see /jmsclient/config/umjms.xml. Unlike the high-level structure above, this file contains relevant option values. You can also review the same information in the UMM GUI. The XML file you create must adhere to the high-level structure presented above.


5.3. Configuring Ultra Messaging JMS with Ultra Messaging Manager

You can use the UMM GUI to create configurations for your JMS applications. With this method, the UMM Daemon must be running to provide server configuration and license information to your JMS applications when they start. To use this method, edit the jndi.properties file as follows:

  1. Make sure that all lines in the first and third section are commented out.

  2. Un-comment the line, java.naming.factory.initial = com.latencybusters.jms.UMMContextFactory

  3. Un-comment java.naming.provider.url and substitute an IP address and port number for localhost:15701 to specify where the UMM Daemon runs. You can add a comma-separated list of daemons.

  4. Save the jndi.properties file.


5.4. Configuring Ultra Messaging JMS with a JMSConfig XML File

Note: This is a legacy feature and no longer recommended.

With this method, you use the /jmsclient/bin/config.bat or /jmsclient/bin/config.sh script to create a .bindings file from your config.xml. To use this method, edit the jndi.properties file as follows:

  1. Make sure that all lines in the first and second section are commented out.

  2. Un-comment the line, java.naming.factory.initial = com.sun.jndi.fscontext.RefFSContextFactory

  3. Un-comment java.naming.provider.url = file:..

  4. Save the jndi.properties file.



The JMSConfig.xml file allows you to assign UM configuration values to the Ultra Messaging JMS ConnectionFactory and specify message topics as destinations. You can create a JMSConfig format XML configuration file using an XML editor or text editor. See /jmsclient/config/config.xml for an example of a JMSConfig file. This is the configuration file for the UM JMS examples described in Ultra Messaging JMS Quick Start.

The configuration file has the following high-level structure.

<JMSConfig>
    <ConnectionFactories>
        <ConnectionFactory>
            <FactoryAttributes>
                <Attribute/>
            </FactoryAttributes>
            <ContextAttributes>
                <Attribute "UM configuration options, scope=context" />
            </ContextAttributes>
            <SourcetAttributes>
                <Attribute "UM configuration options, scope=source" />
            </SourcetAttributes>
            <ReceiverAttributes>
                <Attribute "UM configuration options, scope=receiver" />
            </ReceiverAttributes>
            <WildcardRceiverAttributes>
                <Attribute "UM configuration options, scope=wildcard-receiver" />
            </WildcardReceiverAttributes>
        </ConnectionFactory>
    </ConnectionFactories>
    <Destinations>
        <Destination>
            <DestinationAttributes>
                <Attribute/>
            </DestinationAttributes>
            <ReceiverAttributes>
                <Attribute/>
            </RecieverAttributes>
        </Destination>
    </Destinations>
</JMSConfig>
       

This section discusses the following topics.


5.4.1. ConnectionFactory Attributes

You can configure as many ConnectionFactories as needed. The ConnectionFactory element contains the following sets of attributes.


5.4.1.1. FactoryAttributes

See Ultra Messaging JMS Options for ConnectionFactory options.

The following is an example ConnectionFactory configuration that uses all the default values.

<ConnectionFactories>
    <ConnectionFactory>
        <FactoryAttributes>
            <Attribute name="CLIENT_ID" value="UME1"/>
            <Attribute name="DEBUG" value="false"/> 
            <Attribute name="DEFAULT_TOPIC_TYPE" value="UME"/>
            <Attribute name="DEFAULT_TEMP_TOPIC_TYPE" value="LBM"/>
            <Attribute name="USE_APP_HEADER" value="true"/>
            <Attribute name="DEFAULT_MESSAGE_TYPE" value="TextMessage"/>
        </FactoryAttributes>
    </ConnectionFactory>
</ConnectionFactories>
       

Note: The following message methods will not work if set USE_APP_HEADER to false. (<Attribute name="USE_APP_HEADER" value="false"/>).

  • getJMSCorrelationID/setJMSCorrelationID

  • getJMSDeliveryMode/setJMSDeliveryMode

  • getJMSDestination/setJMSDestination

  • getJMSExpiration/setJMSExpiration

  • getJMSMessageID/setJMSMessageID

  • getJMSPriority/setJMSPriority


5.4.1.2. ContextAttributes

A ConnectionFactory's Context Attributes consist of any UM Configuration Options with the scope of Context. See the Ultra Messaging Configuration Guide for all configuration options. The following are examples of ContextAttributes.

<ContextAttributes>
    <Attribute name="operational_mode" value="sequential"/>
    <Attribute name="resolver_multicast_ttl" value="16"/>
    <Attribute name="resolver_multicast_address" value="225.72.39.173"/>
    <Attribute name="mim_address" value="225.72.39.174"/>
    <Attribute name="transport_lbtrm_multicast_address_low" value="225.73.39.200"/>
    <Attribute name="transport_lbtrm_multicast_address_high" value="225.73.39.210"/>
    <Attribute name="request_tcp_port_low" value="16000"/>
    <Attribute name="request_tcp_port_high" value="16010"/>
    <Attribute name="transport_lbtrm_source_port_low" value="15000"/>
    <Attribute name="transport_lbtrm_source_port_high" value="15500"/>
    <Attribute name="transport_tcp_maximum_ports" value="20"/>
    <Attribute name="transport_tcp_port_low" value="16500"/>
    <Attribute name="transport_tcp_port_high" value="16600"/>
    <Attribute name="resolver_unicast_port_high" value="45000"/>
    <Attribute name="transport_lbtrm_data_rate_limit" value="500000000"/>
    <Attribute name="transport_lbtrm_retransmit_rate_limit" value="1000000"/>
    <Attribute name="transport_lbtrm_receiver_socket_buffer" value="8000000"/>
    <Attribute name="request_tcp_reuseaddr" value="1"/>
</ContextAttributes>
               

5.4.1.3. SourceAttributes

A ConnectionFactory's Source Attributes consist of any UM Configuration Options with the scope of Source. See the Ultra Messaging Configuration Guide for all configuration options. The following are examples of SourceAttributes.

<SourceAttributes>
    <Attribute name="transport" value="lbtrm"/>
    <Attribute name="late_join" value="1"/>
    <Attribute name="ume_store_name" value="JMSStore1"/>
    <Attribute name="ume_store_name" value="JMSStore2"/>
    <Attribute name="ume_store_name" value="JMSStore3"/>
    <Attribute name="ume_store_behavior" value="qc"/>
    <Attribute name="ume_proxy_source" value="1"/>
    <Attribute name="umq_queue_name" value="JMSQueue"/>
    <Attribute name="implicit_batching_minimum_length" value="1"/>
</SourceAttributes>
               

Note: You can define and add stores to a source's store list by using either the ume_store or ume_store_name attribute. We suggest the latter (which uses a name instead of an IP/port address), as this facilitates JMS deployment to different machines and/or the UM Gateway.


5.4.1.4. ReceiverAttibutes

A ConnectionFactory's Receiver Attributes consist of any UM Configuration Options with the scope of Receiver. See the Ultra Messaging Configuration Guide for all configuration options. The following are examples of Receiver Attributes.

<ReceiverAttributes>
    <Attribute name="umq_receiver_type_id" value="100"/>
</ReceiverAttributes>
               

5.4.2. Destination Attributes

Destinations correspond to Ultra Messaging topics. See Ultra Messaging JMS Options for destinations options.

The following is an example destination configuration.

<Destination name="ReplyTopic" type="Topic">
    <DestinationAttributes>
            <Attribute name="REGID" value="4400"/>
        <Attribute name="WILDCARD" value="false"/>
        <Attribute name="TYPE" value="LBM"/>
    </DestinationAttributes>
</Destination>
                   

6. Asynchronous Message Delivery

You can program asynchronous message delivery using the MessageListener class. The application registers a callback handler to receive messages asynchronously.

// Obtain a ConnectionFactory via lookup or direct instantiation
ConnectionFactory factory = (ConnectionFactory)jndiContext.lookup("uJMSConnectionFactory");

// Create a connection - assuming no username/password required for UM
Connection connection = factory.createConnection();

// Create a Session
Session session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

// set the exception listener callback
connection.setExceptionListener(this);

// Create a topic destination
Destination destination = session.createTopic("TOPIC.1");

// create the consumer 
MessageConsumer msgConsumer = session.createConsumer(destination);

// set the message listener callback
msgConsumer.setMessageListener(this);

// start the connection 
connection.start();

// The exception listener
public void onException(JMSException e)
{
    // print the connection exception status 
        System.err.println("Exception occurred: "+ e.getMessage());
}

// The message listener callback
public void onMessage(Message msg)
{
    try
    {
        System.err.println("Received message: " + msg);
    }
    catch(Exception e)
    {
            System.err.println("Exception occurred: "+ e.getMessage());
                System.exit(-1);
        }
}
       

7. Message Selectors

This section discusses the following topics.

Message Selection provides a way to filter messages at the consumer side utilizing message properties. A message selector is an SQL92-compliant expression that guides a consumer to reject the message if it is not a match.

At the time of consumer creation, an application passes the message selector string to JMS. As messages arrive, the consumer compares their header and properties information to the message selector and rejects messages that evaluate false. For example, a message selector "MyProp > 5" allows consumers to receive messages whose JMS message header field MyProp value is greater than 5.


7.1. Publish/Subscribe

In the publish/subscribe scenario, you can have many consumers subscribed to the same topic, but use message selectors to filter out selected consumers, and hence, selected receiving clients and applications. In this scenario, each consumer decides whether or not to discard the message.

Figure 8. Message selectors, publish/subscribe

For example, to create a topic subscriber with a message selector for consuming messages with one property greater than 5 and another property equal to 3:

// Create a selector to receive only messages with MyProp1 greater than 5 and MyProp2 equal to 3.
String selector = "MyProp1 > 5 AND MyProp2 = 3";

// Create a topic subscriber using the selector.
TopicSubscriber topicSubscriber = topicSession.createSubscriber(queue, selector);
   

7.2. Point-To-Point

In the point-to-point scenario, you can employ message selectors at the queue to determine which of multiple consumers to send messages to. To ensure once-and-only-once delivery, the queue typically ensures that only the consumer assigned per message selector consumes a given message.

Figure 9. Message selectors, point-to-point

For example, to create a queue receiver with a message selector for consuming messages with one property greater than 5 and another property equal to 3:

// Create a selector to receive only text messages with MyProp greater than 5.
String selector = "MyProp1 > 5 AND MyProp2 = 3";

// Create a queue receiver using the selector.
QueueReceiver queueReceiver = queueSession.createReceiver(queue, selector);
   

If a consumer is not available for a particular filtered message, the queue skips and retains this message, and then continues processing subsequent messages.

When you configure a queuing application to use application sets, the message selectors can target individual consumers in an application set. Application sets essentially split consumers into logical queues so that the desired once-and-only-once message delivery behavior applies to all consumers inside them. A consumer in one application set can receive the same message as a consumer in another. Message selectors in different application sets let the queue assign messages to selected consumers within the same application set.


7.3. Native Applications

You can use message selectors at the native provider level (i.e., UM sources or receivers written in C, Java, or .NET). Message selectors can work in the native application scenarios listed below.

JMS Producer to UM Receiver - Set option message_selector to the desired message selector string when creating the consumer. This string must follow SQL92 syntax as described in the JMS Specification, for example "MyProp1 = 6 AND MyProp2 < 7". See also Ultra Messaging JMS Options.

UM Source to JMS Consumer - Set message properties so that the name matches that used by the JMS consumer's message selector.

UM Source to UM Receiver - You can use the message selector feature outside of the JMS environment by setting message properties at the UM source, and the message_selector option at the UM receiver.

Note: For a UM receiver, used with UMP, and with an event queue or if retaining/promoting messages outside of the receiver callback function, we recommended you enable either explicit ACK'ing (ume_explicit_ack_only), or ACK batching (ume_use_ack_batching). This prevents undesired/unwarranted ACKs for messages still waiting to be processed.


8. Session IDs

This section discusses the following topics.

When using UMP stores or UMQ queues, UM objects such as sources, receivers, and/or contexts must register with the stores or queues, at which time they acquire registration IDs. You can use Session IDs to manage these registration IDs.


8.1. UMP Session IDs

A UMP Session ID allows stores to identify an application's sources and receivers by automatically assigning them registration IDs. With session IDs, you do not need to directly assign registration IDs. You assign a UMP session ID by first setting option use_ump_session_ids to True, then assigning the session ID with the setClientID() method, or by setting the client_id option. Note that with this option enabled, UM ignores attempts to maintain registration IDs directly.

When using this option, we recommend that you call the setClientID() function after creating a Connection rather than setting the client_id option, to ensure that each created connection has a unique client identifier .

For more information about UMP registration IDs and session IDs, see Registration Identifiers, and more specifically, Managing RegIDs with Session IDs.


8.2. UMQ Session IDs

You can use UMQ Session IDs to manage context registration IDs and receiver assignment IDs. For expanded information on UMQ Session IDs, see Queue Session IDs.

In configurations where a queue must always send messages, in order, to a specific assigned receiver, use UMQ Session IDs, as described in the next paragraphs. This ensures that if a receiver fails, the queue retains messages for that receiver until it recovers.

To configure this scenario, perform the following steps:

  1. Set option message-reassignment-timeout (see Options for a Topic's ume-attributes Element) for the queue to a value of 0.

  2. Set option umq_session_id to a unique value. Do not replicate this value elsewhere, even for sending applications.


9. Request/Reply Sample Applications

The following example applications demonstrate the request/reply model.


9.1. Request Sample Application

// Obtain a ConnectionFactory via lookup or direct instantiation
ConnectionFactory factory = (ConnectionFactory)jndiContext.lookup("uJMSConnectionFactory");


// Create a connection - assuming no username/password required for UM
Connection connection = factory.createConnection();

// Create a Session
Session session = connection.createSession(false,
                              javax.jms.Session.AUTO_ACKNOWLEDGE);
// Create request and reply destinations
Destination requestTopic = lookupDestination(requestTopicName);
Destination replyTopic = lookupDestination(replyTopicName);
        
MessageProducer requestProducer = session.createProducer(requestTopic);
MessageConsumer replyConsumer = session.createConsumer(replyTopic);

TextMessage requestMessage = session.createTextMessage();
requestMessage.setText("Hello world.");
requestMessage.setJMSReplyTo(replyTopic);
requestProducer.send(requestMessage);

// start the connection 
connection.start();

// Wait for the reply
Message replyMessage = replyConsumer.receive();

// Could check correlationID, not really necessary with sync request reply
if (replyMessage.getJMSCorrelationID() != requestMessage.getJMSMessageID())
{
    System.err.println("Unexpected reply message"+ e.getMessage());
}
           

9.2. Reply Sample Application

// Obtain a ConnectionFactory via lookup or direct instantiation
ConnectionFactory factory = (ConnectionFactory)jndiContext.lookup("uJMSConnectionFactory");


// Create a connection - assuming no username/password required for UM
Connection connection = factory.createConnection();

// Create a Session
Session session = connection.createSession(false,
                              javax.jms.Session.AUTO_ACKNOWLEDGE);
// Create request destination
Destination requestTopic = lookupDestination(requestTopicName);

// Create consumer on request topic     
MessageConsumer requestConsumer = session.createConsumer(requestTopic);

// Create a producer, don't know reply destination at this point.
MessageProducer replyProducer = session.createProducer(null);


// set the message listener callback
msgConsumer.setMessageListener(this);

// start the connection 
connection.start();


// The message listener callback
public void onMessage(Message message)
{
    try
    {
        TextMessage requestMessage = (TextMessage) message;
        String contents = requestMessage.getText();

        // get the reply to destination
        Destination replyDestination = requestMessage.getJMSReplyTo();

        TextMessage replyMessage = session.createTextMessage();
        replyMessage.setText(contents);
        
        replyMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
        replyProducer.send(replyDestination, replyMessage);
    }
    catch(Exception e)
    {
            System.err.println("Exception occurred: "+ e.getMessage());
                System.exit(-1);
        }
}
           

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