You can also write your own adapters to tailor MQe for your own environment.
This topic describes some adapter examples that are supplied to help you with
this task.
This example is not intended as a replacement for the adapters that are
supplied with MQe, but as a simple introduction on how to create a communications
adapter.
To use your communications adapter, you must specify the correct class
name when creating the listener on the server queue manager, and specify the
connection definition on the client queue manager.
All communications adapters must inherit from MQeCommunicationsAdapter
and must implement the required methods. In order to show how this might
be done we shall use the example adapter, examples.adapters.MQeTcpipLengthGUIAdapter.
This is a simple example that accepts data to be written. It also places the
data length and the amount of data to be written to standard out, at the front
of the data. When the adapter reads data, the data length is written to standard
out. Proper error checking and recovery is not carried out. This must be added
to any adapter written by a user.
MQe adapters use the default constructor. For this reason, an activate() method
is used in order to set up the adapter with an open() method
used to prepare the adapter for communication.
The
activate() method is called only once in the life
cycle of an adapter and is, therefore, used to set up the information from
MQePropertyProvider. The MQePropertyProvider looks internally to verify that
the specified property is available. If it is not available, it checks the Java™ properties.
In this way, it is possible for a user to specify a property that may be set
by the application or JVM command line. The MQeCommunicationsAdapter provides
two variables that allow the adapter to identify its role within the communications
conversation:
- If the adapter is being used by the MQeListener, the variable listeningAdapter is
set to true.
- If the adapter has been created by the listening adapter in response
to an incoming request, the responderAdapter variable is
set to true.
The following code, taken from the
activate() method,
shows how to obtain the information from the MQePropertyProvider.
if (!listeningAdapter) {
// if we are not a listening adapter we need the
address of the server
address = info.getProperty
(MQeCommunicationsAdapter.COMMS_ADAPTER_ADDRESS);
}
The
open() method is called before each conversation and
must, therefore, be used to set information that needs to be reset for each
request or response. For example, an adapter that is not persistent needs
to create a socket each time it is opened. The following code shows the use
of the variables that identify the role of the adapter role within the conversation:
if (listeningAdapter && null == serverSocket) {
serverSocket = new ServerSocket(port);
} else if (!responderAdapter && null == mySocket) {
mySocket = new Socket(InetAddress.getByName(address), port);
}
Once the
activate() and
open() methods
have been called, the listening adapter
waitForContact method
is called. This method must wait at named location. In an IP network, this
will be a named port. When a request is received, a new adapter is created.
Note: This method must set the listeningAdapter to false and the responderAdapter
to true.
Once the adapter has been set up correctly, you must must returned
it to the caller. The following code shows how to do this:
MQeTcpipLengthGUIAdapter clientAdapter =
(MQeTcpipLengthGUIAdapter)
MQeCommunicationsAdapter.createNewAdapter(info);
// set the boolean variables so the adapter
// knows it is a responder. the listening
// variable will have been set to true as
// the MQePropertyProvider has the relevant
// information to create
// this listening adapter. We must therefore reset the
// listeningAdapter variable to false and the
//responderAdapter variable to true.
clientAdapter.responderAdapter = true;
clientAdapter.listeningAdapter = false;
// Assign the new socket to this new adapter
clientAdapter.setSocket(clientSocket);
return clientAdapter;
The initiator adapter and responder adapter are responsible for the main
part of the conversation. The initiator starts the conversation. The responder
is created by the listening adapter, reads the request that is passed back
to MQe, which then writes a response. The adapter determines how the read
and the write are undertaken. The example uses a BufferedInputStream and a
BufferedOutputStream.
Note: Use a a non-blocking mode of reading and writing.
This enables the adapter to respond to requests to shutdown.
The following
code, taken from the
waitForContact() method, shows how the
non-blocking read can be written. As MQe supports all Java runtime
environments we are unable to use Java version 1.4 specific classes for our
examples, although this version does contain new non-blocking classes
do {
try {
clientSocket = serverSocket.accept();
} catch (InterruptedIOException iioe) {
if (MQeThread.getDemandStop()) {
throw iioe;
}
}
} while (null == clientSocket);