Announcement Announcement Module
No announcement yet.
What should I use for synchrounous send and receive method. Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • What should I use for synchrounous send and receive method.

    I'm stuck implementing an interface from the business layer that looks something like this "XResponsefx(XRequest)".

    Inside fx call
    public XResponse fx(XRequest) {
    channel.send(new GenericMessage(XRequest))
    ..... /* The part I'm blanking on */
    return XResponse


    I'm using a chain to send the XRequest through the input channel to a transformer, header enricher and an int-ws:outbound-gateway that sends the output-channel to a transformer the gives me the XResponse

    But how do I get the payload off of the response channel so I can return that from XResponse? I thought I could use a service-activator, but I now realize that won't work for the synchronous requirement.
    Am I supposed to use a channel adapter to get the response channel payload?
    I will continue to search this form for the answer, but there's only 192 some pages to wade through find, and I'm hoping someone can provide answer faster than I can hunt it down.

  • #2

    How about this one: ?

    Take care,


    • #3
      Thanks. I will experiment with that.
      I did consider using a pollable channel for the response channel, but this looks like a better solution.


      • #4
        I've created the <int:gateway> but I'm don't know how to tie the gateway to the chain where the real work gets done.
        I want the gateway to send it's payload to the chain, and the chain to return the results to the gateway. I'll read the documentation more closely, but if someone already knows the answer I'd appreciate hearing about it.

        <int:gateway id="serviceGateway" default-request-channel="requestChannel" default-reply-channel="responseChannel" service-interface="a.b.service.SomeService" default-reply-timeout="15" default-request-timeout="15">
        <int:method name="fx"/>

        <int:chain input-channel="requestChannel" output-channel="responseChannel">
        <int:transformer ref="transformer"/>
        <int-ws:soap-action value="#{soapActions['blah']}"/>
        <int-ws:outbound-gateway destination-provider="destinationProvider"
        unmarshaller="marshaller" marshaller="marshaller"/>
        <int:transformer ref="transformer"/>


        • #5

          The first: please, use the [ CODE ] & [ /CODE ] or [ HTML ] & [ /HTML ] for wrapping your samples in the post.

          Now what I see in your config: everything looks good.
          Invocation on the serviceGateway#fx() initiates an message flow through requestChannel and this flow makes reply into
          responseChannel. What's going on inside this "black box", doesn't matter .
          As I understand now you have a question how to invoke your gateway. It can be done several point:
          as bean injection into some your service as <service-activator>'s method-invocation.

          Is it what are you looking for?

          By the way: if your message flow so simple, maybe there is no any reason to use 'reply-channel' on the <gateway> and remove 'output-channel' on the <chain>. Gateway's method with non-void return inject into 'reply-channel' messageHeader some TemporaryReplyChannel instance and it will be enough to have classic request-reply message flow.



          • #6
            Originally posted by Cleric View Post
            By the way: if your message flow so simple, maybe there is no any reason to use 'reply-channel' on the <gateway> and remove 'output-channel' on the <chain>. Gateway's method with non-void return inject into 'reply-channel' messageHeader some TemporaryReplyChannel instance and it will be enough to have classic request-reply message flow.
            I'm not sure what to make of this. Think it means I need to do something like this:
            <int:gateway id="serviceGateway" default-request-channel="requestChannel" service-interface="a.b.service.SomeService">
                <int:method name="fx">
                    <int:header name="replyChannel" value=responseChannel"/>
            I've tried this without any changes to the chain, but I get "org.springframework.integration.MessageDeliveryEx ception: Dispatcher has no subscribers for channel responseChannel".

            One key concept that I don't understand is how the gateway feeds into the chain, and I obviously don't know what my responseChannel is doing.

            I don't have a service activator on the end of the chain, and I'm wondering if that is part of the problem. The last transformer at the end of the chain produces that output that I want returned from serviceGateway#fx().
            I've looked at an example that uses a gateway to send stuff directly to a service activator and gets a return value, but the "service activator" I'm trying to use is the chain.


            • #7
              You don't even need to add that replyChannel header explicitly. The gateway will automatically add one by default, and then the terminal downstream component that has no explicit output-channel will then send to that auto-created one. In your case if the ultimate downstream component is actually the chain itself, that means you can remove its 'output-channel' attrib altogether.

              Hope that's clear.


              • #8
                Here's why I am getting hung up on the replyChannel. The log shows that it makes it through the last transformer at the end of the chain, and sends the x.y.z.XReponse back to the serviceGateway, but the gateway carps about no replyChannel header available.

                2012-08-16 08:14:10,598 [main] DEBUG org.springframework.integration.transformer.MessageTransformingHandler - handler 'org.springframework.integration.transformer.MessageTransformingHandler@164cbde' sending reply Message: [Payload=x.y.z.XResponse@1de8aa8][Headers={timestamp=1345122850598, id=4aa38bc5-4df9-4cc1-ad8b-b0f15d2b35c8}]
                2012-08-16 08:14:10,598 [main] WARN  org.springframework.integration.gateway.GatewayProxyFactoryBean$MethodInvocationGateway - failure occurred in gateway serviceGateway
                org.springframework.integration.MessageHandlingException: no replyChannel header available
                	at org.springframework.integration.handler.MessageHandlerChain$ReplyForwardingMessageChannel.send(
                	at org.springframework.integration.handler.MessageHandlerChain$ReplyForwardingMessageChannel.send(
                	at org.springframework.integration.core.MessagingTemplate.doSend(
                	at org.springframework.integration.core.MessagingTemplate.send(
                	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(
                	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(
                	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(
                	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(
                	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(
                	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(
                	at org.springframework.integration.handler.MessageHandlerChain$1.send(


                • #9

                  Let me gues: your transformer bean returns entire Message and you don't copy request headers to that Message on its build.
                  <transformer> is a component with some specific contract: it is an Black Box for framework and what he takes and returns is up to end-developer. And the returned Message will be sended to the output-channel or reply-header-channel (if available ) without any modifications.

                  So, now question from me: what does your transformer bean do?


                  • #10
                    To further clarify; we generally recommend user code to NOT use the messaging APIs directly - in the vast majority of cases, you should use POJOs and not depend on Message<?> etc directly.

                    See this thread for some further insight...



                    • #11
                      Here it is in all of its glory.
                      public class MyTransformer implements Transforme {
                        public Message<?> transform( final Message<?> message ) {
                          Object payload = message.getPayload();
                          Message<?> forwardMessage;
                      if ( payload instanceof ThingThatWrapsMyRequestAndMyResponseTypes ) {
                            // create JAXB request object from our data type
                            // this goes into the int-ws:outbound-gateway
                            ThingThatWrapsMyRequestAndMyResponseTypes x = (ThingThatWrapsMyRequestAndMyResponseTypes)payload;
                            JAXBWebServiceRequestType y = new JAXBWebServiceRequestType();
                            // stuff some values from x into y
                            forwardMessage = new GenericMessage<JAXBRequestType>( y );
                          } else
                          if ( payload instanceof JAXBWebServiceResponse ) {
                            // Transform the JAXB response to out data type
                            // this goes back to the int:gateway "serviceGateway"
                           JAXBObject x = (JAXBObject)payload;
                           ThingThatWrapsMyRequestAndMyResponseTypes y = new ThingThatWrapsMyRequestAndMyResponseTypes();
                           // stuff some values from x into y
                            forwardMessage = new GenericMessage<ThingThatWrapsMyRequestAndMyResponseTypes>( y );
                          else {
                            // this is probably a half-baked idea
                            forwardMessage = new GenericMessage<AssertionError>(
                                new AssertionError( ERROR_MSG + payload.getClass() ) );
                          return forwardMessage;


                      • #12
                        I changed my Transformer to an AbstractTransformer, and changed my method to doTransform that returns the pojos, and it worked.

                        You have a potential source of revenue at your fingers. I would like to see a book that puts more emphasis on the classes such as AbstractTransformer that don't require the developer to mess with the Message.

                        I have just searched Spring Integration in Action, Pro Spring Integration, and the Sprint Integration Reference Manual, and AbstractTransformer was only mentioned in the reference manual once.
                        The books and examples I have found all emphasis the nitty gritty at the Message level and not the POJO level.

                        Thank you all for your help.