Mule ESB: настройка конечной точки JMS для очереди WMQ

В настоящее время я работаю с мулом и нужно написать в очереди WMQ. Но вместо использования конечной точки WMQ я хочу сделать это с помощью конечной точки JMS. Вот моя конфигурация:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:jms="http://www.mulesoft.org/schema/mule/jms" xmlns:jetty="http://www.mulesoft.org/schema/mule/jetty" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:wmq="http://www.mulesoft.org/schema/mule/ee/wmq" xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:data-mapper="http://www.mulesoft.org/schema/mule/ee/data-mapper" xmlns:ajax="http://www.mulesoft.org/schema/mule/ajax" xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.4.1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.mulesoft.org/schema/mule/ajax http://www.mulesoft.org/schema/mule/ajax/current/mule-ajax.xsd
http://www.mulesoft.org/schema/mule/ee/data-mapper http://www.mulesoft.org/schema/mule/ee/data-mapper/current/mule-data-mapper.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd
http://www.mulesoft.org/schema/mule/ee/wmq http://www.mulesoft.org/schema/mule/ee/wmq/current/mule-wmq-ee.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/jetty http://www.mulesoft.org/schema/mule/jetty/current/mule-jetty.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd">
    <wmq:connector name="WMQ" hostName="localhost" port="1414" queueManager="localmanager" validateConnections="true" doc:name="WMQ" ccsId="819"/>
    <data-mapper:config name="map_to_xml" transformationGraphPath="map_to_xml.grf" doc:name="map_to_xml"/>
    <data-mapper:config name="xml_to_json" transformationGraphPath="xml_to_json.grf" doc:name="xml_to_json"/>

    <jms:connector name="jmsConnector"
        connectionFactoryJndiName="jms/ConnectionFactory"
        jndiInitialFactory="com.ibm.websphere.naming.WsnInitialContextFactory"
        specification="1.1"
        connectionFactory-ref="MQConnectionFactory">
        <spring:property name="jmsSupport" ref="customJmsSupport"/>
    </jms:connector>
    <spring:beans>
        <spring:bean id="customJmsSupport" class="CustomJms11Support">
            <spring:constructor-arg ref="jmsConnector" />
        </spring:bean>
        <spring:bean name="MQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
            <spring:property name="hostName" value="localhost"/>
            <spring:property name="port" value="1414"/>
            <spring:property name="queueManager" value="localmanager"/>
            <spring:property name="transportType" value="1"/>
        </spring:bean>
    </spring:beans>

    <flow name="RequestFlow" doc:name="RequestFlow">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8088" path="uebermittleAusweisdaten" doc:name="HTTP" contentType="text/html"/>
        <expression-filter expression="#[message.payload !='/favicon.ico']" doc:name="Expression"/>
        <jersey:resources doc:name="REST">
            <component class="de.fraport.sources.RestClass"/>
        </jersey:resources>
        <set-variable variableName="id" value="#[message.id]" doc:name="Message ID"/>
        <json:json-to-object-transformer returnClass="java.util.Map" doc:name="JSON to Object"/>
        <data-mapper:transform config-ref="map_to_xml" doc:name="Map To XML">
            <data-mapper:input-arguments>
                <data-mapper:input-argument key="id">#[flowVars['id']]</data-mapper:input-argument>
            </data-mapper:input-arguments>
        </data-mapper:transform>
        <flow-ref name="Subflow1" doc:name="Flow Reference"/>
        <parse-template location="D:\Workspace\ajax_rest\src\main\app\www\index.html" doc:name="Parse Template"/>
    </flow>
    <sub-flow name="Subflow1" doc:name="Subflow1">
        <mulexml:xslt-transformer encoding="ISO8859-1" maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="D:\Workspace\ajax_rest\mobako.sender.xsl" doc:name="SOAP Envelope"/>
        <mulexml:dom-to-xml-transformer outputEncoding="ISO8859-1" doc:name="DOM to XML"/>
        <outbound-endpoint doc:name="JMS" address="jms://LSMH.ZKSEAP.SERVICEBUS" connector-ref="jmsConnector" encoding="ISO8859-1"/>
        <!-- <wmq:outbound-endpoint queue="LSMH.ZKSEAP.SERVICEBUS" encoding="ISO8859-1" connector-ref="WMQ" doc:name="ZKSEAP IN"/> -->
        <set-property propertyName="MULE_CORRELATION_ID" value="#[function:dateStamp:yyyy-MM-dd HH:mm:ss]" doc:name="Set Correlation ID"/>
        <request-reply>  
            <vm:outbound-endpoint path="sender">  
                <message-properties-transformer scope="outbound"> 
                    <delete-message-property key="MULE_REPLYTO"/> 
                </message-properties-transformer> 
            </vm:outbound-endpoint>  
            <vm:inbound-endpoint path="response">  
                <logger level="INFO" message="#[string:XXXXXX 1:  #[message.inboundProperties]"/> 
            </vm:inbound-endpoint> 
        </request-reply>
    </sub-flow>
    <flow name="ResponseFlow" doc:name="ResponseFlow">
        <inbound-endpoint address="jms://ZKSEAP.LSMH.SERVICEBUS" connector-ref="jmsConnector" doc:name="ZKSEAP OUT"/>
        <!-- <wmq:inbound-endpoint queue="ZKSEAP.LSMH.SERVICEBUS" connector-ref="WMQ" doc:name="ZKSEAP OUT" encoding="UTF-8"/> -->
        <set-property propertyName="MULE_CORRELATION_ID" value="#[function:dateStamp:yyyy-MM-dd HH:mm:ss]" doc:name="Set Correlation ID"/>
        <data-mapper:transform doc:name="XML To JSON" config-ref="xml_to_json"/>
        <byte-array-to-string-transformer doc:name="Byte Array to String"/>
        <vm:outbound-endpoint path="response" doc:name="Response Outbound" exchange-pattern="one-way"/>
    </flow>
</mule>

Я успешно прочитал сообщение из очереди WMQ с помощью конечной точки JMS. Однако, когда я попытался написать какое-либо сообщение в очереди WMQ с помощью конечной точки JMS, я получил следующую ошибку с моего сервера:

2014-07-22 10:11:27,064 [Задача Axis2] ОШИБКА WMQMsg - Ожидаемый формат сообщения MQ "MQSTR", но получен "MQHRF2" 2014-07-22 10:11:27,064 [Задача Axis2] WARN QMgrConnection - Перемещение сообщения в очередь недоставленных сообщений после 1 попытки / попытки: 414D51206C6F63616C6D616E616765721A0CCE5320003C0 2 [Неустранимая ошибка]:1:1: Содержимое ist nicht zulõssig в ​​Прологе. ОШИБКА: "Содержание в прологе." 2014-07-22 10:11:27,064 [Задача Axis2] ПРЕДУПРЕЖДЕНИЕ ESBMsg - Ошибка предварительной настройки ESBMsg для печати журнала

Я знаю, что эта ошибка произошла, потому что я пытался записать в очередь не JMS. Также я знаю, что мне нужно решить эту проблему, установив "? TargetClient=1". Однако, когда я попытался добавить атрибут targetClient в свой URL-адрес очереди, я все равно получил ошибку (кажется, что атрибут тоже был распознан как URL-адрес WMQ).

Затем из своего исследования я обнаружил, что не могу напрямую установить "? TargetClient" в URL. Вместо этого мне нужно создать класс Java для установки "? TargetClient". Чтобы создать этот класс, я следую некоторым инструкциям из следующего URL

Создать пользовательский класс JMSSupport

Но, к сожалению, у меня это тоже не сработало. У кого-нибудь есть идеи о том, как я могу это решить? Благодарю.

NB. В Apache Camel я могу просто решить эту проблему, добавив:

<setHeader headerName="CamelJmsDestinationName">
    <constant>queue:///LSMH.ZKSEAP.SERVICEBUS?targetClient=1</constant>    
</setHeader>

Есть ли что-то похожее в Mule ESB?

1 ответ

Решение

Просто решил проблему:

Это правильно, что нам нужно создать Java-класс для установки targetClient. И для этого мы можем перейти по ссылке, которую я дал выше. Однако нам нужно немного изменить код. Вот правильный код:

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Session;

import org.mule.api.endpoint.ImmutableEndpoint;
import org.mule.transport.jms.Jms11Support;
import org.mule.transport.jms.JmsConnector;

import com.ibm.mq.jms.JMSC;
import com.ibm.mq.jms.MQQueue;

/**
* Implements WebSphere MQ specific JMS support for Mule. The class
* overrides the createDestination method to intercept JMS Queue object
* creation and sets the targetClient=1 property on created MQQueue
* objects. This is necessary to prevent non-JMS consumers from being
* choked by RFH2 headers.
*/
public class CustomJms11Support extends Jms11Support {

    public CustomJms11Support(JmsConnector connector) {
        super(connector);
    }

    @Override
    public Destination createDestination(Session session, String name, boolean
    topic, ImmutableEndpoint ie) throws JMSException {
        Destination destination = super.createDestination(session, name, topic, ie);
        if (destination instanceof MQQueue){
            ((MQQueue) destination).setTargetClient(JMSC.MQJMS_CLIENT_NONJMS_MQ);
        }
        return destination;
    }
}

И затем нам нужно будет установить свойство с именем "JMS_IBM_Character_Set" (в противном случае мы получим "Ожидаемый MQ message characterSet" 819 ", но получил ошибку" 1208 "") перед отправкой запроса в конечную точку JMS. Вот как я это настраиваю:

<set-property propertyName="JMS_IBM_Character_Set" value="ISO8859_1" doc:name="Property"/>

И только для вашей информации, изменив конечную точку WMQ на конечную точку JMS, это точно улучшит производительность.

Надеюсь, это будет полезно:D

Другие вопросы по тегам