Problem statement:
Spring amqp-outbound gateway to produce reply from a different thread (Like jms-outbound gateway, having different queue, correlate t
The correlation is done in the Spring AMQP as well. See its RabbitTemplate#sendAndRecevie()
for more info. Also there is a good documentation on the matter in the Reference Manual.
Spring Integration with its AbstractAmqpOutboundEndpoint
and AmqpInboundGateway
implementations provides out-of-the-box request-reply correlation solution. If you are not able to use AmqpInboundGateway
on the server side, you should ensure the correlationId
transfer from received request to the reply to send back. Yes, you can use dedicated exchange for replies and that is what supported by the RabbitTemplate#setQueue()
to wait for replies on the client, outbound side. But that still isn't going to work without proper correlation
transferring. Also see https://docs.spring.io/spring-integration/docs/4.3.12.RELEASE/reference/html/amqp.html#amqp-message-headers for the info how headers (including correlationId
) are mapped in Spring Integration.
UPDATE
Thank you for sharing your application.
Well, now I see several problems:
You are definitely missing the replyQueue
binding:
@Bean
public Binding bindingReply(){
return BindingBuilder.bind(this.replyQueue()).to(this.exchangeReply()).with("reply_exchange_queue");
}
RabbitTemplate
must use setReplyAddress()
. You have to configure MessageListenerContainer
for the reply_queue
and have RabbitTemplate
as a listener:
@Bean
public RabbitTemplate template(ConnectionFactory rabbitConnectionFactory){
final RabbitTemplate template = new RabbitTemplate(rabbitConnectionFactory);
template.setReplyAddress(replyQueue().getName());
return template;
}
@Bean
public MessageListenerContainer replyContainer(RabbitTemplate template) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(template.getConnectionFactory());
container.setQueues(replyQueue());
container.setMessageListener(template);
return container;
}
Your OuboundService
with org.springframework.amqp.core.Message
manipulation is useless. The Channel Adapters don't know about this type of payload
and your custom Message
just becomes as a serialized body
of another org.springframework.amqp.core.Message
. I have changed it to this and everything works well:
public String createRequest(String message){
System.out.println("Inside createRequest : "+ message);
return message;
}
public Message processRequest(Message message){
System.out.println("Inside process Request : " + message);
return message;
}
Anyway I suggest you to rethink your design and come back to the AmqpInboundGateway
.
BTW in the final solution you don't need to care about any correlation
. The Framework does that for you automatically.