1

I am the newbie on Spring Integration and EIP.

I tried to solve myself but it would not come proper solution on my mind.

Here is the example of the flow I need.

  1. Client send Json data to SI.
  2. HTTP inbound Gateway got Json data as payload.
  3. This Json data will be used two separate HTTP outbound. But the second outbound call is followed on the response of the first call outbound call.
  4. reply the result to Step 0 (replychannel on HTTP inbound Gateway)

I am thinking to use publishSubscribeChannel or RecipientListRouter to send the same message to separate calls. but in this case, it need to execute the second http outbound on certain time. And as I understand it should be one transaction for the reply on step 4.

Or...

Is it possible keep the message instance (JSON data from http inbound Gateway) to use at the second call after the first call.

Please give me some idea and if you have a sample code, it must be wonderful. Currently I am write JAVA config style but XML sample also welcome.

Update the question

I am trying to add the bridge and executorChannel.

Here is my code and few thing are not working as I expected.

  1. I want to the second outbound handler(httpPMGateway) use the message from aIncomingGateway(using publishSubscribeChannel because of this) , but after httpJ3Gateway outbound handler, it use the message from the httpJ3Gateway. I use the route with response message from httpJ3Gateway. (Ok -> httpPMgateway , Default -> backAChannel)

  2. I would like to send response message to aIncomingGateway from end of j3ValidationFlow or broadcastFlow. But aIncomingGateway got reply message already before they send. this is log message.

2017-05-16 11:17:09.061 WARN 11488 --- [pool-1-thread-1] cMessagingTemplate$TemporaryReplyChannel : Reply message received but the receiving thread has already received a reply:

This is code section :

@Bean
public MessagingGatewaySupport aIncomingGateway() {
    HttpRequestHandlingMessagingGateway handler = new HttpRequestHandlingMessagingGateway(true);

    RequestMapping requestMapping = new RequestMapping();
    requestMapping.setMethods(HttpMethod.POST);
    requestMapping.setPathPatterns("/a/incoming");
    requestMapping.setConsumes("application/json");
    requestMapping.setProduces("application/json");


    handler.setRequestMapping(requestMapping);
    handler.setMessageConverters(getMessageConverters());
    handler.setRequestPayloadType(Amount.class);

    handler.setReplyChannelName("backAChannel");
    return handler; 
}

@Bean
public MessageHandler httpJ3Gateway(){
    HttpRequestExecutingMessageHandler httpHandler = new HttpRequestExecutingMessageHandler("http://localhost:8080/j3/incoming");
    httpHandler.setHttpMethod(HttpMethod.POST);
    httpHandler.setExpectReply(true);
    httpHandler.setMessageConverters(getMessageConverters());
    httpHandler.setExpectedResponseType(String.class);
    httpHandler.setRequestFactory(requestFactory());
    return httpHandler;
}

@Bean
public MessageHandler httpPMGateway(){
    HttpRequestExecutingMessageHandler httpHandler = new HttpRequestExecutingMessageHandler("http://localhost:8080/pm/incoming");
    httpHandler.setHttpMethod(HttpMethod.POST);
    httpHandler.setExpectReply(true);
    httpHandler.setMessageConverters(getMessageConverters());
    httpHandler.setExpectedResponseType(String.class);
    return httpHandler;
}

@Bean
public MessageChannel broadChannel(){
    return new ExecutorChannel(Executors.newCachedThreadPool());
}

@Bean
@ServiceActivator(inputChannel = "brigdeChannel")
public MessageHandler bridgeHandler(){
    BridgeHandler handler = new BridgeHandler();
    handler.setOutputChannel(broadChannel());
    return handler;
}


@Bean
public IntegrationFlow aIncomingFlow() {
    return IntegrationFlows.from(aIncomingGateway())
            .log(LoggingHandler.Level.INFO, "From Inbound http gateway", m -> m.getPayload().toString())
            .publishSubscribeChannel(p -> p
                    .subscribe(s -> s.channel("j3Channel"))
                    .subscribe(s -> s.bridge(b -> bridgeHandler()) )
                    )
            .get();
}

@Bean
public IntegrationFlow j3ValidationFlow() {
    return IntegrationFlows.from("j3Channel")
            .log(LoggingHandler.Level.INFO, "Run j3ChannelFlow", m -> m.getPayload().toString())
            .handle(httpJ3Gateway())
            .route("headers.http_statusCode", m -> m
                    .resolutionRequired(false)
                    .channelMapping("OK", "brigdeChannel")
                    .defaultOutputToParentFlow()
                    )
            .channel("backAChannel")
            .get();
}

@Bean
public IntegrationFlow broadcastFlow() {
    return IntegrationFlows.from("broadChannel")
            .log(LoggingHandler.Level.INFO, "Run broadcastFlow", m -> m.getPayload().toString())
            .handle(httpPMGateway())
            .channel("backAChannel")
            .get();
}

Please help me to get an idea.
I appreciated in advance. Thank you for helping me on this dumb question.

Alfabravo
  • 7,493
  • 6
  • 46
  • 82
Jun
  • 11
  • 3

1 Answers1

0

Yes; use a pub/sub channel or a recipient list router

inbound -> ... -> pubsub

pubsub -> outbound1

pubsub -> bridge -> executorChannel -> outbound2

outbound1 will run on the inbound thread; outbound2 will run on another thread.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thank for quick answering. I have one remaining question. If outbound2 will run another thread, it could reply to original inbound (Client) ? – Jun May 15 '17 at 18:48
  • Yes, if the `outbound1` is one-way, non-replying component (`Outbound Channel Adapter` in terms of Spring Integration). Only one reply can be sent to the waiting Inbound Gateway. – Artem Bilan May 15 '17 at 18:53
  • Hello Gary and Atrem, I updated my question. Please help me to get an idea to solve it..... Thank you in advance. – Jun May 16 '17 at 17:00
  • You can't send two replies (as the message clearly states, and as @Artem said above). You need to route the reply from one of the gateways to `nullChannel`. Or, if you need information from both, they need to go to an aggregator where you can combine the results. – Gary Russell May 17 '17 at 15:11