Using the messaging API

This topic describes how to use the messaging external client APIs to connect to a messaging broker and send and receive messages.

Overview

The messaging external client provides two classes necessary to connect a JMS client application to a messaging broker:

WrappedQueueConnectionFactory
An implementation of javax.jms.QueueConnectionFactory that is used to establish the connection to the messaging broker.
QueueFactory
A class that allows an application to obtain javax.jms.Queue instance for a queue residing in the messaging broker.

See the API reference for zero.messaging.externalclient for more information about these classes.

After using these classes to get references to the messaging resources, the application can use the methods of the javax.jms.QueueConnectionFactory and javax.jms.Queue interfaces to send and receive messages.

The WrappedQueueConnectionFactory class

The WrappedQueueConnectionFactory class is used to establish a connection to the messaging broker. The application must first construct an instance of the factory class and supply the required connection properties, using one of the following constructors:

  • WrappedQueueConnectionFactory(String brokerName, String brokerHostName, int portNumber)
  • WrappedQueueConnectionFactory(String brokerName, String brokerHostName, int portNumber, String userid, String password)
  • If a user ID and password is supplied to the connection factory constructor, the values are used to attempt to establish an authenticated connection when the createQueueConnection() method is invoked. If the user ID and password is not supplied to the connection factory constructor, the createQueueConnection() method attempts an unauthenticated connection.
  • See the API reference for zero.messaging.externalclient for more information about these methods.

Controlling connection pooling

The WrappedQueueConnectionFactory class maintains a pool of javax.jms.Connection instances created using the connection factory. When the close() method of a connection is invoked, the connection can be returned to the pool and be reallocated to the application when it subsequently requests a similar connection.

The pooling behavior can be controlled using the following methods:

  • void setMaxPoolSize(int size)
  • int getMaxPoolSize()

Set the pool size to 0 to disable connection pooling. Set the pool size to a negative value to specify an unlimited pool size. The default pool size is 10.

Setting the delivery timeout

The delivery timeout for a connection defines the length of time that the client should wait for the broker to acknowledge requests, in milliseconds. If acknowledgments are not received within this time interval, the application receives an exception. The delivery timeout for the connections can be configured using the following methods:

  • void setDeliveryTimeout(int milliseconds)
  • int getDeliveryTimeout()

Connecting to secure broker instances

The following methods are used to configure connections to secured messaging brokers:

  • void setTrustStore(String trustStore)
  • void setTrustStorePassword(String password)
  • void setTrustStoreType(String trustStoreType)

The following example outlines the calls required to set up a WrappedQueueConnectionFactory for use with a secured messaging broker:

// Calls to qcf.createConnection() will use "user" and "password" by default
WrappedQueueConnectionFactory qcf =
    new WrappedQueueConnectionFactory("brokerName", "hostName", port, "user", "password");

qcf.setTrustStore("keystore.jks");
qcf.setTrustStorePassword("trustStorePassword");
qcf.setTrustStoreType("JKS");

The setAlgorithm(String algorithm) of the WrappedQueueConnectionFactory class can be used to select the trust manager algorithm to be used. By default, the external client connection factory automatically selects IbmX509 when using an IBM® Java™ runtime, or SunX509 otherwise.

Creating connections

The application can obtain a connection from the connection factory using one of the following methods:

  • QueueConnection createQueueConnection()
  • QueueConnection createQueueConnection(String username, String password)
  • If a user ID and password was supplied to the connection factory constructor then createQueueConnection() attempts to establish an authenticated connection. If a user ID and password was not supplied to the connection factory constructor then createQueueConnection() attempts an unauthenticated connection. However, the createQueueConnection(String username, String password) method always attempts an authenticated connection using the supplied user ID and password.
  • See the API reference for zero.messaging.externalclient for more information about these methods.

Closing connections

The application should call the close() method of allocated connections when they are no longer required.

If connection pooling is disabled then the connection to the messaging broker is disconnected when the connection close() method is called. However if connection pooling is enabled then the connection to the messaging broker can remain open until it is finally removed from the pool.

To finally close any remaining pooled connections associated with a connection factory, the application should call the close() method of the WrappedQueueConnectionFactory instance. If this method is not called, connections to the messaging broker might remain open and the associated threads might prevent the application runtime from terminating.

The QueueFactory class

The QueueFactory class provides methods to create javax.jms.Queue instances for queues in the messaging broker:

  • static Queue createQueue(String queueName)
  • static Queue createStoreAndForwardQueue(String brokerName, String remoteQueueName)

The javax.jms.Queue instance returned by createQueue() can be used to send messages to, or receive messages from, a queue in the local messaging broker. The value of the queueName parameter must be one of the following:

  • The name of a queue in the local messaging broker. The local queue name must not begin with the characters storeAndForward and must not contain more than 79 characters.
  • The local store-and-forward name for a queue in a remote messaging broker. See Considerations for store-and-forward scenarios for more information about store-and-forward queue names.

The javax.jms.Queue instance returned by createStoreAndForwardQueue() can be used to send messages to a store-and-forward queue in the local messaging broker. These messages will then be forwarded to the target queue in the remote messaging broker using store-and-forward processing. The values of the parameters must be the following:

  • The brokerName parameter must match the name of the remote broker as specified in the configuration of the local broker.
  • The remoteQueueName parameter must not begin with the characters storeAndForward and must not contain more than 79 characters.

See Considerations for store-and-forward scenarios for more information about store-and-forward processing.

  • Invoking either createQueue() or createStoreAndForwardQueue does not directly create an active queue in a messaging broker. These methods create a javax.jms.Queue instance which can be used to send or receive messages from a queue in the local messaging broker. However, if the named queue does not exist in the messaging broker when the application attempts to access it using the javax.jms.Queue instance, the active queue will be automatically created.
  • See the API reference for zero.messaging.externalclient for more information about these methods.

Simple example

The following sample stand-alone application uses the messaging external client to send a message to an unsecured messaging broker:

package sample;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.Session;

import zero.messaging.externalclient.wrapper.QueueFactory;
import zero.messaging.externalclient.wrapper.WrappedQueueConnectionFactory;

public class SendMessage {

    public static void main(String args[]) {
        if (args.length < 5) {
            System.out.println("Usage: SendMessage brokerName hostName port queueName messageText");
        } else {
            try {
                sendMessage(args[0], args[1], Integer.parseInt(args[2]), args[3], args[4]);
                System.out.println("SendMessage: Successful");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("SendMessage: Failed");
            }
        }
    }
    
    public static void sendMessage(String brokerName, String hostName, int port, String queueName, String messageText) throws JMSException {
        WrappedQueueConnectionFactory connectionFactory = new WrappedQueueConnectionFactory(brokerName, hostName, port);
        connectionFactory.setMaxPoolSize(0); // Not using connection pooling in this sample
        Queue queue = QueueFactory.createQueue(queueName);
        System.out.println("SendMessage: Connection for " + brokerName);
        QueueConnection conn = connectionFactory.createQueueConnection();
        try {
            System.out.println("SendMessage: Establishing session");
            Session session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
            try {
                System.out.println("SendMessage: Creating message producer");
                MessageProducer producer = session.createProducer(queue);
                try {
                    System.out.println("SendMessage: Sending message");
                    Message message = session.createTextMessage(messageText);
                    producer.send(message);
                } finally {
                    producer.close();
                }
                System.out.println("SendMessage: Committing session");
                session.commit();
            } finally {
                session.close();
            }
        } finally {
            conn.close();
        }
    }
    
}

The messaging code is contained in the sendMessage() method:

  1. An instance of the WrappedQueueConnectionFactory class is created for the specified broker name, host name and port.
  2. Before the connection factory is used to create a connection, the setMaxPoolSize() method is used to disable connection pooling by setting the pool size to 0. The sample application uses a single connection and would not benefit from connection pooling. Disabling connection pooling means that the close() of an allocated connection immediately disconnects the connection to the messaging broker.
  3. The QueueFactory class is used to create an instance of javax.jms.Queue representing the named queue.
  4. The connection factory is used to create an instance of javax.jms.QueueConnection representing a connection to the messaging broker.
  5. The javax.jms.* interfaces are used to establish a session and a message producer, to send a message, and to commit the session.
  6. The close() methods of message producer, session and connection objects are called in finally clauses to ensure that the messaging resources are deallocated.

To use this sample application, ensure that the messaging external client JARs are on the application's class path. See Preparing to use the messaging external client for more information.

Version 1.1.31300