spring amqp-outbound gateway to produce reply from a different thead (Like jms-outbound gateway)

前端 未结 1 843
再見小時候
再見小時候 2021-01-28 16:04

Problem statement:

Spring amqp-outbound gateway to produce reply from a different thread (Like jms-outbound gateway, having different queue, correlate t

相关标签:
1条回答
  • 2021-01-28 16:58

    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:

    1. You are definitely missing the replyQueue binding:

      @Bean
      public Binding bindingReply(){
          return BindingBuilder.bind(this.replyQueue()).to(this.exchangeReply()).with("reply_exchange_queue");
      }
      
    2. 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;
      }
      
    3. 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.

    0 讨论(0)
提交回复
热议问题