【问题标题】:Apache Camel -- Websphere MQ integrationApache Camel——Websphere MQ 集成
【发布时间】:2018-02-10 01:16:07
【问题描述】:

我有一个使用 apache-camel 解决方案的应用程序,想通过 jms 向 Websphere MQ 服务器发送消息,将 jms 属性 JMS_IBM_MQMD_MsgId 转换为 MQMD 字段 MQMD.MsgId,以便我通过骆驼在消息上设置此值

exchange.getIn().setHeader(WMQConstants.JMS_IBM_MQMD_MSGID, "XXXXXXXXXXXXXXXXXXXXXXXX".getBytes());

根据Apache Camel - IBM MQ integration,似乎我们需要在目标对象上设置另一个属性。参考http://camel.apache.org/jms.html上的Setting JMS Provider Options on the Destination,我为camel jms组件提供了一个自定义的DestinationResolver,为目标对象设置mdWriteEnabledmdReadEnabled

<bean id="ibmMQServer01" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="ibmMQCredentialConnectionFactory01" />
    <property name="destinationResolver" ref="wmqDestinationResolver" />
</bean>

public class WMQDestinationResolver implements DestinationResolver {
    @Override
    public Destination resolveDestinationName(Session session, String destinationName, 
            boolean pubSubDomain) throws JMSException {
        MQSession mqSession = (MQSession) session;
        MQQueue queue = (MQQueue) mqSession.createQueue("queue:///" + destinationName);
        queue.setBooleanProperty(WMQConstants.WMQ_MQMD_WRITE_ENABLED, true);
        queue.setBooleanProperty(WMQConstants.WMQ_MQMD_READ_ENABLED, true);
        queue.setIntProperty(WMQConstants.WMQ_MQMD_MESSAGE_CONTEXT, WMQConstants.WMQ_MDCTX_SET_ALL_CONTEXT);
        return queue;
    }
}

我可以在接收器上获得JMS_IBM_MQMD_MsgId,同时设置mdReadEnabled 等于真。但是,mdWriteEnabled 似乎对我不起作用,我得到了 JMS_IBM_MQMD_MsgId 作为意外值 AMQ CS.QA.CBSA.Q�Y�b(从 byte[] 解析,共 24 个字节)。

接收到的JMSMessageIDID:414d512043532e51412e434253412e511987055902cc6222,可以解析成上面乱七八糟的字符串。

【问题讨论】:

    标签: apache-camel jms ibm-mq


    【解决方案1】:

    我钻取骆驼代码并找到根本原因

    在设置 jms 属性时,它会运行 org.apache.camel.component.jms.JmsBinding 的方法 getValidJMSHeaderValue

    protected Object getValidJMSHeaderValue(String headerName, Object headerValue) {
        if (headerValue instanceof String) {
            return headerValue;
        } else if (headerValue instanceof BigInteger) {
            return headerValue.toString();
        } else if (headerValue instanceof BigDecimal) {
            return headerValue.toString();
        } else if (headerValue instanceof Number) {
            return headerValue;
        } else if (headerValue instanceof Character) {
            return headerValue;
        } else if (headerValue instanceof CharSequence) {
            return headerValue.toString();
        } else if (headerValue instanceof Boolean) {
            return headerValue;
        } else if (headerValue instanceof Date) {
            return headerValue.toString();
        }
        return null;
    }
    

    似乎骆驼拒绝字节数组值并返回null,因此jms提供者无法应用JMS_IBM_MQMD_MsgId的属性。我重写了这个方法来解决它。

    注意:我只是在源文件夹src/main/java 中创建了相同的类org.apache.camel.component.jms.JmsBinding,类加载器会默认加载这个类而不是 maven 库中的类。

    【讨论】:

    • 有没有办法向 Apache Camel 提交错误报告,以便在上游处理这个问题?
    【解决方案2】:

    我可以在设置 mdReadEnabled 时在接收器上获取 JMS_IBM_MQMD_MsgId 等于真。但是, mdWriteEnabled 似乎对我不起作用,我得到了 JMS_IBM_MQMD_MsgId 作为意外值“AMQ CS.QA.CBSA.Q�Y�b” (由byte[]解析而来,共24个字节)。

    收到的 JMSMessageID 是 “ID:414d512043532e51412e434253412e511987055902cc6222”,可以是 解析成上面乱七八糟的字符串。

    你看到的是正确的。 MsgId 是一个 24 字节的字节数组。它由字符串和二进制值组成。因此,您不能将其用作字符串。

    【讨论】:

      猜你喜欢
      • 2018-02-08
      • 2018-06-27
      • 2016-11-23
      • 2015-03-05
      • 2016-05-05
      • 2011-02-07
      • 1970-01-01
      • 2011-12-05
      • 2012-09-30
      相关资源
      最近更新 更多