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.
- Client send Json data to SI.
- HTTP inbound Gateway got Json data as payload.
- 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.
- 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.
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)
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.