Search code examples
apache-camelactivemq-artemisspring-camel

JMSReplyTo - How to create a generic camel route for VM/Artemis/IBM MQ


I have the following service.

  • Spring boot 2.5.13
  • Camel 3.18.0
  • JMS

I want to use an embedded ActiveMQ Artemis, standalone ActiveMQ Artemis, and IBM MQ.

I've managed to get all 3 running and connecting, but one thing I cant figure out is the JMSReplyTo option.

Running locally with embedded broker:

This runs fine. I can write a message to the queue and a response is send to the JMSReplyTo:

public void sendRequest(){
    ActiveMQQueue activeMQQueue = new ActiveMQQueue("RESPONSE_QUEUE");
    jmsTemplate.convertAndSend("REQUEST_QUEUE", "Hello", pp -> {
        pp.setJMSReplyTo(activeMQQueue);
        return pp;
    });
}

Via ActiveMQ Artemis console:

This is where the inconstancy comes as the Object received is an ActiveMQDestination which makes setting the CamelJmsDestination much more involved.

Am I wasting my time here? Should I just grab the queue name and construct the uri manually? Or I am missing some logic as to how this works? Or maybe I'm not using the Artemis console in the correct way?

.setExchangePattern(ExchangePattern.InOut)
.setHeader("CamelJmsDestination", header("JMSReplyTo"))

ActiveMQ Artemis Console. Send message


Solution

  • When using javax.jms.Message#setJMSReplyTo(Destination) you have to pass a javax.jms.Destination which must implement one of the following:

    • javax.jms.Queue
    • javax.jms.TemporaryQueue
    • javax.jms.Topic
    • javax.jms.TemporaryTopic

    In order to reproduce this semantic via text in the web console of ActiveMQ Artemis you need to prefix your destination's name with one of the following respectively:

    • queue://
    • temp-queue://
    • topic://
    • temp-topic://

    So when you set the JMSReplyTo header try using queue://RESPONSE_QUEUE.

    When your application then receives this message and invokes getJMSReplyTo() it will receive a javax.jms.Queue implementation (i.e. ActiveMQQueue) and then you can use getQueueName() to get the String name of the queue if necessary.