I am trying to expose HTTP endpoint which will drop a message to a JMS queue I want to reply with Success if the delivery is successful and FAILURE if message can not be delivered.
@Bean
public IntegrationFlow systemTaskCall(MapToServiceTaskConfigTransformer mapTransformer, CachingConnectionFactory jmsConnectionFactory) {
return IntegrationFlows.from(
Http.inboundGateway("/spartaSystemTask")
.requestMapping(r -> r
.methods(HttpMethod.POST)
.consumes("application/json")
)
.requestPayloadType(Map.class)
.replyChannel(RESPONSE_CHANNEL)
.errorChannel("errorChannel")
)
.handle((payload, headers) -> mapTransformer.transform((Map<String, String>) payload))
.enrichHeaders(Collections.singletonMap(DESTINATION_QUEUE, "request.queue"))
.enrichHeaders(Collections.singletonMap(JMS_REPLY_TO, "response.queue"))
.transform(Transformers.toJson())
.handle(
Jms.outboundGateway(jmsConnectionFactory,)
.requestDestination(message -> message.getHeaders().get(DESTINATION_QUEUE))
)
.log(LoggingHandler.Level.ERROR)
.enrichHeaders(
c -> c.header(org.springframework.integration.http.HttpHeaders.STATUS_CODE, HttpStatus.CREATED)
)
.transform(source -> "SUCCESS")
.transform(Transformers.toJson())
.channel(RESPONSE_CHANNEL)
.get();
}
@Bean
public IntegrationFlow errorFlow(){
return IntegrationFlows.from("errorChannel")
.transform(source -> "error")
.transform(Transformers.toJson())
.channel(RESPONSE_CHANNEL)
.get();
}
When I call this URL, Message is dropped but HTTP call times out. It seems post the JMS Outbound gateway call rest of the code is not executed.
In case of Failure in message delivery I am getting correct response.
You have this configuration:
.handle(
Jms.outboundGateway(jmsConnectionFactory,)
.requestDestination(message -> message.getHeaders().get(DESTINATION_QUEUE))
)
outboundGateway
. That means you send a request and expect a response from the other side, but it looks like you only send a JMS message into a queue and no one on the other listener side answers you with something into that response.queue
. That's the reason for time out your get with a normal JMS publishing.You need to sure that logic is correct in your flow and it is indeed valid in your distributed solution that you expect some reply from the server side.
Otherwise you need to think about changing your logic into a Jms.outboundAdapter()
which is really one-way sender. For HTTP reply you could use a publishSubscribeChannel()
with this Jms.outboundAdapter()
as the first subscriber and the rest of your flow as a second one. This way the second subscriber is not going to be called until the first one finishes its logic properly. For the error cases you can wrap that Jms.outboundAdapter()
with an ExpressionEvaluatingRequestHandlerAdvice
: https://docs.spring.io/spring-integration/docs/5.2.3.RELEASE/reference/html/messaging-endpoints.html#message-handler-advice-chain