【问题标题】:How to stop WSO2 passing ActiveMQ CorrelationID directly to Websphere MQ如何阻止 WSO2 将 ActiveMQ CorrelationID 直接传递给 Websphere MQ
【发布时间】:2013-03-08 02:39:48
【问题描述】:

我正在尝试从 ActiveMQ 队列中提取消息并将其传递给 Websphere MQ 队列。

我正在使用 WSO2,因为最终我们会想要使用它提供给我们的所有功能。

问题似乎是 WSO2 尝试将 ActiveMQ MessageId 作为 Correlation Id 直接传递给 Websphere MQ - 格式错误。

我试图删除 TRANSPORT_HEADERS,但我一定是做错了什么。

我在 inSequence 中添加了一个虚拟属性 JMS_CORRELATION_ID(根据 post)来查看我是否可以验证这一点,但 Websphere MQ 似乎无法识别此标头。

很高兴将消息从 Websphere MQ 传递到 ActiveMQ 在我创建的另一个代理服务中工作正常。在这种情况下,Websphere MQ 消息 ID 被传递给 Active MQ 相关 ID。

这是个例外

[2013-03-08 12:18:23,414] ERROR - JMSSender Error creating a JMS message from the message context
com.ibm.msg.client.jms.DetailedJMSException: JMSCMQ1044: String is not a valid hexadecimal number - 'dolguldur-51590-1362693989456-3:4:1:1:4'.
Either an attempt was made to specify a group ID or correlation ID which starts with the prefix ID but is not followed by a well-formed hexadecimal value, or an attempt was made to receive a message w
hich contains an MQRFH2 property of type bin.hex that does not have a well-formed hexadecimal value.
Ensure that a valid hexadecimal value always follows the ID prefix when setting group ID or correlation ID values. Ensure that any MQRFH2 headers generated by non-JMS applications are well-formed.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
        at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
        at com.ibm.msg.client.wmq.common.internal.WMQUtils.hexToBin(WMQUtils.java:414)
        at com.ibm.msg.client.wmq.common.internal.WMQUtils.stringToId(WMQUtils.java:496)
        at com.ibm.msg.client.wmq.common.internal.messages.WMQMessageHeader.setJMSCorrelationID(WMQMessageHeader.java:314)
        at com.ibm.msg.client.jms.internal.JmsMessageImpl.setJMSCorrelationID(JmsMessageImpl.java:610)
        at com.ibm.jms.JMSMessage.setJMSCorrelationID(JMSMessage.java:1133)
        at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:428)
        at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:172)
        at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:154)
        at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
        at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
[2013-03-08 12:18:23,417]  INFO - AxisEngine [MessageContext: logID=a7a3184cd19f3b5ab7a012af40cd7840329dd8fc40d0e9c3] Error creating a JMS message from the message context

WSO2 代理服务配置

<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestService" transports="jms" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <property name="TRANSPORT_HEADERS" scope="transport" action="remove"/>
         <property name="OUT_ONLY" value="true"/>
         <log level="full"/>
      </inSequence>
      <endpoint>
         <address uri="jms:/QUEUE.OUT?transport.jms.ConnectionFactory=ibmMQQueueConnectionFactory"/>
      </endpoint>
   </target>
   <parameter name="transport.jms.ConnectionFactory">activeMQQueueConnectionFactory</parameter>
   <parameter name="transport.jms.Destination">TESTJMS.IN</parameter>
   <description></description>
</proxy>

axis2.xml 传输接收器

  <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
        <parameter name="activeMQQueueConnectionFactory" locked="false">
            <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
            <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
            <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
        </parameter>

        <parameter name="ibmMQQueueConnectionFactory" locked="false">
            <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
            <parameter name="java.naming.provider.url" locked="false">file:/E:/work/MQ-JNDI-Directory</parameter>
            <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">ConnectionFactoryTest</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
        </parameter>

    </transportReceiver>

axis2.xml 传输发送者

org.apache.activemq.jndi.ActiveMQInitialContextFactory tcp://localhost:61616 队列连接工厂 队列

<parameter name="ibmMQQueueConnectionFactory" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">file:/E:/work/MQ-JNDI-Directory</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">ConnectionFactoryTest</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>

干杯, 史蒂夫

11/3 更多信息

因此,当我在 ActiveMQ 消息中放置一个简单字符串等相关 ID 时,我似乎没有收到错误“JMSCMQ1044:字符串不是有效的十六进制数”。

所以从活动 MQ 到 Websphere MQ 相关 Id 的映射是有问题的。

但这是我现在得到的错误 - 看起来类 org.apache.axis2.transport.jms.JMSUtils 正在尝试设置 JMS_DESTINATION 标头而 Websphere MQ 不允许这样做?

我已经通过编写一个简单的 java 客户端验证了这一点,并尝试设置标头 JMS_DESTINATION,但我从 Websphere MQ 收到了同样的错误。

我可以让 Websphere MQ 处理这些标头吗?还是让 JMSSender 以不同的方式发布消息?还是 org.apache.axis2.transport.jms.JMSSender 根本不能与 Websphere MQ 一起使用?

顺便说一下,我正在使用最新的 Websphere MQ 7.5。

[2013-03-11 09:33:20,378] DEBUG - JMSMessageReceiver Received new JMS message for service :TestService
Destination    : queue://TESTJMS.IN
Message ID     : ID:dolguldur-50398-1362951749472-3:2:1:1:24
Correlation ID : NONE
ReplyTo        : null
Redelivery ?   : false
Priority       : 0
Expiration     : 0
Timestamp      : 1362958400374
Message Type   :
Persistent ?   : false
[2013-03-11 09:33:20,380] TRACE - JMSMessageReceiver
Message : Enter some text here for the message body...
[2013-03-11 09:33:20,381]  INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:dolguldur-50398-1362951749472-3:2:1:1:24, Direction: request, Envelope: <?xml version=
'1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><axis2ns5:text xmlns:axis2ns5="http://ws.apache.org/commons/ns/payload">Enter some tex
t here for the message body...</axis2ns5:text></soapenv:Body></soapenv:Envelope>
[2013-03-11 09:33:20,388] DEBUG - JMSConnectionFactory Creating a new JMS Session from JMS CF : ibmMQQueueConnectionFactory
[2013-03-11 09:33:20,392] DEBUG - JMSConnectionFactory Creating a new JMS MessageProducer from JMS CF : ibmMQQueueConnectionFactory
[2013-03-11 09:33:20,393] ERROR - JMSSender Error creating a JMS message from the message context
com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0050: The property name 'JMS_DESTINATION' is reserved and cannot be set.
The supplied property name begins with the JMS prefix, but is not one of the supported, settable properties.
Check the property name and correct errors.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
        at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
        at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:109)
        at com.ibm.msg.client.jms.internal.JmsMessageImpl.checkSettablePropertyName(JmsMessageImpl.java:2125)
        at com.ibm.msg.client.jms.internal.JmsMessageImpl.setStringProperty(JmsMessageImpl.java:1560)
        at com.ibm.jms.JMSMessage.setStringProperty(JMSMessage.java:1496)
        at org.apache.axis2.transport.jms.JMSUtils.setTransportHeaders(JMSUtils.java:278)
        at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:441)
        at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:172)
        at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:154)
        at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
        at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
[2013-03-11 09:33:20,399] ERROR - AsyncCallback Error creating a JMS message from the message context
org.apache.axis2.AxisFault: Error creating a JMS message from the message context
        at org.apache.axis2.transport.base.AbstractTransportSender.handleException(AbstractTransportSender.java:226)
        at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:174)
        at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:154)
        at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
        at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
Caused by: com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0050: The property name 'JMS_DESTINATION' is reserved and cannot be set.
The supplied property name begins with the JMS prefix, but is not one of the supported, settable properties.
Check the property name and correct errors.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
        at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
        at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:109)
        at com.ibm.msg.client.jms.internal.JmsMessageImpl.checkSettablePropertyName(JmsMessageImpl.java:2125)
        at com.ibm.msg.client.jms.internal.JmsMessageImpl.setStringProperty(JmsMessageImpl.java:1560)
        at com.ibm.jms.JMSMessage.setStringProperty(JMSMessage.java:1496)
        at org.apache.axis2.transport.jms.JMSUtils.setTransportHeaders(JMSUtils.java:278)
        at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:441)
        at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:172)
        ... 6 more

【问题讨论】:

  • 感谢您,因为 WSO2 无法根据您的帖子实际设置 MessageID,它必须设置其他内容。

标签: activemq wso2 ibm-mq


【解决方案1】:

这是因为 WebSphere MQ 遵守 JMS 规范,该规范声明消息 ID 始终由传输提供者设置。请看JMS 1.1 specification


3.4.3 JMSMessageID
JMSMessageID 标头字段包含一个唯一标识每个 提供商发送的消息。

发送消息时,将忽略 JMSMessageID。当发送方法 返回时,该字段包含一个提供者分配的值。


这已在 WMQ 信息中心主题 Mapping JMS header fields at send() or publish() 中得到证实,其中说:

从 JMS 发送的所有消息都有唯一的消息标识符,由 WebSphere® MQ。分配的值在 MQMD.MessageId 中返回 MQPUT 调用后的字段,并在 JMSMessageID 字段。 WebSphere MQ messageId 是一个 24 字节的二进制文件 值,而 JMSMessageID 是一个字符串。 JMSMessageID 是 由转换为 48 序列的二进制 messageId 值组成 十六进制字符,前缀为字符 ID:。 JMS 提供 可以设置为禁用消息生成的提示 身份标识。忽略此提示,并分配唯一标识符 在所有情况下。之前设置到 JMSMessageId 字段中的任何值 send() 被覆盖。

您可以缓存消息 ID 并在它们通过代理时关联它们,或者可以通过退出 JMS API 并使用 Java 原生 API 发送消息来完成。假设您使用的是现代版本的 WebSphere MQ,JMS 消息不再需要 RFH2 头,而是将 JMS 属性作为本机 WMQ 消息属性。这意味着在大多数情况下,JMS 应用程序可以像读取 JMS 消息一样读取本机 WMQ 消息,假设应用程序使用现代 QMgr 和 JMS 类的现代版本。

如果您需要更新,最新的 WMQ 客户端和 JMS 类位于SupportPac MQC75

【讨论】:

  • 我看到,当我通过这种方法从 IBM MQ 向 ActiveMQ 发送消息时 - IBM MQ 消息 ID 设置为 ActiveMQ 相关 ID,ActiveMQ 会创建它自己的消息 ID。
  • 所以我现在的猜测是 WSO2 正在从 Active Mq 消息 Id 填充 IBM MQ 关联 Id,并且 IBM MQ 期望关联 Id 与消息 Id 的格式相同。所以从这里我要么需要用 IBm MQ 的期望填充相关 ID,要么不填充相关 ID。
  • 听起来不错。那么你可能需要服务器端的应用程序来保存correlID,以便ActiveMQ端的东西可以找到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 2022-12-31
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多