2016-01-29 19 views
7

Witam, czy ktoś kiedykolwiek używał Camela z IBM MQ. Rozważamy możliwość wspólnego korzystania z dwóch produktów, ale nie mamy żadnego przykładu, aby oba produkty współpracowały ze sobą.Apache Camel z IBM MQ

+1

Musisz użyć JMS, aby połączyć te dwa elementy. –

Odpowiedz

1

Najlepszą udało mi się dostać to udokumentowane poniżej przedstawiono jako kontekst aplikacji Wiosna XML, który sam serwer z kontekstu i trasy Camel. Ten przykład działa z macierzystym adapterem zasobów IBM MQ JCA w wersji 7.5, CAMEL 2.16, Spring Core 4.2. Rozmieściłem go na serwerach Glassfish, Weblogic i JBoss EAP7.

Złożoność jest związana z obsługą przepływu raportów MQ, których filozofia jest sprzeczna z prostym komunikatem odpowiedzi JMS. Szczegółowe wyjaśnienie znajduje się pod następującym numerem: Implementing native websphere MQ with CoD over Camel JMS component

Ten przykład oparty na CAMEL XML DSL jest samodzielny i łatwy do przetestowania.

rozpoczynamy ze sprężyną zgłoszeń & CAMEL:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:util="http://www.springframework.org/schema/util" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:camel="http://camel.apache.org/schema/spring" 
xmlns:jee="http://www.springframework.org/schema/jee" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd 
    http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd 
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> 

Kontekst CAMEL następujący 2 drogami: MQ do JMS i JMS do MQ o szeregowo tworząc mostek w celu ułatwienia badania.

<camel:camelContext id="mqBridgeCtxt"> 
<camel:route id="mq2jms" autoStartup="true"> 

Weird: na Weblogic, jedynym sposobem, aby uzyskać (np) 3 słuchaczy jest egzekwowanie 3 połączeń (z 3 Camel: od stwierdzeń w sekwencji) z max 1 sesja każdego, inaczej błąd MQ następuje: MQJCA1018 : Dozwolona jest tylko jedna sesja na połączenie. Na JBoss, można po prostu ustawić concurrentConsumers = ...

<camel:from uri="wmq:queue:TEST.Q1?concurrentConsumers=1&amp;disableReplyTo=true&amp; 
     acknowledgementModeName=SESSION_TRANSACTED"/> 

Powyższa opcja disableReplyTo wyłączyć zapewnia, że ​​CAMEL nie przyniesie odpowiedź, zanim będziemy mogli przetestować typ komunikatu MQ być 1 = kupna (-reply) lub 8 = datagram (w jedną stronę!). Ta konstrukcja testu i odpowiedzi nie została tutaj przedstawiona.

Następnie egzekwujemy EIP do InOnly w następnym wpisie do zwykłego JMS, aby był zgodny z trybem Inbound MQ.

<camel:setExchangePattern pattern="InOnly"/> 
    <!-- camel:process ref="reference to your MQ message processing bean fits here"/--> 
    <camel:to uri="ref:innerQueue" /> 
</camel:route> 

To kończy trasę MQ-to-jms; Następnie przychodzi trasa JMS-do-MQ nadal w tym samym kontekście CAMEL:

<camel:route id="jms2mq" autoStartup="true"> 
    <camel:from uri="ref:innerQueue" /> 
    <!-- remove inner message headers and properties to test without inbound side effects! --> 
    <camel:removeHeaders pattern="*"/> 
    <camel:removeProperties pattern="*" /> 
    <!-- camel:process ref="reference to your MQ message preparation bean fits here"/--> 

Teraz przychodzi flagę żądania do raportu MQ CoD zostać zwrócony przez zdalny przeznaczenia. Ponadto wymuszamy, aby komunikat MQ był typu Datagram (wartość 8).

<camel:setHeader headerName="JMS_IBM_Report_COD"><camel:simple resultType="java.lang.Integer">2048</camel:simple></camel:setHeader> 
    <camel:setHeader headerName="JMS_IBM_Report_Pass_Correl_ID"><camel:simple resultType="java.lang.Integer">64</camel:simple></camel:setHeader> 
    <camel:setHeader headerName="JMS_IBM_MsgType"><camel:simple resultType="java.lang.Integer">8</camel:simple></camel:setHeader> 

Kolejkę ReplyTo można określić za pomocą opcji ReplyTo uri, w przeciwnym razie jako nagłówek, jak poniżej.

Następnie używamy nagłówka CamelJmsDestinationName, aby wymusić wyłączenie nagłówka komunikatu MQ MQRFH2 (przy użyciu wartości opcji 1 adresu URL obiektu docelowego MClientClient). Innymi słowy, chcemy wysłać zwykłą binarną wiadomość MQ wanilii (to jest tylko deskryptor komunikatu MQMD, po którym następuje ładunek).

<camel:setHeader headerName="JMSReplyTo"><camel:constant>TEST.REPLYTOQ</camel:constant></camel:setHeader> 
    <camel:setHeader headerName="CamelJmsDestinationName"> <camel:constant>queue://MYQMGR/TEST.Q2?targetClient=1</camel:constant></camel:setHeader> 

Więcej pól MQMD może być kontrolowanych poprzez zastrzeżone właściwości JMS, jak pokazano poniżej. Zobacz ograniczenia w dokumencie IBM.

<camel:setHeader headerName="JMS_IBM_Format"><camel:constant>MQSTR </camel:constant></camel:setHeader> 
    <camel:setHeader headerName="JMSCorrelationID"><camel:constant>_PLACEHOLDER_24_CHARS_ID_</camel:constant></camel:setHeader> 

Cel kolejka URI są zastępowane przez CamelJmsDestinationName powyżej, stąd nazwa kolejka URI staje się zastępczy.

Opcja URI preserveMessageQos to taka, która - zgodnie z obserwacją - pozwala na wysłanie wiadomości z ustawionymi danymi ReplyTo (aby uzyskać raport CoD MQ), ale uniemożliwić CAMEL utworzenie instancji odbiornika wiadomości Reply poprzez wymuszenie InOnly MEP.

<camel:to uri="wmq:queue:PLACEHOLDER.Q.NAME?concurrentConsumers=1&amp; 
      exchangePattern=InOnly&amp;preserveMessageQos=true&amp; 
      includeSentJMSMessageID=true" /> 
</camel:route> 
</camel:camelContext> 

Nie skończyliśmy, mamy jeszcze zadeklarować nasze fabryki kolejki zarówno rodzimego dostawcy JMS i WebSphere MQ (poprzez natywny IBM WMQ JCA zasobów Adapter), należy dostosować do kontekstu. Używamy tutaj wyszukiwań JNDI na obiektach administracyjnych.

<camel:endpoint id="innerQueue" uri="jmsloc:queue:transitQueue"> 
</camel:endpoint> 

<jee:jndi-lookup id="mqQCFBean" jndi-name="jms/MYQMGR_QCF"/> 
<jee:jndi-lookup id="jmsraQCFBean" jndi-name="jms/jmsra_QCF"/> 

<bean id="jmsloc" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="connectionFactory" ref="jmsraQCFBean" /> 
</bean> 

<bean id="wmq" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="connectionFactory" ref="mqQCFBean" /> 
</bean> 

</beans> 

Alternatywą do pobierania fabryk (i adapterów JCA) z JNDI jest zadeklarować jako klient JMS wiosennych fasoli. W Weblogic i GlassFish, będziesz lepiej inspirowany wdrażania rodzimej adaptera zasobów IBM JCA i tworzenia zasobów JNDI następnie odwołuje Spring kontekście jak powyżej, w JBoss MQ bezpośrednia deklaracja fasola klient najlepiej pasuje jak poniżej)

<bean id="mqCFBean" class="com.ibm.mq.jms.MQXAConnectionFactory"> 
    <property name="hostName" value="${mqHost}"/> 
    <property name="port" value="${mqPort}"/> 
    <property name="queueManager" value="${mqQueueManager}"/> 
    <property name="channel" value="${mqChannel}"/> 
    <property name="transportType" value="1"/> <!-- This parameter is fixed and compulsory to work with pure MQI java libraries --> 
    <property name="appName" value="${connectionName}"/> 
</bean> 

<bean id="wmq" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="connectionFactory" ref="mqCFBean"/> 
    <property name="transacted" value="true"/> 
    <property name="acknowledgementModeName" value="AUTO_ACKNOWLEDGE"/> 
</bean> 

Zapraszamy i komentarze.

5

mam szerokie wykorzystanie IBM MQ z wielbłąda. Nie ma problemu z wykorzystaniem obu razem. Wkleję przykładową konfigurację z jednego z moich plików kontekstowych sprężyn, wykorzystując wielbłąd Jms Endpoint, fabrykę połączeń sprężynowych i definicję produktu IBM MQ.

Camel Route

from("someplace") 
    .to("cpaibmmq:queue:myQueueName"); 

Wiosna Kontekst

<bean name="cpaibmmq" class="org.apache.camel.component.jms.JmsComponent" destroy-method="doStop"> 
    <property name="transacted" value="${jms.transacted}" /> 
    <property name="concurrentConsumers" value="${cpa.concurrentConsumers}" /> 
    <property name="maxConcurrentConsumers" value="${cpa.concurrentConsumers}" /> 
    <property name="acceptMessagesWhileStopping" value="${jms.acceptMessagesWhileStopping}" /> 
    <property name="acknowledgementModeName" value="${jms.acknowledgementModeName}" /> 
    <property name="cacheLevelName" value="${jms.cacheLevelName}" /> 
    <property name="connectionFactory" ref="ibmFac1" /> 
    <property name="exceptionListener" ref="ibmFac1" /> 
</bean> 

<bean id="ibmFac1" class="org.springframework.jms.connection.SingleConnectionFactory" destroy-method="destroy"> 
    <constructor-arg> 
     <bean class="com.ibm.mq.jms.MQQueueConnectionFactory"> 
      <property name="transportType" value="1" /> 
      <property name="channel" value="${cpa.wmq.channel}" /> 
      <property name="hostName" value="${cpa.wmq.hostname}" /> 
      <property name="port" value="${cpa.wmq.port}" /> 
      <property name="queueManager" value="${cpa.wmq.mqmanager}" /> 
     </bean> 
    </constructor-arg> 
</bean> 
+0

Wygląda na to, że nie ma potrzeby określania właściwości 'queueManager' i' channel'. Określenie właściwości 'port' byłoby również opcjonalne, jeśli menedżer kolejek ma aktywnego detektora na domyślnym porcie' 1414', czyż nie? Myślę, że jako agent między aplikacją 'jms' i' ibm mq', detektor określa docelowy menedżer kolejek. Co więcej, zasadniczo nie ma potrzeby posiadania żadnego 'channel' w docelowym menedżerze kolejek! – faghani

Powiązane problemy