Examples of ASF use

 


There is a set of classes, with their source, in the directory <install_dir>/samples/jms/asf (where <install_dir> is the installation directory for WebSphere MQ JMS). These classes use the WebSphere MQ JMS appserver facilities that are described in ASF classes and functions, within the sample standalone application server environment that is described in Application server sample code.

These samples provide examples of ASF use from the perspective of a client application:

  • A simple point-to-point example uses:

    • ASFClient1.java

    • Load1.java

    • CountingMessageListenerFactory.java

  • A more complex point-to-point example uses:

    • ASFClient2.java

    • Load2.java

    • CountingMessageListenerFactory.java

    • LoggingMessageListenerFactory.java

  • A simple publish/subscribe example uses:

    • ASFClient3.java

    • TopicLoad.java

    • CountingMessageListenerFactory.java

  • A more complex publish/subscribe example uses:

    • ASFClient4.java

    • TopicLoad.java

    • CountingMessageListenerFactory.java

    • LoggingMessageListenerFactory.java

  • A publish/subscribe example using a durable ConnectionConsumer uses:

    • ASFClient5.java

    • TopicLoad.java

The following sections describe each class in turn.

 

Load1.java

This class is a generic JMS application that loads a given queue with a number of messages, then terminates. It can either retrieve the required administered objects from a JNDI namespace, or create them explicitly, using the WebSphere MQ JMS classes that implement these interfaces. The administered objects that are required are a QueueConnectionFactory and a queue. You can use the command line options to set the number of messages with which to load the queue, and the sleep time between individual message puts.

This application has two versions of the command line syntax.

For use with JNDI, the syntax is:

java Load1 [-icf jndiICF] [-url jndiURL] [-qcfLookup qcfLookup]
           [-qLookup qLookup] [-sleep sleepTime] [-msgs numMsgs]

For use without JNDI, the syntax is:

java Load1 -nojndi [-qmgr qMgrName] [-q qName]
                   [-sleep sleepTime] [-msgs numMsgs]

Table 29 describes the parameters and gives their defaults.

Table 29. Load1 parameters and defaults

Parameter Meaning Default
jndiICF Initial context factory class used for JNDI com.sun.jndi.ldap.LdapCtxFactory
jndiURL Provider URL used for JNDI ldap://localhost/o=ibm,c=us
qcfLookup JNDI lookup key used for QueueConnectionFactory cn=qcf
qLookup JNDI lookup key used for Queue cn=q
qMgrName Name of queue manager to connect to "" (use the default queue manager)
qName Name of queue to load SYSTEM.DEFAULT.LOCAL.QUEUE
sleepTime Time (in milliseconds) to pause between message puts 0 (no pause)
numMsgs Number of messages to put 1000

If there are any errors, an error message is displayed and the application terminates.

You can use this application to simulate message load on a WebSphere MQ queue. In turn, this message load can trigger the ASF-enabled applications described in the following sections. The messages put to the queue are simple JMS TextMessage objects. These objects do not contain user-defined message properties, which could be useful to make use of different message listeners. The source code is supplied so that you can modify this load application if necessary.

 

CountingMessageListenerFactory.java

This file contains definitions for two classes:

  • CountingMessageListener

  • CountingMessageListenerFactory

CountingMessageListener is a very simple implementation of the javax.jms.MessageListener interface. It keeps a record of the number of times its onMessage method has been invoked, but does nothing with the messages it is passed.

CountingMessageListenerFactory is the factory class for CountingMessageListener. It is an implementation of the MessageListenerFactory interface described in MessageListenerFactory.java. This factory keeps a record of all the message listeners that it produces. It also includes a method, printStats(), which displays usage statistics for each of these listeners.

 

ASFClient1.java

This application acts as a client of the WebSphere MQ JMS ASF. It sets up a single ConnectionConsumer to consume the messages in a single WebSphere MQ queue. It displays throughput statistics for each message listener that is used, and terminates after one minute.

The application can either retrieve the required administered objects from a JNDI namespace, or create them explicitly, using the WebSphere MQ JMS classes that implement these interfaces. The administered objects that are required are a QueueConnectionFactory and a queue.

This application has two versions of the command line syntax:

For use with JNDI, the syntax is:

java ASFClient1 [-icf jndiICF] [-url jndiURL] [-qcfLookup qcfLookup]
                [-qLookup qLookup] [-poolSize poolSize] [-batchSize batchSize]

For use without JNDI, the syntax is:

java ASFClient1 -nojndi [-qmgr qMgrName] [-q qName]
                        [-poolSize poolSize] [-batchSize batchSize]

Table 30 describes the parameters and gives their defaults.

Table 30. ASFClient1 parameters and defaults

Parameter Meaning Default
jndiICF Initial context factory class used for JNDI com.sun.jndi.ldap.LdapCtxFactory
jndiURL Provider URL used for JNDI ldap://localhost/o=ibm,c=us
qcfLookup JNDI lookup key used for QueueConnectionFactory cn=qcf
qLookup JNDI lookup key used for Queue cn=q
qMgrName Name of queue manager to connect to "" (use the default queue manager)
qName Name of queue to consume from SYSTEM.DEFAULT.LOCAL.QUEUE
poolSize The number of ServerSessions created in the ServerSessionPool being used 5
batchSize The maximum number of message that can be assigned to a ServerSession at a time 10

The application obtains a QueueConnection from the QueueConnectionFactory.

A ServerSessionPool, in the form of a MyServerSessionPool, is constructed using:

  • The QueueConnection that was created previously

  • The required poolSize

  • An acknowledge mode, AUTO_ACKNOWLEDGE

  • An instance of a CountingMessageListenerFactory, as described in CountingMessageListenerFactory.java

The connection's createConnectionConsumer method is invoked, passing in:

  • The queue that was obtained earlier

  • A null message selector (indicating that all messages should be accepted)

  • The ServerSessionPool that was just created

  • The batchSize that is required

The consumption of messages is then started by invoking the connection's start() method.

The client application displays throughput statistics for each message listener that is used, displaying statistics every 10 seconds. After one minute, the connection is closed, the server session pool is stopped, and the application terminates.

 

Load2.java

This class is a JMS application that loads a given queue with a number of messages, then terminates, in a similar way to Load1.java. The command line syntax is also similar to that for Load1.java (substitute Load2 for Load1 in the syntax). For details, see Load1.java.

The difference is that each message contains a user property called value, which takes a randomly selected integer value between 0 and 100. This property means that you can apply message selectors to the messages. Consequently, the messages can be shared between the two consumers that are created in the client application described in ASFClient2.java.

 

LoggingMessageListenerFactory.java

This file contains definitions for two classes:

  • LoggingMessageListener

  • LoggingMessageListenerFactory

LoggingMessageListener is an implementation of the javax.jms.MessageListener interface. It takes the messages that are passed to it and writes an entry to the log file. The default log file is ./ASFClient2.log. You can inspect this file and check the messages that are sent to the connection consumer that is using this message listener.

LoggingMessageListenerFactory is the factory class for LoggingMessageListener. It is an implementation of the MessageListenerFactory interface described in MessageListenerFactory.java.

 

ASFClient2.java

ASFClient2.java is a slightly more complicated client application than ASFClient1.java. It creates two ConnectionConsumers that feed off the same queue, but that apply different message selectors. The application uses a CountingMessageListenerFactory for one consumer, and a LoggingMessageListenerFactory for the other. Use of two different message listener factories means that each consumer must have its own server session pool.

The application displays statistics that relate to one ConnectionConsumer on screen, and writes statistics that relate to the other ConnectionConsumer to a log file.

The command line syntax is similar to that for ASFClient1.java (substitute ASFClient2 for ASFClient1 in the syntax). Each of the two server session pools contains the number of ServerSessions set by the poolSize parameter.

There should be an uneven distribution of messages. The messages loaded onto the source queue by Load2 contain a user property, where the value is between 0 and 100, evenly and randomly distributed. The message selector value>75 is applied to highConnectionConsumer, and the message selector value<=75 is applied to normalConnectionConsumer. The highConnectionConsumer's messages (approximately 25% of the total load) are sent to a LoggingMessageListener. The normalConnectionConsumer's messages (approximately 75% of the total load) are sent to a CountingMessageListener.

When the client application runs, statistics that relate to the normalConnectionConsumer, and its associated CountingMessageListenerFactories, are printed to screen every 10 seconds. Statistics that relate to the highConnectionConsumer, and its associated LoggingMessageListenerFactories, are written to the log file.

You can inspect the screen and the log file to see the real destination of the messages. Add the totals for each of the CountingMessageListeners. As long as the client application does not terminate before all the messages are consumed, this accounts for approximately 75% of the load. The number of log file entries accounts for the remainder of the load. (If the client application terminates before all the messages are consumed, you can increase the application timeout.)

 

TopicLoad.java

This class is a JMS application that is a publish/subscribe version of the Load2 queue loader described in Load2.java. It publishes the required number of messages under the given topic, then terminates. Each message contains a user property called value, which takes a randomly selected integer value between 0 and 100.

To use this application, ensure that the broker is running and that the required setup is complete. For details, see Additional setup for publish/subscribe mode.

This application has two versions of the command line syntax.

For use with JNDI, the syntax is:

java TopicLoad [-icf jndiICF] [-url jndiURL] [-tcfLookup tcfLookup]
               [-tLookup tLookup] [-sleep sleepTime] [-msgs numMsgs]

For use without JNDI, the syntax is:

java TopicLoad -nojndi [-qmgr qMgrName] [-t tName]
                       [-sleep sleepTime] [-msgs numMsgs]

Table 31 describes the parameters and gives their defaults.

Table 31. TopicLoad parameters and defaults

Parameter Meaning Default
jndiICF Initial context factory class used for JNDI com.sun.jndi.ldap.LdapCtxFactory
jndiURL Provider URL used for JNDI ldap://localhost/o=ibm,c=us
tcfLookup JNDI lookup key used for TopicConnectionFactory cn=tcf
tLookup JNDI lookup key used for Topic cn=t
qMgrName Name of queue manager to connect to, and broker queue manager to publish messages to "" (use the default queue manager)
tName Name of topic to publish to MQJMS/ASF/TopicLoad
sleepTime Time (in milliseconds) to pause between message puts 0 (no pause)
numMsgs Number of messages to put 200

If there are any errors, an error message is displayed and the application terminates.

 

ASFClient3.java

ASFClient3.java is a client application that is a publish/subscribe version of ASFClient1.java. It sets up a single ConnectionConsumer to consume the messages published on a single Topic. It displays throughput statistics for each message listener that is used, and terminates after one minute.

This application has two versions of the command line syntax.

For use with JNDI, the syntax is:

java ASFClient3 [-icf jndiICF] [-url jndiURL] [-tcfLookup tcfLookup]
                [-tLookup tLookup] [-poolsize poolSize] [-batchsize batchSize]

For use without JNDI, the syntax is:

java ASFClient3 -nojndi [-qmgr qMgrName] [-t tName] 
                        [-poolsize poolSize] [-batchsize batchSize]

Table 32 describes the parameters and gives their defaults.

Table 32. ASFClient3 parameters and defaults

Parameter Meaning Default
jndiICF Initial context factory class used for JNDI com.sun.jndi.ldap.LdapCtxFactory
jndiURL Provider URL used for JNDI ldap://localhost/o=ibm,c=us
tcfLookup JNDI lookup key used for TopicConnectionFactory cn=tcf
tLookup JNDI lookup key used for Topic cn=t
qMgrName Name of queue manager to connect to, and broker queue manager to publish messages to "" (use the default queue manager)
tName Name of topic to consume from MQJMS/ASF/TopicLoad
poolSize The number of ServerSessions created in the ServerSessionPool being used 5
batchSize The maximum number of message that can be assigned to a ServerSession at a time 10

Like ASFClient1, the client application displays throughput statistics for each message listener that is used, displaying statistics every 10 seconds. After one minute, the connection is closed, the server session pool is stopped, and the application terminates.

 

ASFClient4.java

ASFClient4.java is a more complex publish/subscribe client application. It creates three ConnectionConsumers that all feed off the same topic, but each one applies different message selectors.

The first two consumers use high and normal message selectors, in the same way as described for the application ASFClient2.java. The third consumer does not use any message selector. The application uses two CountingMessageListenerFactories for the two selector-based consumers, and a LoggingMessageListenerFactory for the third consumer. Because the application uses different message listener factories, each consumer must have its own server session pool.

The application displays statistics that relate to the two selector-based consumers on screen. It writes statistics that relate to the third ConnectionConsumer to a log file.

The command line syntax is similar to that for ASFClient3.java (substitute ASFClient4 for ASFClient3 in the syntax). Each of the three server session pools contains the number of ServerSessions set by the poolSize parameter.

When the client application runs, statistics that relate to the normalConnectionConsumer and the highConnectionConsumer, and their associated CountingMessageListenerFactories, are printed to screen every 10 seconds. Statistics that relate to the third ConnectionConsumer, and its associated LoggingMessageListenerFactories, are written to the log file.

You can inspect the screen and the log file to see the real destination of the messages. Add the totals for each of the CountingMessageListeners and inspect the number of log file entries.

The distribution of messages is different from the distribution obtained by a point-to-point version of the same application (ASFClient2.java). This is because, in the publish/subscribe domain, each consumer of a topic obtains its own copy of each message published on that topic. In this application, for a given topic load, the high and normal consumers receive approximately 25% and 75% of the load, respectively. The third consumer still receives 100% of the load. Therefore, the total number of messages received is greater than 100% of the load originally published on the topic.

 

ASFClient5.java

This sample exercises the durable publish/subscribe ConnectionConsumer functionality in WebSphere MQ JMS.

You invoke it with the same command-line options as the ASFClient4 sample, and, as with the other samples, the TopicLoad sample application can be used to trigger the consumer that is created. For details of TopicLoad, see TopicLoad.java.

When invoked, ASFClient5 displays a menu of three options:

   1. Create/reactivate a durable ConnectionConsumer
   2. Unsubscribe a durable ConnectionConsumer
   X. Exit

If you choose option 1, and this is the first time this sample has been run, a new durable ConnectionConsumer is created using the given name. It then displays one minute's worth of throughput statistics, rather like the other samples, before closing the connection and terminating.

Having created a durable consumer, messages published on the topic in question continues to arrive at the consumer's destination even though the consumer is inactive.

This can be confirmed by running ASFClient5 again, and selecting option 1. This reactivates the named durable consumer, and the statistics displayed show that any relevant messages published during the period of inactivity were subsequently delivered to the consumer.

If you run ASFClient5 again and select option 2, this unsubscribes the named durable ConnectionConsumer and discards any outstanding messages delivered to it. Do this to ensure that the broker does not continue to deliver unwanted messages.

 

WebSphere is a trademark of the IBM Corporation in the United States, other countries, or both.

 

IBM is a trademark of the IBM Corporation in the United States, other countries, or both.