воскресенье, 2 августа 2009 г.

Oracle OC4J 10.1.3.3 и IBM Websphere MQ 6

Хотел поделиться опытом настройки OC4J (Oracle Containers for J2EE) для подключения к системе обмена сообщениями Websphere MQ 6.

Проблема с первого взгляда тривиальна, но существует ряд моментов, на которые можно потратить уйму времени, так как полной документации по настройке нет.

До выхода WMQ 6, для подключения Oc4J к WMQ, мы использовали несколько модифицированный адаптер oraclejms (поставляется с Oc4j), jndi файлы с настройками очередей. Так же приходилось патчить класслоадер OC4J. В WMQ 6, начиная, кажется, с версии 6.0.2.5 появился JCA 1.5 адаптер для подключения java приложений к WMQ. Вот его я и решил попробовать использовать.

Итак, задача такая. Нужно научить JEE приложение читать сообщения из очередей WMQ и отправлять в WMQ.



Последовательность шагов такая:

  1. Подготавливаем архив с адаптером ресурсов WMQ и устанавливаем его в OC4J.
  2. Настраиваем коннектор в OC4J.
  3. Настраиваем приложение на данный адаптер ресурсов

Подготовка адаптера ресурсов к WMQ для OC4J.

1. Файл с адаптером находится в каталоге WMQ\Java\lib\jca\wmq.jmsra.rar. Нужно создать файл oc4j-ra.xml и поместить его внутутрь wmq.jmsra.rar в каталог META-INF

Файл oc4j-ra.xml:

<oc4j-connector-factories xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/oc4j-connector-factories-10_0.xsd"
schema-major-version="10"
schema-minor-version="0">
<connector-factory location="WMQ/QueueConnectionFactory" connector-name="WMQ">
<config-property name="CCSID" value="1208"/>
<config-property name="channel" value="SRV.CONN"/>
<config-property name="failIfQuiesce" value="true"/>
<config-property name="hostName" value="127.0.0.1"/>
<config-property name="port" value="1414"/>
<config-property name="queueManager" value="TESTQMGR"/>
<config-property name="transportType" value="BINDINGS"/>
<config-property name="sslResetCount" value="1"/>
<connectionfactory-interface>javax.jms.QueueConnectionFactory</connectionfactory-interface>
</connector-factory>
<connector-factory location="WMQ/XAQueueConnectionFactory" connector-name="WMQ">
<config-property name="CCSID" value="1208"/>
<config-property name="channel" value="SRV.CONN"/>
<config-property name="failIfQuiesce" value="true"/>
<config-property name="hostName" value="127.0.0.1"/>
<config-property name="port" value="1414"/>
<config-property name="queueManager" value="TESTQMGR"/>
<config-property name="transportType" value="BINDINGS"/>
<config-property name="sslResetCount" value="1"/>
<connectionfactory-interface>javax.jms.QueueConnectionFactory</connectionfactory-interface>
</connector-factory>
</oc4j-connector-factories>


Параметры:
WMQ – имя адаптера ресурсов,
WMQ/QueueConnectionFactory (XAQueueConnectionFactory) – имя фабрики для соединения с WMQ,
TESTQMGR – имя менеджера очередей

2. Нужно скопировать следующие библиотеки из WMQ\java\lib в OC4J\j2ee\home\applib и перезапустить OC4J:
* com.ibm.mq.jar
* com.ibm.mqjms.jar
* dhbcore.jar
* mqconnector.jar

3. Через консоль администрирования установить wmq.jmsra.rar.

Настройка коннектора в OC4J.
Далее, нужно настроить адаптер, прописав нужные параметеры с файле oc4j-connectors.xml:

<connector name="WMQ" path="WMQ.rar">
<security-permission enabled="false">
<description>Security Permissions for the JMS client</description>
<security-permission-spec>grant {
permission java.security.AllPermission;
};</security-permission-spec>
</security-permission>
<config-property name="connectionConcurrency" value="10"/>
<config-property name="maxConnections" value="30"/>
<config-property name="logWriterEnabled" value="true"/>
<config-property name="reconnectionRetryCount" value="5"/>
<config-property name="reconnectionRetryInterval" value="300000"/>
<config-property name="timestampsEnabled" value="true"/>
<config-property name="traceDestination" value="wmq_jms.log"/>
<config-property name="traceEnabled" value="true"/>
<config-property name="traceLevel" value="10"/>
<adminobject-config location="WMQ/MQTest">
<adminobject-class>com.ibm.mq.connector.outbound.MQQueueProxy</adminobject-class>
<config-property name="encoding" value="NATIVE"/>
<config-property name="expiry" value="UNLIMITED"/>
<config-property name="baseQueueName" value="TESTQ"/>
<config-property name="failIfQuiesce" value="true"/>
<config-property name="targetClient" value="MQ"/>
<config-property name="baseQueueManagerName" value="TESTQMGR"/>
<config-property name="CCSID" value="1208"/>
<config-property name="priority" value="QDEF"/>
<config-property name="persistence" value="PERS"/>
<config-property name="port" value="1414"/>
</adminobject-config>
...


Основные параметры, которые вам нужно будет поменять – это baseQueueManagerName (имя менеджера), baseQueueName (имя очереди), adminobject-config location (имя в JNDI)


После изменения фала нужно перезапустить OC4J перед установкой JEE приложения.

Настройка приложения


Настройка приложения на чтение, сводится к настройке MDB бина, прописыванием правильного activation-config.
Пример настройки:

@MessageDriven
(name = "GeneralTransportMQBean",
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue ="TESTQ"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"),
@ActivationConfigProperty(propertyName = "hostName", propertyValue = "127.0.0.1"),
@ActivationConfigProperty(propertyName = "port", propertyValue = "1414"),
@ActivationConfigProperty(propertyName = "channel", propertyValue = "SRV.CONN"),
@ActivationConfigProperty(propertyName = "queueManager", propertyValue = "TESTQMGR"),
@ActivationConfigProperty(propertyName = "transportType", propertyValue = "BINDINGS")
})
@MessageDrivenDeployment(resourceAdapter = "WMQ")

public class TestMQBean implements MessageListener{…


Тут, вроде бы, все ясно, где какой параметр.
Если хочется, чтобы настройки на очередь находились вне приложения и их можно было менять без пересборки, то можно прописать конфиг с использованием JNDI:

@MessageDriven
(name = "TestMQBean",
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "WMQ/MQTest"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true")
})
@MessageDrivenDeployment(resourceAdapter = "WMQ")
public class TestMQBean implements MessageListener{…



В принципе, вот и все - приложение готово для установки.

И еще, чтобы при ошибках обработки сообщения помещались из очереди TESTQ в другую очередь, например, очередь ошибочных сообщений, нужно в натройках MQ для очереди TESTQ указать "Backout threshold" (количество повторов обработки) и "Backout requeue queue" (имя очереди).
ps: При использовании JNDI имеется ряд проблем, которые мешают полноценно использовать конфигурацию в JNDI. Подробно проблему и ее решение я описывал на форуме mqseries.net - MQ 6.0.2.7 JCA 1.5 and OC4J. Problems and Solutions

Читать далее