2016-01-29 18 views
7

Xin chào có ai từng sử dụng Camel với MQ của IBM. Chúng tôi đang xem xét có thể sử dụng hai sản phẩm với nhau nhưng không có ví dụ về hai sản phẩm làm việc cùng nhau.Apache Camel với IBM MQ

+1

Bạn cần sử dụng JMS để kết nối cả hai với nhau. –

Trả lời

1

Điều tốt nhất tôi đã có thể để có được được ghi chép lại dưới đây, minh họa như một bối cảnh ứng dụng Spring XML mà bản thân tổ chức bối cảnh CAMEL và các tuyến đường. Mẫu này hoạt động với bộ điều hợp nguồn tài nguyên tương thích MQ JCA của IBM v7.5, CAMEL 2.16, lõi Spring 4.2. Tôi đã triển khai nó trong các máy chủ Glassfish, Weblogic và JBoss EAP7.

Độ phức tạp bị ràng buộc để xử lý luồng báo cáo MQ có triết lý xung đột với thông điệp trả lời JMS đơn giản. Để được giải thích chi tiết, vui lòng tham khảo Implementing native websphere MQ with CoD over Camel JMS component

Ví dụ này dựa trên CAMEL XML DSL là khép kín và dễ kiểm tra.

Chúng tôi bắt đầu với mùa xuân khai & 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"> 

Bối cảnh CAMEL sau với 2 tuyến đường: MQ để JMS và JMS để MQ, đây xích để tạo thành một cây cầu để giảm bớt thử nghiệm.

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

Weird: trên WebLogic, cách duy nhất để có được (ví dụ) 3 thính giả là để thực thi 3 kết nối (với 3 Camel: từ báo cáo theo trình tự) với tối đa 1 phiên mỗi, nếu không một lỗi MQ xảy ra sau đó: MQJCA1018 : Chỉ cho phép một phiên cho mỗi kết nối. Trên JBoss, bạn chỉ có thể điều chỉnh concurrentConsumers = ...

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

Tùy chọn disableReplyTo vô hiệu hóa trên đảm bảo rằng CAMEL sẽ không tạo ra một câu trả lời trước khi chúng tôi có thể kiểm tra các loại thông điệp MQ là 1 = Request (-reply) hoặc 8 = datagram (một chiều!). Việc xây dựng kiểm tra và trả lời đó không được minh họa ở đây.

Sau đó, chúng tôi thực thi EIP thành InOnly trong lần đăng tiếp theo tới JMS thuần túy để nhất quán với chế độ MQ đến.

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

Điều này kết thúc lộ trình MQ-to-jms; tiếp theo là tuyến đường jms-to-MQ vẫn còn trong cùng một ngữ cảnh 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"/--> 

Bây giờ đến cờ yêu cầu cho báo cáo MQ CoD được trả về bằng đích từ xa. Chúng tôi cũng thực thi thông báo MQ là loại Datagram (giá trị 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> 

Hàng đợi Trả lời có thể được chỉ định hoặc thông qua tùy chọn Trả lời uri, dưới dạng tiêu đề như bên dưới.

Tiếp theo, chúng tôi sử dụng tiêu đề CamelJmsDestinationName để thực thi triệt tiêu tiêu đề thư JMS MQ MQRFH2 (sử dụng giá trị tùy chọn URL targetClient MQ 1). Nói cách khác, chúng tôi muốn gửi một thông điệp nhị phân milla thuần túy (nghĩa là chỉ mô tả thông điệp MQMD tiếp theo là tải trọng).

<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> 

Các trường MQMD khác có thể được kiểm soát thông qua các thuộc tính JMS được đặt trước như minh họa bên dưới. Xem các hạn chế trong tài liệu của 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> 

Hàng đợi đích trong URI bị ghi đè bởi CamelJmsDestinationName ở trên, do đó tên hàng đợi trong URI trở thành trình giữ chỗ.

Tùy chọn URI preserveMessageQos là tùy chọn - như đã quan sát - cho phép gửi thư có dữ liệu ReplyTo (để nhận Báo cáo CoD MQ), nhưng ngăn CAMEL khởi tạo trình nghe tin nhắn Trả lời bằng cách thực thi 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> 

Chúng tôi đã không hoàn thành, chúng tôi có vẫn tuyên bố các nhà máy hàng đợi của chúng tôi cho cả nhà cung cấp JMS bản địa và Websphere MQ (thông qua JCA Resource Adaptor nguồn gốc IBM WMQ), phải được điều chỉnh để hoàn cảnh của bạn. Chúng tôi sử dụng ở đây tra cứu JNDI về các đối tượng hành chính.

<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> 

Cách khác để tìm nạp nhà máy (và bộ điều hợp JCA) từ JNDI là khai báo ứng dụng khách JMS là Spring bean. Trong Weblogic và Glassfish, bạn sẽ được truyền cảm hứng tốt hơn bằng cách triển khai bộ nguồn tài nguyên JCA của IBM và tạo tài nguyên JNDI sau đó được tham chiếu trong Ngữ cảnh mùa xuân như trên, trong JBoss khai báo hạt khách hàng MQ trực tiếp phù hợp nhất như bên dưới)

<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> 

Nhận xét và cải tiến được chào đón.

5

Tôi có sử dụng rộng rãi với IBM MQ của lạc đà. Không có vấn đề gì khi sử dụng cả hai. Tôi sẽ dán một cấu hình mẫu từ một trong các tệp ngữ cảnh mùa xuân của tôi tận dụng một điểm cuối JMS lạc đà, một nhà máy kết nối mùa xuân và một định nghĩa IBM MQ.

Camel Route

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

Spring Context

<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

Dường như không cần phải xác định thuộc tính 'queueManager' và' channel'. Chỉ định thuộc tính 'port' cũng sẽ là tùy chọn nếu trình quản lý hàng đợi có một trình lắng nghe hoạt động trên cổng mặc định '1414', phải không? Tôi nghĩ là một tác nhân giữa ứng dụng 'jms' và' ibm mq', người nghe xác định trình quản lý hàng đợi đích. Hơn nữa, về cơ bản không cần phải có bất kỳ 'kênh' nào trong trình quản lý hàng đợi đích! – faghani

Các vấn đề liên quan