0

I am new to Spring Integration and i am trying to use the HttpRequestExecutingMessageHandler and the HttpRequestHandlingMessagingGateway. The Handler is sending a POST Request and expecting reply. The Gateway is consuming the request. It works fine, BUT the Handler is not getting a reply back. I dont know how to setup my flow, that i can direcly send a reply back and continue my flow.

@Bean
public HttpRequestExecutingMessageHandler httpOutbound() {
  HttpRequestExecutingMessageHandler handler = Http.outboundGateway(restUrl)
        .httpMethod(HttpMethod.POST)
        .messageConverters(new MappingJackson2HttpMessageConverter())
        .mappedRequestHeaders("Content-Type")
        .get();
  handler.setExpectReply(true);
  handler.setOutputChannel(httpResponseChannel());
  return handler;
}

@Bean
public HttpRequestHandlingMessagingGateway httpRequestGateway() {
  HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
  RequestMapping mapping = new RequestMapping();
  mapping.setMethods(HttpMethod.POST);
  mapping.setPathPatterns(httpRequestHandlingPathPattern);
  gateway.setRequestMapping(mapping);
  gateway.setErrorChannel(errorChannel());
  gateway.setReplyChannel(replyChannel());
  gateway.setRequestChannel(requestChannel());
  gateway.setRequestPayloadTypeClass(DocumentConverterInput.class);
  return gateway;
 }

@Bean
public IntegrationFlow documentConverterFlow() {
  return IntegrationFlows
        .from(requestChannel())
        .publishSubscribeChannel(publishSubscribeSpec ->
              publishSubscribeSpec.subscribe(flow -> flow
                          .enrichHeaders(headerEnricherSpec -> headerEnricherSpec.header("http_statusCode", HttpStatus.OK))
                          .channel(replyChannel())))
        .enrichHeaders(headerEnricherSpec ->
             headerEnricherSpec.headerExpression(Constants.DOCUMENT_CONVERTER_INPUT, "payload"))
        .handle(Jms.outboundAdapter(jmsTemplate(connectionFactory)))
        .get();
 }

My HttpRequestExecutingMessageHandler is successfully posting the request. The HttpRequestHandlingMessagingGateway is successfully consuming it. At first i had an error "No reply received within timeout", so that i added a publishSubscriberChannel. I don't know if it is the right way, but i cannot find working examples, which show how to reply correctly.

My above code is working, BUT not sending reply back to HttpRequestExecutingMessageHandler!

My goal is to receive the request message and directly send back 200 OK. After that i want to continue my integration flow, do some stuff and send the result to queue.

Any suggestions?

Anton Styopin
  • 753
  • 4
  • 17
  • 35

1 Answers1

1

For just 200 OK response you need to consider to configure an HttpRequestHandlingMessagingGateway with a expectReply = false. This way it is going to work as an Inbound Channel Adapter, but having the fact that HTTP is always request-response, it will just do this setStatusCodeIfNeeded(response, httpEntity); and your HttpRequestExecutingMessageHandler on the client side will get an empty, but OK resposnse.

Not sure though why your channel(replyChannel()) doesn't work as expected. It might be the fact that you return a request palyoad into a reply message which eventually becomes as a HTTP response, but somehow it fails there, may be during conversion...

UPDATE

Here is a simple Spring Boot application demonstrating a reply-and-process scenario: https://github.com/artembilan/sandbox/tree/master/http-reply-and-process

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Thank you for this answer. I'll give that a try. You said "For just 200 OK response you need to consider to configure an HttpRequestHandlingMessagingGateway with a expectReply = false.". What about if i would like to also get other http states, like a states handler? How can i build my flow to achieve that? – Anton Styopin Sep 27 '19 at 18:50
  • Then it is indeed has to be as a gateway (`new HttpRequestHandlingMessagingGateway()`). Consider to return an empty string as a response. Some simple `.transform()` before `.channel(replyChannel())` – Artem Bilan Sep 27 '19 at 18:59
  • Can you maybe provide an example please? After that i would except that as a correct answer. Would help me a lot! – Anton Styopin Sep 29 '19 at 09:42
  • Please, find an UPDATE in my answer. Sorry for delay though. Been busy with release: https://spring.io/blog/2019/10/02/spring-integration-5-2-ga-available – Artem Bilan Oct 03 '19 at 18:53
  • Thanks for the reply and the example :) – Anton Styopin Oct 04 '19 at 06:53
  • Ok, this code example is really the same like i did. I made it work. I successfully get a reply. But i thought, that the reply arrives directly when publishSubscribeSpec.subscribe() invokes. But the reply is arriving after the whole flow finished. Is this the normal way or do i missundertand something? – Anton Styopin Oct 04 '19 at 07:23
  • That’s correct. Because you do everything in the same thread. To return control to the gateway in the beginning waiting for reply, we indeed need to finish all the work in that thread. To change behavior, you can use an `executor` for that publish-subscribe making subscribers to work in the separate threads and in most cases in parallel – Artem Bilan Oct 04 '19 at 11:53
  • I understand, thank you very much! This helped a lot! – Anton Styopin Oct 04 '19 at 13:11