Spring Integration - How to create the adapters programmatically? - java

I am implementing spring-integration based application where i need to send messages (POJO) to ActiveMQ queues dynamically (based on message params). What is the best way to implement this using spring integration concepts ?
E.g., The request message (id:123, processor:ABC) should be sent to ABC.REQUEST queue and response message should be received from ABC.RESPONSE queue. Similarly the request message (id:456, processor:XYZ) should be sent to XYZ.REQUEST queue and response message should be received from XYZ.RESPONSE queue.

You don't need to programmatically create them programmatically, you can use dynamic destinations.
See request-destination-expression and reply-destination-expression in the documentation.
Something like...
request-destination-expression="payload.processor + '.REQUEST'"
reply-destination-expression="payload.processor + '.RESPONSE'"
...should do it.

Related

How to handle response timeout in activeMq when using two queues for communication between two applications

Say you have an Application A and an Application B that communicates together using ActiveMQ queues. The communication happens as below.
A sends a request message to application B using the queue name
com.example.requestQueue
B consumes the message request from the queue name com.example.requestQueue
B takes some time to handle the message request and then sends a
response back to B using the response queue
name com.example.responseQueue
A consumes the response message from com.example.responseQueue queue and is done
If application B is always answering, there is no problem. 
But if for some reason the application B consumes a message from the request queue com.example.requestQueue and never puts a response message in the response queue com.example.responseQueue, application A will wait forever. 
Is there any way to solve this kind of problem please?
NB: The application A is written with Java and Camel and the application B is Written in C++
Thanks.
Camel supports request-reply flows in a single route (exchange pattern InOut), or you can break the request-reply into two separate routes (both exchange pattern InOnly) depending on your use case.
The request-reply patterns have timeout settings available based on the Camel component used. Add the timeout to the Application A Camel route request-reply.
ref: SJMS Component - Newer JMS component
ref: JMS Component - Original JMS component
ref: Request Reply pattern - Info on InOut patterns
Side note--
If Application A is also expected to return something to a caller (ie a web app or a REST/SOAP client), than you would want to make sure you set the messaging response timeout to be lower than than the timeout used by the caller. This allows Application A to return a proper exception/error to the caller before the caller's timeout occurs.

How to pass the destination value from many message driven channel adapter to common inbound channel in spring integration

Having the following requirement, where we have many message driven channel adapter to consume messages from a different WMQ's and send it to common outbound channel.
I need the detail of message adapter that consumes the message to handle the business scenarios.
Any help is appreciated.
First of all no one in the Spring Integration sends directly to the inbound channel. Let's hope you mean a common outbound channel adapter.
There is not too much out-of-the-box information about a message driven channel adapter in the messages it emits. Maximum what you can do is to enable Message History - and the message will have an id of components it travels through.
If you need more info, I suggest to place a Header Enricher just after each message driven channel adapter and populate a required information from there.

Camel route - get JMSMessageId after sent

How can I get JMSMessageID in camel route producer (with Spring context),
JMSMessageID needs to be generated by MQ server, like it works with native JMS.
In the camel's documentation
JMSMessageID is in section "consumer",
"Camel adds the following JMS properties to the In message headers when it receives a JMS message",
but I need it from producer side after send.
I can's use tmpReply queue with camel's InOut.
I suppose, I need to use MessagePostProcessor, or MessageSentCallback, but I don't know how.
Thanks a lot!
This works for me:
from("someRoute")
.to("jms://OUTPUT.QUEUE?includeSentJMSMessageID")
.log("JMSMessageID = ${header.JMSMessageID}");

RabbitMQ RPC tutorial query

I was going through the tutorial shared by RabbitMQ here
I am assuming that the client code below
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
if (ea.BasicProperties.CorrelationId == corrId)
{
return Encoding.UTF8.GetString(ea.Body);
}
}
Would receive all messages on the queue and will unnecessarily iterate through messages not designated for it. Is their anyway we can avoid it i.e we can modify the client to only receive the messages intended for it only.
The basic work that i intend to achieve through RabbitMQ is Request-Response pattern where a request would be received by web-service which will send data in a queue the data object would have a unique reference number . This would be received by an asynchronous tcp-client which will send data on a tcp/ip layer based on message it had received.
On receiving reply from the asynchronous channel of tcp/ip the channel would parse the data and respond back on the queue with the corresponding request reference number.
The RPC approach is well suited for it but the client code shared have this shortcoming would appreciate feedback on it.
Actually I didn’t understand well your aim, but when you create an RPC model, you have to create an “reply queue”, this queue is bound only to the client.
It means that you will receive back only the client messages, and not all messages.
Since the Rabbitmq RPC model is asynchronous you can execute more than one request without wait the responses and replies could not have the same publish order.
The correlation id is necessary to map your client requests with the replies, so there are not "unnecessarily" messages
hope it helps

How to make a JMS Synchronous request

I have an webapp that is expected to fetch and display data from an External App which is accessible only via messaging (JMS).
So, if a user submits a request on a browser, the same HTTP request thread will have to interact with the Messaging system (MQ Series) such that the same request thread can display the data received from the Messaging System.
Is there a pattern I can make use of here? I saw some vague references on the net that use "Correlation ID" in this way:
Msg m = new TextMsg("findDataXYZ");
String cr_id = m.setCorrelationID(id);
sendQueue.send(m).
// now start listening to the Queue for a msg that bears that specific cr_id
Response r = receiverQueue.receive(cr_id);
Is there something better out there? The other patterns I found expect the response to be received asynchronously.. which is not an option for me, since I have to send the response back on the same HTTP request.
The request/reply messaging pattern is useful for your requirement. You typically use a CorrelationId to relate request & reply messages.
While sending request message you set JMSReplyTo destination on the message. Typically a temporary queue is used as JMSReplyTo destination. When creating a consumer to receive response use a selector with JMSCorrelationId, something like
cons = session.createConsumer(tempDestination,"JMSCorrelationId="+requestMsg.JMSMessageId);
At the other end, the application that is processing the request message must use the JMSReplyTo destination to send response. It must also use the MessageId of the request message and set it as CorrelationId of the response message.
First, open the response queue. Then pass that object to the set reply-to method on the message. That way the service responding to your request knows where to send the reply. Typically the service will copy the message ID to the correlation ID field so when you send the message, take the message ID you get back and use that to listen on the reply queue. Of course if you use a dynamic reply-to queue even that isn't neessary - just listen for the next message on the queue.
There's sample code that shows all of this. If you installed to the default location, the sample code lives at "C:\Program Files (x86)\IBM\WebSphere MQ\tools\jms\samples\simple\SimpleRequestor.java" on a Windows box or /var/mqm/toolsjms/samples/simple/SimpleRequestor.java on a *nix box.
And on the off chance you are wondering "install what, exactly?" the WMQ client install is downloadable for free as SupportPac MQC71.

Categories