1

The following bit of config accepts a HTTP POST with a JSON request body of a User instance to create, but I'm danged if I can get it to return a 201 Created. Any ideas?

@Bean
public IntegrationFlow flow(UserService userService) {
    return IntegrationFlows.from(
            Http.inboundGateway("/users")
            .requestMapping(r -> r.methods(HttpMethod.POST))
            .statusCodeFunction(f -> HttpStatus.CREATED)
            .requestPayloadType(User.class)
            .replyChannel(replyChannel())
            .requestChannel(inputChannel())
        )
        .handle((p, h) -> userService.create((User) p)).get();
}

I tried calling statusCodeFunction on the HttpRequestHandlerEndpointSpec, but I must be doing it wrong.

DeejUK
  • 12,891
  • 19
  • 89
  • 169
  • I fixed it by just replacing Http.inboundGateway with Http.inboundChannelAdapter. Can someone shed some light on why that responds with a http status and when would I use / not use inboundGateway over inboundChannelAdapter ? – johnwick0831 Nov 09 '18 at 01:41

1 Answers1

2

The answer was that statusCodeFunction only works for inbound adapters (ie things that are one-way on the way in). Kinda begs the question of why I can call it on a gateway, but ho-hum...

Using enrichHeaders on the IntegrationFlow did the trick.

@Configuration
@EnableIntegration
@Profile("integration")
public class IntegrationConfiguration {
    @Autowired
    UserService userService;

    @Bean
    public DirectChannel inputChannel() {
        return new DirectChannel();
    }

    @Bean
    public DirectChannel replyChannel() {
        return new DirectChannel();
    }

    @Bean
    public HttpRequestHandlingMessagingGateway httpGate() {
        HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
        RequestMapping requestMapping = new RequestMapping();
        requestMapping.setMethods(HttpMethod.POST);
        requestMapping.setPathPatterns("/users");
        gateway.setRequestPayloadType(User.class);
        gateway.setRequestMapping(requestMapping);
        gateway.setRequestChannel(inputChannel());
        gateway.setReplyChannel(replyChannel());
        return gateway;
    }

    @Bean
    public IntegrationFlow flow(UserService userService) {
        return IntegrationFlows.from(httpGate()).handle((p, h) -> userService.create((User) p))
                .enrichHeaders(
                        c -> c.header(org.springframework.integration.http.HttpHeaders.STATUS_CODE, HttpStatus.CREATED))
                .get();
    }
}
DeejUK
  • 12,891
  • 19
  • 89
  • 169
  • Ah! Good catch! Yep, indeed, the status code is fully related to the reply. Like we do `ResponseEntity` together with its `status`, the same is applied here for the reply. So, yes, the `HttpHeaders.STATUS_CODE` header has to be set. – Artem Bilan Oct 02 '17 at 19:57
  • I have the exact same code, but I'm still getting "No reply received within timeout" – johnwick0831 Nov 09 '18 at 01:27