将amqp消息发送到ibm mq

时间:2019-04-08 09:07:59

标签: spring-integration ibm-mq

尝试将消息从RabbitMQ <int-amqp:inbound-channel-adapter传输到MQSeries <int-jms:outbound-channel-adapter。效果很好。

实际上,MQSeries上的一些生产者使用这样的IBM JMS类:

MQMessage messageMQ = new MQMessage();
messageMQ.format = "        ";
messageMQ.persistence = 1;
messageMQ.correlationId = MQ_MESSAGE_CORRELATION_ID;
messageMQ.write(message.getMessageData());
MQPutMessageOptions putMessageOption = new MQPutMessageOptions();
putMessageOption.options = 8194;
MQQueue queue = openQueue(destinataire, 8208);
queue.put(messageMQ, putMessageOption);

我尝试在amqp和jms之间使用变压器,如下所示:

<int:transformer id="testTransformer" ref="testTransformerBean" input-channel="fromRabbit"
         method="transform" output-channel="toJms"/>


public MQMessage transform(Message<?> msg) throws Exception {

    MQMessage result = new MQMessage();
    result.format = "        ";
    result.persistence = 1;
    result.correlationId = MQC.MQCI_NONE;

    String test = "message to send ";
    result.write(test.getBytes());
    return result;
}

msg.getPayload()中存储的对象的类型是什么?如何将其转换为String对象?

实施此方法,我有一个例外,因为出站需要JMS消息,而不是com.ibm.mq.MQMessage!

Cannot convert object of type [com.ibm.mq.MQMessage] to JMS message

这样正确吗?

还是我应该删除出站通道并使用服务激活程序代替IBM的特定代码?

感谢您的帮助

致谢

按照Artem的答案进行编辑

遵循jms出站配置:

<bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory">
    <property name="queueManager" value="${queueManager}" />
    <property name="hostName" value="${hostName}" />
    <property name="port" value="${port}" />
    <property name="channel" value="${channelName}" />
    <property name="transportType" value="1" />
</bean>
<bean id="jmsQueue" class="com.ibm.mq.jms.MQQueue" depends-on="jmsConnectionFactory">
    <property name="baseQueueManagerName" value="${queueManager}" />
    <property name="baseQueueName" value="${queueName}" />
    <property name="targetClient" value="1" />
</bean>
<bean id="jmsConnectionFactory_cred"
    class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
    <property name="targetConnectionFactory" ref="jmsConnectionFactory" />
    <property name="username" value="${user}"/> 
    <property name="password" value="${password}"/> 
</bean> 

<bean id="connectionFactoryCaching"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="jmsConnectionFactory_cred" />
    <property name="sessionCacheSize" value="${BRIDGE_MQ_OUTBOUND_SESSION_CACHE}" />
</bean>

<bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice" id="requestHandler">
    <property name="trapException" value="false"/>
    <property name="onFailureExpressionString" value="#this"/>
    <property name="failureChannel" ref="processChannel1"/>
</bean>

<int-jms:outbound-channel-adapter   channel="channelRmqMQ" 
                                    id="jmsOut" destination="jmsQueue" connection-factory="connectionFactoryCaching" delivery-persistent="true" 
                                    explicit-qos-enabled="true" session-transacted="true" >
    <int-jms:request-handler-advice-chain>
        <ref bean="requestHandler" />
    </int-jms:request-handler-advice-chain>                                         
</int-jms:outbound-channel-adapter>

1 个答案:

答案 0 :(得分:0)

If your AMQP message comes with the text/* contentType, then its body is converted to string automatically by the out-of-the-box SimpleMessageConverter in the AmqpInboundChannelAdapter:

     if (contentType != null && contentType.startsWith("text")) {
            String encoding = properties.getContentEncoding();
            if (encoding == null) {
                encoding = this.defaultCharset;
            }

            try {
                content = new String(message.getBody(), encoding);
            } catch (UnsupportedEncodingException var8) {
                throw new MessageConversionException("failed to convert text-based Message content", var8);
            }

Otherwise you need to place a simple transformer in between to convert a byte[] to string:

<object-to-string-transformer>

The <int-jms:outbound-channel-adapter> is exactly for JMS protocol interaction, so, your MQMessage is not going to be accepted there. That's why you get that Cannot convert object of type [com.ibm.mq.MQMessage] to JMS message exception.

Yes, you can use IBM MP API directly in some custom service-activator, however I would suggest to take a look into JMS to MQ bridge on IBM WebSphere. Then you need only to configure an appropriate connection factory and use it from the <int-jms:outbound-channel-adapter>:

<jee:jndi-lookup id="jndiMqConnectionFactory" jndi-name="${mqConnectionFactory}"/>

<bean id="jmsQueueConnectionFactory"
          class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
        <property name="targetConnectionFactory" ref="jndiMqConnectionFactory"/>
        <property name="username" value="${mqLogin}"/>
        <property name="password" value="${mqPassword}"/>
    </bean>

<jee:jndi-lookup id="myMqQueue" jndi-name="queue/myMqQueue"/>

<bean id="mqQueueJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
    <property name="defaultDestination" ref="myMqQueue"/>
</bean>

<jms:outbound-channel-adapter channel="myMqChannel" jms-template="mqQueueJmsTemplate"/>