This document summarises configurations for consuming and producing messages using the native IBM WebsphereMQ API. If you are attaching to WebsphereMQ via JMS, then the JMS Guide contains specifics for that. It assumed that you have a passing knowledge of Interlok and its configuration. This guide has been built with MQSeries version 7.5 in mind. However if you happen to be using another version, the only changes should be to the java archive files you will need to copy from your MQSeries installation to your Interlok installation, mentioned later in this guide.
Before you can start Interlok that is able to consume or produce from or to MSMQ, you must first install the Interlok MSMQ sub component into your Interlok installation. All available Interlok sub components are shipped with the standard Interlok installation. Simply navigate to the optional directory at the root of your Interlok installation and from there the
webspheremq subdirectory. Copy the java archive file named
interlok-webspheremq.jar to your lib directory in the root of your Interlok installation. Finally you will also need to copy any required java archives for client access from your MQSeries installation into the lib directory of your Interlok installation directory. Generally speaking this will be all
com.ibm.*.jar files, along with
dhbcore.jar, however additional jars may be required depending on the connection method. All configuration examples for can be found in the docs/optional/example-xml directory as normal.
Native Consumer / Producer
In some situations, it is preferable to use the native API for accessing WebsphereMQ, perhaps because not all of the available fields from MQMessage are mapped when using the JMS API.
There are two types of connection available to use: wmq-attached-connection and wmq-detached-connection. Both types of connection have exactly the same configuration. The key difference between the two connections is that an wmq-attached-connection reuses the same
MQQueueManager instance for the lifecycle of the connection. wmq-detached-connection creates a new MQQueueManager instance every time it is required. wmq-attached-connection may have added performance benefits, if
MQQueueManager is a resource hungry component; however, in testing, using wmq-attached-connection stopped WebsphereMQ from performing a controlled shutdown, and caused additional issues when attempting to recover from an uncontrolled shutdown.
|queue-manager||The name of the queue manager within WebsphereMQ to connect to|
|redirect-exception-logging||Defaults to false. MQException exposes a static field log which receives additional logging information when an MQException is encountered. Set this to be true, if you wish for that additional logging to be redirected from stderr to the log4j logging system.|
|environment-properties||A KeyValuePairSet that contains additional properties that are provided to the MQQueueManager constructor. This exposes primitive values (such as String, Boolean, Integer) so that the default WebsphereMQ Client settings can be overridden. Consult the javadocs for NativeConnection for additional information|
Sending and Receiving Messages
Both the wmq-native-producer and wmq-native-consumer implementations have broadly the same type of configuration. The standard implementation for consuming messages from WebsphereMQ is a PollingConsumer implementation. There is no facility within the WebsphereMQ API to register a listener, so we physically poll the MQQueueManager for any new messages and process them upon each poll trigger. Each implementation contains a list of
field-mapper elements that are responsible for mapping each MQMessage field to and from the AdaptrisMessage. Additionally, each implementation has a number of configurable options available so that the MQQueue is accessible with a variety of options.
There are a number of ways you can map specific MQMessage fields into AdaptrisMessage and vice versa. All field mapper instances contain some common configuration elements:
|mq-field-name||This refers to the specific field within the MQMessage that you wish to map. Refer to the javadocs for FieldMapper to see the supported fields.|
|byte-translator||Some MQMessage fields are byte fields. The byte-translator is responsible for mapping the byte into Strings and vice versa.|
|convert-null||Whenever a null value is encountered, and this field is true, an attempt is made to convert the null into something meaningful.|
|wmq-metadata-field-mapper||This maps an item of AdaptrisMessage metadata to a specific MQMessage field (and vice versa). The metadata-key element determines the metadata key that will be used to derive the content of the mapping.|
|wmq-message-id-mapper||This maps the AdaptrisMessage unique id into a specific MQMessage field (and vice versa)|
|wmq-configured-field||This simply sets a specific MQMessage field to the configured value. MQMessage fields may not be mapped into AdaptrisMessage using this FieldMapper instance.|
|wmq-xpath-field||This resolves an XPath against the AdaptrisMessage payload and sets a specific MQMessage field based on this value. MQMessage fields may not be mapped into AdaptrisMessage instances using this instance|
|wmq-uuid-field-mapper||This field mapper sets the configured field to a freshly generated UUID. This is primarily only of use when using
There are currently 4 different byte translator implementations: charset-byte-translator, simple-byte-translator, base64-byte-translator and hex-string-byte-translator. These are described in their associated javadocs.
Message Format and Queue Options
The options on the consumer and producer control the behaviour when you
- Open the queue
- Close the queue
- Message Type that is sent/received from the queue
- Specific message options that control the behaviour of
All the options available are text values that match the MQC constant name; the corresponding integer value is derived through reflection. What this means is that if you have specific options (other than the default) which need to be applied, you will have to check the notes in the information centre for those values and to use the constant name as a comma separated string. (e.g.
MQOO_INPUT_AS_Q_DEF,MQOO_OUTPUT - no spaces!); alternatively you could use the literal integer value of 17 (MQOO_INPUT_AS_Q_DEF = 1 and MQOO_OUTPUT = 16). The default values are fairly sensible, and you should not have to modify these in most situations. If the options you have specified do not enable features that are specifically required by the Producer or Consumer at runtime, they may be added dynamically and a log message will be displayed indicating the option that was missing.
|queue-open-options||Sets the open options on the queue when accessing the Queue. Any or none of the literal values associated with the following MQC fields may be used. If more than one option is required, then values can separated using a , (make sure there are no spaces).
|queue-close-options||Set the specific options to be used when closing a queue. The default value is
|message-format||Specify the format of the message. Valid values are Text, String, Bytes, and Object. They correspond to the values
|message-options||This controls the options that are used when invoking
It is possible that messages that have been consumed from WebsphereMQ cannot be translated into an AdaptrisMessage object. Common causes for this would be:
- Incorrect mapping configuration
- Incorrect message type configuration
In both of these cases, an error will be logged; but the message may appear to have been discarded. WebsphereMQ queue has removed the message from the queue because it is considered as delivered. The adapter has indeed consumed this message but cannot continue to process the message if there are translation errors. If this situation is possible (because you are not in control of the sending application, or testing has not been sufficient) you need to configure a wmq-forwarding-native-consumer-error-handler which simply forwards the message that was consumed to another configured queue. The WebsphereMQ connection details are taken from the parent consumer, you can only configure a new queue to produce the error messages to. Also, the message options described previously will be inherited from the parent consumer, although you may override these if needed.
<consumer class="wmq-native-consumer"> <error-handler class="wmq-forwarding-native-consumer-error-handler"> <destination class="configured-produce-destination"> <destination>The_Error_Queue</destination> </destination> <options> <queue-open-options>MQOO_INPUT_AS_Q_DEF,MQOO_OUTPUT,MQOO_BROWSE</queue-open-options> <queue-close-options>MQCO_NONE</queue-close-options> <message-options>MQPMO_NO_SYNCPOINT</message-options> <message-format>Text</message-format> </options> </error-handler> ... // Other configuration skipped. </consumer>
The configuration above is a minimal configuration needed to forward a message that generates an error at the point when the adapter tries to translate the message from WebsphereMQ. We have overridden the message options from the consumer itself.