Announcement Announcement Module
Collapse
No announcement yet.
GatewayProxyFactoryBean and AMQP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • GatewayProxyFactoryBean and AMQP

    Hi there,

    First off let me admit that I am pretty new to Spring Integration and AMQP so I apologize in advance if I am completely off track.

    I am trying to get an example working using a GatewayProxyFactoryBean and AMQP. Here is an snippet from my spring configuration:

    -------

    <int:gateway id="gateway"
    service-interface="com.innovisionsystems.service.StringCon versionService">
    <int:method name="convertToUpperCase" />
    </int:gateway>

    <int-amqp:outbound-gateway id="outboundGateway"
    request-channel="toRabbit"
    amqp-template="rabbitTemplate"
    exchange-name="si.test.exchange"/>

    -------

    As I understand it the GatewayProxyFactory bean will automatically create a temporary reply queue. When I step through my example in the debugger I can see the message arrive at the AmqpOutboundEndPoint::sendAndReceive() method with a replyChannel set.


    Here is an extract of the code:

    private Message<?> sendAndReceive(String exchangeName, String routingKey, Message<?> requestMessage) {
    // TODO: add a convertSendAndReceive method that accepts a MessagePostProcessor so we can map headers?
    Assert.isTrue(amqpTemplate instanceof RabbitTemplate, "RabbitTemplate implementation is required for send and receive");
    MessageConverter converter = ((RabbitTemplate) this.amqpTemplate).getMessageConverter();
    MessageProperties amqpMessageProperties = new MessageProperties();
    this.headerMapper.fromHeadersToRequest(requestMess age.getHeaders(), amqpMessageProperties);
    org.springframework.amqp.core.Message amqpMessage = converter.toMessage(requestMessage.getPayload(), amqpMessageProperties);
    org.springframework.amqp.core.Message amqpReplyMessage = this.amqpTemplate.sendAndReceive(exchangeName, routingKey, amqpMessage);
    if (amqpReplyMessage == null) {
    return null;
    }

    By the time we get to the amqpTemplate.sendAndReceive() method call the amqpMessage does not appear to have any reply / replyChannel set.

    Is this expected behaviour ? Is there anyway for the temporary reply queue generated by the Gateway to be passed through AMQP ???


    Cheers

  • #2
    No; the gateway can't "send" the replyChannel over AMQP (it's a live Java object the GPFB is waiting to receive() a reply on).

    Why do you need it there? The outbound gateway keeps a reference to the replyChannel (in the headers of the outbound message) and adds it to the reply when it's received from the template.

    However, you need to be sure to set the receive-timeout on the outbound gateway if the remote service might take longer than 5 seconds (the default). Otherwise, the outbound gateway will time out silently.

    The best way to debug issues like these is to run with DEBUG logging.

    Comment


    • #3
      Hi Gary,

      Thanks for the quick reply. Sounds like I may have gone off on a tangent - I started looking at this behavior because one of the down stream elements was complaining that there was no reply channel specified.

      I'll try and describe my setup - I'm not at my work PC right now so I cant cut and paste picture / config so I'll do my best to explain.

      I am trying to model a client / server split

      On the Client side I am imagining the flow within spring integration would look a bit like this:

      POJO => Gateway Interface => Direct Channel => Outbound AMQP Gateway => onto AMQP queue


      Here is the same diagram for the server side:

      AMQP Queue => Inbound AMQP Gateway => Direct Channel => Service Activator

      My Service Activator keeps complaining that no reply channel is specified. Thats problem 1.

      I dont seem to grok how the reply from my Service Activator is going to make it back to the GatewayProxy / POJO on the client side.

      Apologies in advance for the lameness of my questions but I have been bashing my head on this for a while and its time to swallow my pride and sing out for some help. I thought I understood the basics of how things hang together in spring integration but this example has shown up my short comings.

      Please advise if there is a better / simpler solution to my problem. My aim is to be able to present a POJO interface to the client and to the server so that knowledge of the messaging protocol etc doesn't leak out into the client / server code.

      Cheers

      Comment


      • #4
        This should (does) work ok; there must be something missing from the picture.

        In this case, the replyChannel on the server side is a "new" replyChannel, created by the inbound-gateway; the listener container thread (that received the message from AMQP) is (or will eventually be) waiting on a receive() in that channel.

        This is quite separate from the replyChannel on the client side, in which the original caller will get the reply from the outbound channel adapter.

        If your server flow is as simple you show, I see nowhere that the replyChannel header will be "lost"; so I am assuming there is something else going on over there.

        Turn on DEBUG logging on the server; you should see the message from the inbound gateway contains a replyChannel header - trace through the logs to see where it is dropped.

        Comment


        • #5
          Okay at least the basic scenario is semi sane - I will do what you say and increase the log levels to find out whats going on. Its bound to be looser error - sounds like the logging will help me pin point where my stuff up is.

          Thanks for your help - i'll let you know how I go.

          Comment


          • #6
            Success

            Success !

            As predicted it was "looser" error. I enabled logging and was pretty quickly able to determine that the AmqpOutboundEndpoint was not sending the message. I was specifying the exchange but not supplying the "routing key" so the message wasnt actually being put on the queue. Didn't really understand all that exchange, binding, routing key - now I have a slightly better idea

            I should have enabled logging and checked the logs - my only excuse is I wasnt confident that I had the basic scenario right. Once it was confirmed that I was doing something that should work I was able to check the logs and get it sorted.

            Thanks for your help !

            Comment

            Working...
            X