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.QueueConnectionFactorythat is used to establish the connection to the messaging broker. -
QueueFactory - A class that allows an application to obtain
javax.jms.Queueinstance 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, thecreateQueueConnection()method attempts an unauthenticated connection. - See the API reference for
zero.messaging.externalclientfor 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 thencreateQueueConnection()attempts an unauthenticated connection. However, thecreateQueueConnection(String username, String password)method always attempts an authenticated connection using the supplied user ID and password. - See the API reference for
zero.messaging.externalclientfor 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
storeAndForwardand 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
brokerNameparameter must match the name of the remote broker as specified in the configuration of the local broker. - The
remoteQueueNameparameter must not begin with the charactersstoreAndForwardand 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()orcreateStoreAndForwardQueuedoes not directly create an active queue in a messaging broker. These methods create ajavax.jms.Queueinstance 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 thejavax.jms.Queueinstance, the active queue will be automatically created. - See the API reference for
zero.messaging.externalclientfor 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:
- An instance of the
WrappedQueueConnectionFactoryclass is created for the specified broker name, host name and port. - Before the connection factory is used to create a connection,
the
setMaxPoolSize()method is used to disable connection pooling by setting the pool size to0. The sample application uses a single connection and would not benefit from connection pooling. Disabling connection pooling means that theclose()of an allocated connection immediately disconnects the connection to the messaging broker. - The
QueueFactoryclass is used to create an instance ofjavax.jms.Queuerepresenting the named queue. - The connection factory is used to create an instance of
javax.jms.QueueConnectionrepresenting a connection to the messaging broker. - The
javax.jms.*interfaces are used to establish a session and a message producer, to send a message, and to commit the session. - The
close()methods of message producer, session and connection objects are called infinallyclauses 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.