2

I am trying to handle multiple subflows in my application. Kindly see below example:

@Component
@DependsOn(value = { "flowUpperCase" })
public class SampleHttpFlowTest extends IntegrationFlowAdapter {
    protected IntegrationFlowDefinition<?> buildFlow() {
        System.out.println("SampleHttpFlowTest.buildFlow");
        return IntegrationFlows.from(Http.inboundGateway("/sampleflow/{myinput}")
                .payloadExpression("#pathVariables.myinput"))
                .channel("flowUpperCase.input");
    }
}

@Component
public class SampleSubFlows {
    @Bean
    public IntegrationFlow flowUpperCase() {
        System.out.println("SampleHttpFlow.flowUpperCase");
        return sf -> sf.<String, String>transform(String::toUpperCase);
    }
}

Using above case if use http://localhost:8080/sampleflow/hello then I got response => HELLO which is the expected result as I am expecting input path variable should transform into upper case. Everything is fine till here. Now I am trying to log the statement using Spring DSL, so I modified my code a bit:

protected IntegrationFlowDefinition<?> buildFlow() {
    System.out.println("SampleHttpFlowTest.buildFlow");
    return IntegrationFlows.from(Http.inboundGateway("/sampleflow/{myinput}")
            .payloadExpression("#pathVariables.myinput"))
            .channel("flowUpperCase.input")
            .log().bridge(); // log and return the output               
}

Using this, I am getting my expected result on every alternate request only, meaning first request giving me correct response with capital letters, but second request giving me wrong response with string having lower case and so on. I did some analysis and found that transformation calling skipped by spring framework in every alternate request, however couldn't find the root cause of this behavior yet.

I also tried with subscriberchannel as mentioned below:

@Component
public class SampleHttpFlow2 extends IntegrationFlowAdapter {
    protected IntegrationFlowDefinition<?> buildFlow() {
        System.out.println("SampleHttpFlow.buildFlow");
        return IntegrationFlows.from(Http.inboundGateway("/subscriberChannel/{myinput}")
                            .payloadExpression("#pathVariables.myinput"))
                            .publishSubscribeChannel(s -> s.subscribe(flowOk1()));
    }

    private IntegrationFlow flowOk1() {
        System.out.println("SampleHttpFlow2.createAnotherFlow");
        return sf -> sf.<String, String>transform(String::toUpperCase);
    }
}

Again its working fine and I am getting my expected result. But as soon as I add log statement then I am getting always wrong response (always getting letter in lower case). See below statement, its giving me wrong result with string in lower case:

return IntegrationFlows.from(Http.inboundGateway("/subscriberChannel/{myinput}")
                       .payloadExpression("#pathVariables.myinput"))
                       .publishSubscribeChannel(s -> s.subscribe(flowOk1()))
                       .log().bridge();

If use "gateway" method followed by log and bridge then everything is fine.

return IntegrationFlows.from(Http.inboundGateway("/subscriberChannel/{myinput}")
                       .payloadExpression("#pathVariables.myinput"))
                       .gateway("flowUpperCase.input")
                       .log().bridge();

But, I am not sure if it is right and best way to use "gateway" method for internal calling. Is gateway method expensive call? I am new in Spring integration, kindly help to understand what is the best way to call subflows using spring integration DSL?

One more question: As you see above, I have created a flow with bean "flowUpperCase". Lets assume that I have 200 different APIs/interfaces to be exposed in my application. Can I use same bean/channel for my all APIs/interfaces as I need to perform same logic (transform string to upper case)? So question is that should I share my same "channel" with two or more APIs? Will it create a problem when two or more users send request at same time?

ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
javatech
  • 33
  • 3
  • It is not clear what you are trying to do; in the first case, you have 2 subscribers on the (default) `DirectChannel`, which means the subflows will get alternate requests (Round Robin) which is what you are observing. Changing it to a pub/sub channel means both subflows will get the request, but that makes no sense because a gateway can only process one response per request. – Gary Russell Aug 23 '21 at 12:38
  • 1. The main objective is to understand that how to consume existing “IntegrationFlow”. 2. If we use gateway to consume “IntegrationFlow” then application booting time increase as more flows increase the app boot time exponentially. We have about 200 APIs and each having 10 to 12 different steps along with multiple Integration flows. 3. Can we reuse existing IntegrationFlow in multiple APIs? – javatech Aug 24 '21 at 08:10
  • https://stackoverflow.com/questions/17875236/are-spring-integration-channels-single-threaded – javatech Aug 24 '21 at 08:30

0 Answers0