I have a spring integration flow that expects a "routingkey" message header. If this is not present I'd like to send a HTTP 400 response back to the client. How can I do that? Below you will see the determineRoutingKey method is where I can determine whether the routing key was passed as a header.
@Bean
public IntegrationFlow webToRabbit(RabbitTemplate amqpTemplate)
{
return IntegrationFlows
.from
(
Http.inboundGateway("/tunnel")
.replyTimeout(Integer.valueOf(timeout))
.mappedRequestHeaders("*")
.mappedResponseHeaders("*")
)
.log()
.handle
(
Amqp.outboundGateway(amqpTemplate)
.exchangeName(exchangeName)
.routingKeyFunction(f->determineRoutingKey(f))
.mappedRequestHeaders("*")
.mappedReplyHeaders("*")
)
.log()
.bridge(null)
.get();
}
private String determineRoutingKey(Message<?> message)
{
MessageHeaders headers = message.getHeaders();
if(headers.containsKey(HEADER_ROUTINGKEY))
{
String routingKey = Objects.toString(headers.get(HEADER_ROUTINGKEY));
log.debug("Using routing key: " + routingKey);
return routingKey;
}
else
{
log.error("Headers found: " + Objects.toString(headers));
//Here I get an exception stating that MessageHeaaders is immutable
message.getHeaders().put(HttpHeaders.STATUS_CODE, HttpStatus.BAD_REQUEST);
return null;
}
}
Thanks in advance for the help.
There is a logic like:
private HttpStatus resolveHttpStatusFromHeaders(MessageHeaders headers) {
Object httpStatusFromHeader = headers.get(org.springframework.integration.http.HttpHeaders.STATUS_CODE);
return buildHttpStatus(httpStatusFromHeader);
}
So, what you need is just regular (string with error message?) reply and an appropriate HttpStatus.BAD_REQUEST as a http_statusCode header.
No reason in any exceptions.
UPDATE
Since you are in the middle of the flow and it is still far away from the reply, you can stick with that exception approach.
What you have to do there to return proper 400 response is an errorChannel on the Http.inboundGateway() and some simple transformer to returns a Message with an appropriate HttpHeaders.STATUS_CODE header:
Http.inboundGateway("/tunnel")
.errorChannel("httpErrorFlow.input")
...
@Bean
public IntegrationFlow httpErrorFlow() {
return f -> f
.<RuntimeException, Message<?>>transform(payload -> {
if (payload.getCause() instanceof MyRoutingKeyException) {
return MessageBuilder.withPayload("Bad routing key")
.setHeader(HttpHeaders.STATUS_CODE, HttpStatus.BAD_REQUEST)
.build();
}
throw payload;
});
}
But again: you can't just throw an exception.
That is
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With