Search code examples
spring-integrationspring-integration-dsl

Spring Integration DSL: How to refactor into Subflows?


To make my Spring Integration DSL code more readable and modular, I would like to extract a complex operation like .scatterGather() into a subflow.

Take this as an example of how the code could look before the refactoring:

@Bean
IntegrationFlow testFlow() {
        return IntegrationFlows
                .from(Http.inboundChannelAdapter("test").get())
                .scatterGather(
                        s -> s
                                .applySequence(true)
                                .recipientFlow(getSubFlow2()),
                        g -> g.outputProcessor(MessageGroup::getOne))
                .log(INFO, m -> m)
                .routeToRecipients(route -> route
                        .recipientFlow(IntegrationFlowDefinition::nullChannel)
                        .get())
                .get();
}

private IntegrationFlow getSubFlow2() {
    return f -> f.handle((m, h) -> 42);
}

This is the part I would like to extract into it's own subflow and method:

                .scatterGather(
                        s -> s
                                .applySequence(true)
                                .recipientFlow(getSubFlow2()),
                        g -> g.outputProcessor(MessageGroup::getOne))
                .log(INFO, m -> m)

I'm imagining the result looking something like this:

@Bean
IntegrationFlow testFlow() {
        return IntegrationFlows
                .from(Http.inboundChannelAdapter("test").get())
                .someMethod(getSubFlow1())
                .routeToRecipients(route -> route
                        .recipientFlow(IntegrationFlowDefinition::nullChannel)
                        .get())
                .get();
}

private IntegrationFlow getSubFlow1() {
        return f -> f
                .scatterGather(
                        s -> s
                                .applySequence(true)
                                .recipientFlow(getSubFlow2()),
                        g -> g.outputProcessor(MessageGroup::getOne))
                .logAndReply(INFO, m -> m)
}

private IntegrationFlow getSubFlow2() {
    return f -> f.handle((m, h) -> 42);
}

Can this be done somehow with Spring Integration DSL ? How ?


Solution

  • See gateway(IntegrationFlow) method of flow definition :

        /**
    
     * Populate the "artificial"
    
     * {@link org.springframework.integration.gateway.GatewayMessageHandler} for the
    
     * provided {@code subflow}.
    
     * Typically used with a Java 8 Lambda expression:
    
     * <pre class="code">
    
     * {@code
    
     *  .gateway(f -> f.transform("From Gateway SubFlow: "::concat))
    
     * }
    
     * </pre>
    
     * @param flow the {@link IntegrationFlow} to to send a request message and wait for reply.
    
     * @return the current {@link BaseIntegrationFlowDefinition}.
    
     */
    
    public B gateway(IntegrationFlow flow) {