Search code examples
xmlspringspring-integrationdeclarative

Spring-Integration: Using a recipient-list-router from inside of a chain to achieve iteration but getting a routing error


From a spring-integration chain A I'm calling a chain B that may "loop" on itself until all information recovery is satisfied (since the first call may retrieve information that itself needs to be resolved by subsequent calls).

chain A calls to chain B via a gateway call, hence expects a return message:

<int:chain input-channel="A_channel" />
    ...
    <int:gateway request-channel="B_channel" />
    ...
</int:chain>

In case that it's useful, I'll note that the chain A is itself called from a gateway call originating from an HTTP inbound-gateway.

Chain B then embeds a recipient-list-router:

<int:channel            id="B_channel" />
<int:chain   input-channel="B_channel" >
    <int:gateway request-channel="C_channel" />
    <int:transform ... set the payload to indicate if still more work to do ... />
    <int:recipient-list-router resolution-required="false">
        <int:recipient channel="B_channel" select-expression="payload.size() != 0" />
    </int:recipient-list-router>
</int:chain>

The is giving me an error. Either of

  • "No channel resolved by router" (when no resolution-required attribute is set)
  • "No channel resolved by router and no defaultOuputChannel defined" (with resolution-required set to false)

I'm wanting an iterative loop based upon a condition and I was thinking that recipient-list-router would give me that possibility, but I'm not finding the magic invocation. Also, if the recipient-list-router at the end of a chain resolves no output channel, I was thinking that it would continue to the output-channel that the chain itself would have configured, in this case, the replyChannel set up by the gateway call to chain B.

What will allow this kind of iterative execution from within a declarative environment?


Solution

  • Solution using <int:filter ...> as proposed by @artem-bilan:

    <int:channel            id="B_channel" />
    <int:chain   input-channel="B_channel" >
        <int:gateway request-channel="C_channel" />
        <int:transform ... set the payload to indicate if still more work to do ... />
        <int:filter expression="payload.size() eq 0" discard-channel="B_channel" />  
        <... post-iteration operations here ...>
    </int:chain>
    

    Much more compact and easier to read. Thanks!