Announcement Announcement Module
No announcement yet.
gateway proxy vs reply-channel Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • gateway proxy vs reply-channel

    We are implementing a scenario where we want to call a single webservice gateway from multiple flows. We want to configure this gateway in one context and import that context into several flow context files. For this reason we need to dynamically specify the reply-channel for the webservice gateway, because we don't know to which channel it needs to respond to. This can be achieved by setting the reply channel of the message being sent to the webservice gateway. It all works nicely until we want to invoke this flow from a gateway proxy. The gateway proxy is using some internal temporary channel, which if we override in the message it will send the message to the overriding channel instead of just returning it through the interface method. This results in an infinite loop.
    I can think of a number of workarounds for this issue, but what's really bugging me is the fact that we are doing something really simple and straightforward here that I strongly feel is supported by the framework in some way. Please let me know where our assumptions are failing us, and what could be a good solution for the problem. Here is a minimalist sample flow showing the problem:

    <beans xmlns=""
    	   xmlns:xsi="" xmlns:int=""
    	<int:gateway service-interface="myseitest.SeiService"/>
    	<int:channel id="inputChannel1"/>
    	<int:channel id="outputChannel1"/>
    	<int:chain id="flow1" input-channel="inputChannel1" output-channel="wsInputChannel">
    		<int:transformer expression="payload + '-flow1'"/>
    			<int:reply-channel ref="postprocess1" overwrite="true"/>
    	<int:channel id="inputChannel2"/>
    	<int:channel id="outputChannel2"/>
    	<int:chain id="flow2" input-channel="inputChannel2" output-channel="wsInputChannel">
    		<int:transformer expression="payload + '-flow2'"/>
    			<int:reply-channel ref="postprocess2" overwrite="true"/>
    	<int:channel id="wsInputChannel"/>
    	<int:transformer id="wsCall" input-channel="wsInputChannel" expression="payload + ':WS-RESULT'"/>
    	<int:channel id="postprocess1"/>
    	<int:transformer input-channel="postprocess1" output-channel="outputChannel1" expression="payload + '-postprocess1'"/>
    	<int:channel id="postprocess2"/>
    	<int:transformer input-channel="postprocess2" output-channel="outputChannel2" expression="payload + '-postprocess2'"/>
    And the definition of SeiService:

    package myseitest;
    import org.springframework.integration.annotation.Gateway;
    public interface SeiService {
    	@Gateway(requestChannel = "inputChannel1", replyChannel = "outputChannel1")
    	String operation1(String message);
    	@Gateway(requestChannel = "inputChannel2", replyChannel = "outputChannel2")
    	String operation2(String message);
    Thank you!

    Adam Sandor

  • #2
    Well, the reply channel header is exactly the mechanism the framework uses to send the response to the gateway proxy, so messing with it will do exactly what you see.

    A common way to deal with what you want is to define the common subflow with well-known input and output channels; send the request to the input channel and <bridge/> the output channel to the next channel in the calling flow.

    You may also be able to use an <enricher/>.

    Hope that helps.


    • #3
      If the flow wrapping the webservice gateway would have a well-known reply channel, and we would have two or more flows attached to it, wouldn't all flows receive all the messages coming on the reply channel? I don't see how could the flow distinguish messages from different originating flows without setting the reply channel on those messages.


      • #4
        You said
        ...import that context...
        I assumed you meant <import .../> the common configuration into each application's context; in which case each application gets a private copy; the components will get the same bean names but within each context so each <bridge/> will be the sole subscriber to each instance of the output channel.

        If you meant something else by "import", please explain.


        • #5
          OMG... I didn't realize that the import will actually create private copies... I thought we are really sharing the same bean instance. In that case your solution makes perfect sense. Thanks very much!