Search code examples
apache-cameljms

Replicating AMQ Admin UI move functionality in Camel


In the Hawtio ActiveMQ plugin there is functionality to move messages from one queue to another. This process keeps the body and all the headers all the same as the original message.

Is there a way to do this in Camel? A simple from(queue1).to(queue2) always seems to change headers.

edit: tried

from(
            "cMQConnectionFactory1:queue:queue1"
                    + "?forceSendOriginalMessage=" + true
                    + "&mapJmsMessage=" + false)
            .routeId("testMove_cJMS_1")
            .to("cMQConnectionFactory1:queue:queue2"
                    + "?forceSendOriginalMessage=" + true
                    + "&mapJmsMessage=" + false).id("testMove_cJMS_2");
}` 

Solution

  • The Camel documentation for the JMS component describes the forceSendOriginalMessage option saying:

    When using mapJmsMessage=false Camel will create a new JMS message to send to a new JMS destination if you touch the headers (get or set) during the route. Set this option to true to force Camel to send the original JMS message that was received.

    forceSendOriginalMessage defaults to false.

    The docs say this about mapJmsMessage:

    Specifies whether Camel should auto map the received JMS message to a suited payload type, such as javax.jms.TextMessage to a String etc.

    mapJmsMessage defaults to true.

    Therefore it seems like you need to set mapJmsMessage=false & forceSendOriginalMessage=true.

    Keep in mind that Camel will be using the JMS API to consume the message and then resend it. Even though the new message will have the same body and headers as the old message it will be slightly different because the JMS specification dictates that when a message is sent the broker must assign it a message ID and timestamp. Therefore the JMSMessageID and JMSTimestamp on the new message will be different from the old message, and there's really no way around that. If you need to identify the message uniquely you should set the correlation ID on the original message and use that to identify the message rather than the JMSMessageID. Also, if you need to preserve the original time the message was sent then set that in a custom property.

    The reason the JMSMessageID and JMSTimestamp are not changed when moving the messages via the management console is because the broker moves the messages internally with a completely different mechanism than JMS.