Implemeting InOut Message Exchange Pattern with Apache Camel and JMS
Prerequisites
- Active MQ Broker already.
- A queue called “orders” created.
For achieve these prerequisites, just follow this story.
EIP: Request Reply
When we use Queue, the message is unidirectional, that’s means the Producer send a message to a Consumer, and done, like that:
However, in some situations, the Producer will wait for a answer from the Consumer, that is a EIP called Request Reply:
But, the problem is that a only queue can’t suport this, then we need use two queues, one for request and another to response, right flow will be some like this:
Message header: Reply To
When the Producer wait for a response, it’ll indicate using the message’s header Reply To, which will take the name of the response queue as its value.
The JMS will automatically interpret it for us, and will know which queue it needs to answer to at the end of our route.
Yeah, that’s right! Using JMS, we do not need to do anything on our code to implement this pattern.
We’ll just implement a route that consume the queue, and that’s it. Let’s do it!
Create the route
Here, we’ll create our RouteBuilder, called OrderAnswerRoute, inside a package called route:
@Component
public class OrderAnswerRoute extends RouteBuilder { @Override
public void configure() throws Exception {
from("activemq:queue:orders").
log("Pattern: ${exchange.pattern}").
end();
}}
As we see, this routing just get a message form a queue and does not anything useful, but, that’s enough for us right now.
Take a look on log() method, we’ll use this to understand that’s really happening.
Run as
Just run your application: Run as Spring Boot App.
Right clean up your Console log, and keep the app running.
ActiveMQ
Now, everything that we need do is on our message broker, so, let’s doing this on steps:
1 — Send message without Reply To header
Access the message broker (http://127.0.0.1:8161/admin)/, then:
Queues > Send To (in orders) > Put a message into the Message Body > Click on Send.
Note: I have used the same message that we have inside the folder “orders” (if you had followed the previous story, you can do the same.)
On console log, will be appear:
2020-09-13 15:05:22.068 INFO 11720 --- [onsumer[orders]] route1 : Pattern: InOnly
Keep in our mind the “InOnly”, and, move on to the next step.
2 — Create a answer queue
Now, we’ll create a 2nd queue called “orders.answer”, to get the response from the consumer.
Just create it, and move on.
3 — Send message with Reply To header
After created the 2nd queue, we can see, of course, two queues, one is the “orders” and another one is the “orders.answer”.
Let’s send another message, but, now, we’ll set up the Reply To.
Queues > Send To (in orders) > Put a message into the Message Body > Put the value “orders.answer” into the “Reply To” field > Click on “Send”:
On console log, will be appear:
2020-09-13 15:23:15.759 INFO 11720 --- [onsumer[orders]] route1 : Pattern: InOut
Keep in our mind the “InOut” too, we’ll talk about that below. You can stop the application right now.
Now, reload (F5) the Admin Message Broker, and, we’ll see that we have a message on queue “orders.answer”.
To see the message: Click on “orders.answer” > then click on Message ID. As we can look, is the same message that we had sended byqueue “orders”.
InOnly x InOut
In a practical way, we saw what happened on our route when we set up the Reply To.
This happens because the Apache Camel detects the header Reply To on JMS message and gives it back the route’s return to the queue “orders.answer”.
To be clear, the Apache Camel change the Exchange Pattern from InOnly to InOut:
See more about Message Echange Patterns.
In our example the route is pretty simple, but, if we have a very complex route that do many processing, requesting, transforming, etc., at the end of all, the Apache Camel will send a return to the answer queue.
Conclusion
When we need to uncouple the systems in a async way but the Producer need to get the response for any reason, this pattern is very useful.
Here, we have used the Apache ActiveMQ, but, in enterprise ecosystem the most common is use the IBM Websphere MQ. And the good news is that this is indifferent to us, the JMS absorve that.
As well it is common that the message broker to be running on cluster, that’s indifferent too, because in this case, the right instance will be indicate on Reply To.
The source code is on Github: https://github.com/thiagoericson/camel-project.
If you have any questions, please, let me know!
Regards.