1

Camel route1 is used to send a message to route2, which does process the message and in the middle of the processing sends reply back to route1 but will continue processing. How would you implement this pattern?

Considering few options here:

Option 1

Please refer this diagram:

diagram.

Here's how I've currently tested to do this.

<route id="route1">
    <from uri="direct:test-queue" />
    <log message="Start test. Body :: ${body}" />
    <setHeader headerName="JMSCorrelationID">
        <constant>JMS_TEST</constant>
    </setHeader>
    <to uri="activemq:queue:jms.test.queue.request?
             replyToType=Exclusive
        &amp;replyTo=jms.test.queue.reply
        &amp;useMessageIDAsCorrelationID=false" pattern="InOut" />
    <log message="Body is now :: ${body}" />
</route>

<route id="route2">
    <from uri="activemq:queue:jms.test.queue.request" />
    <setBody>
        <constant>TEST! (Correct body).</constant>
    </setBody>
    <to uri="activemq:queue:jms.test.queue.reply" pattern="InOnly" />
    <setBody>
         <constant>Wrong body...</constant>
    </setBody>
    <log message="Continue processing..." />
</route>

This seems to work, but gives a warning:

QueueReplyManager - org.apache.camel.camel-jms - 2.16.2 | Reply received for 
unknown correlationID [JMS_TEST] 
on reply destination [queue://jms.test.queue.reply]. Current correlation map 
size: 0. The message will be ignored: 
ActiveMQTextMessage {commandId = 4175, responseRequired = true, messageId = 
<cut> text = Wrong body...}

When route2 reaches at end, it also sends new reply to reply-channel, which causes the warning.

Better way to do this? I guess this is not doable without warning with camel-jms, since the JMSReplyTo cannot be dynamically changed.

Option 2

A similar, but not the same question was asked here here. The difference is that in there the route2 should stop routing on certain condition. The offered solution does not apply here because it creates a new thread. The problem is that if route2 is called (e.g. by routeX) then the caller does not get the expected reply from route3. This could be still used in some cases, but instead of wiretap I'd prefer ActiveMQ since it serializes/deserializes the object, thus creating deep copy for free. With wiretap the onPrepareRef should be first implemented to create a deep copy. See diagram below:

new thread

Option 3:

There's yet another way to do this. It requires more work, but offers full control. Consider the diagram below:enter image description here

I haven't implemented this option as the option 1 could work well enough. However, with this option 3 I don't see any lurking problems as the implementation is quite straightforward.

Tuomas
  • 93
  • 9
  • You can check my answer to similar question. https://stackoverflow.com/questions/34617646/return-back-from-current-route-in-apache-camel-and-continue-routing/34619346#34619346 – Vyacheslav Enis Jun 06 '17 at 14:35
  • Possible duplicate of [return back from current route in Apache Camel and continue routing](https://stackoverflow.com/questions/34617646/return-back-from-current-route-in-apache-camel-and-continue-routing) – Vyacheslav Enis Jun 06 '17 at 14:35
  • I wold more or less go with your #1 but to send the reply from 1 to 2, inject a new message with sendtemplatebody as the reply and let the original exchange continue. You need to change the pattern to inOnly since you're not really using the jms reply-to functionality. – Steve Huston Jun 07 '17 at 15:21

0 Answers0