寻找Apache Camel和IBM MQ之间集成的一些示例。
Apache camel充当MQ和我们基于java的套接字应用程序之间的中间件路由器。
答案 0 :(得分:2)
您应该在组件扫描包中定义一个JmsComponent bean,并为其提供所有连接工厂属性,并在路由中使用该bean。 例如:
@Bean
public JmsComponent ibmmq(){
JmsComponent ibmmq = new JmsComponent();
MQTopicConnectionFactory factory = new MQTopicConnectionFactory();
factory.setQueueManager("yyy"); //yyy is you QueueManager
factory.setHostName("zzz"); //zzz is your host
factory.setPort(111);
factory.setTransportType(1);
ibmmq.setConnectionFactory(factory);
return ibmmq;
}
在您的路线中添加以下内容
camelContext.addRoutes(
new RouteBuilder()
{
@Override
public void configure() throws Exception
{
from("ibmmq:topic:YY.ZZZ").to("stream:out"); //YY.ZZZ is your topic name. If Queue use ibmmq:queue:YY.ZZZ.
}
});
如果您正在使用" stream:out "请在依赖项和camel-stream中使用camel-jms和IBM MQ库。测试。
答案 1 :(得分:0)
答案 2 :(得分:0)
下面记录了我能够获得的最好的结果,说明为Spring XML应用程序上下文,它本身托管CAMEL上下文和路由。此示例适用于IBM本机MQ JCA兼容资源适配器v7.5,CAMEL 2.16,Spring core 4.2。我已将它部署在Glassfish,Weblogic和JBoss EAP7服务器中。
复杂性必然会处理MQ报告的流程,这些报告的哲学与普通JMS回复消息的哲学冲突。有关详细说明,请参阅Implementing native websphere MQ with CoD over Camel JMS component
这个基于CAMEL XML DSL的示例是独立的,易于测试。
我们从Spring& 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">
CAMEL上下文有两条路由:MQ到JMS和JMS到MQ,这里链接形成一个桥梁以便于测试。
<camel:camelContext id="mqBridgeCtxt">
<camel:route id="mq2jms" autoStartup="true">
很奇怪:在Weblogic上,获得(例如)3个侦听器的唯一方法是强制执行3个连接(3个Camel:来自语句中的语句),每个连接最多1个会话,否则会发生MQ错误:MQJCA1018:只有一个会话每个连接是允许的。在JBoss上,您可以简单地调整concurrentConsumers = ...
<camel:from uri="wmq:queue:TEST.Q1?concurrentConsumers=1&disableReplyTo=true&
acknowledgementModeName=SESSION_TRANSACTED"/>
上面的disable disableReplyTo选项确保CAMEL在我们可以测试MQ消息类型为1 = Request(-reply)或8 = datagram(单向!)之前不会产生回复。这里没有说明测试和回复结构。
然后我们在下一个发布到普通JMS时强制执行EIP到InOnly以与入站MQ模式保持一致。
<camel:setExchangePattern pattern="InOnly"/>
<!-- camel:process ref="reference to your MQ message processing bean fits here" / -->
<camel:to uri="ref:innerQueue" />
</camel:route>
这结束了MQ-to-jms路由;接下来,jms-to-MQ路由仍处于相同的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" / -->
现在,远程目标返回MQ CoD报告的请求标志。我们还将MQ消息强制为数据报类型(值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>
可以通过ReplyTo uri选项指定ReplyTo队列,否则作为标题指定。
接下来,我们使用CamelJmsDestinationName标头来强制抑制JMS MQ消息头MQRFH2(使用targetClient MQ URL选项值1)。换句话说,我们希望发送一个简单的vanilla MQ二进制消息(即只有MQMD消息描述符,后跟有效负载)。
<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>
可以通过保留的JMS属性控制更多MQMD字段,如下所示。请参阅IBM doc。
中的限制 <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>
URI中的目标队列被上面的CamelJmsDestinationName覆盖,因此URI中的队列名称成为占位符。
URI选项preserveMessageQos是一个 - 如所观察到的 - 允许发送一条消息,其中设置了ReplyTo数据(以获取MQ CoD报告),但阻止CAMEL通过强制执行InOnly MEP来实例化一个Reply消息监听器。 / p>
<camel:to uri="wmq:queue:PLACEHOLDER.Q.NAME?concurrentConsumers=1&
exchangePattern=InOnly&preserveMessageQos=true&
includeSentJMSMessageID=true" />
</camel:route>
</camel:camelContext>
我们还没有完成,我们仍然要为本机JMS提供程序和Websphere MQ(通过本机IBM WMQ JCA资源适配器)声明我们的队列工厂,以根据您的上下文进行调整。我们在这里使用管理对象的JNDI查找。
<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>
从JNDI获取工厂(和JCA适配器)的替代方法是将JMS客户端声明为Spring bean。在Weblogic和Glassfish中,通过部署本机IBM JCA资源适配器并创建随后在Spring Context中引用的JNDI资源,您将获得更好的启发,在JBoss中,直接MQ客户端bean声明最适合,如下所示)
<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>
欢迎评论和改进。
答案 3 :(得分:0)
我是使用带有MQConnectionFactory的JmsComponent完成的,这是我的代码:
@Bean(name = "wmq")
public JmsComponent wmq() throws JMSException {
JmsComponent wmq = new JmsComponent();
MQConnectionFactory mqConnectionFactory = new MQConnectionFactory();
mqConnectionFactory.setTransportType(1);
mqConnectionFactory.setHostName("localhost");
mqConnectionFactory.setPort(1414);
mqConnectionFactory.setQueueManager("QMGRSCORE");
mqConnectionFactory.setChannel("EXTAPP.SRVCONN");
wmq.setConnectionFactory(mqConnectionFactory);
return wmq;
}
在我的路线中,我这样说:
from("wmq:queue:myqueue").id("myMq")