Basically my use-case is to retry an http -request when a 401 occurs in an HttpOutboundGateway request . The request comes from a jms broker into the integration flow .
@Bean
IntegrationFlow bank2wallet(ConnectionFactory jmsConnectionFactory,
MessageHandler creditWalletHttpGateway) {
return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory)
.destination(cp.getTransactionIn()))
.<String, CreditRequest>transform(
request -> new Gson().fromJson(request, CreditRequest.class))
.enrichHeaders((headerEnricherSpec -> {
// Todo get token from cache
headerEnricherSpec.header(HttpHeaders.AUTHORIZATION, String.join(" ", "Bearer", ""));
headerEnricherSpec.header(HttpHeaders.ACCEPT, "application/json");
headerEnricherSpec.header(HttpHeaders.CONTENT_TYPE, "application/json");
}))
.handle(creditWalletHttpGateway, (e) -> e.advice(retryAdvice()))
.get();
}
@Bean
MessageHandler creditWalletHttpGateway( @Value("${api.base.uri:https:/localhost/v3/sync}") URI uri) {
HttpRequestExecutingMessageHandler httpHandler = new HttpRequestExecutingMessageHandler(uri);
httpHandler.setExpectedResponseType(CreditResponse.class);
httpHandler.setHttpMethod(HttpMethod.POST);
return httpHandler;
}
@Bean
RequestHandlerRetryAdvice retryAdvice() {
RequestHandlerRetryAdvice requestHandlerRetryAdvice = new RequestHandlerRetryAdvice();
requestHandlerRetryAdvice.setRecoveryCallback(errorMessageSendingRecoverer());
return requestHandlerRetryAdvice;
}
@Bean
ErrorMessageSendingRecoverer errorMessageSendingRecoverer() {
return new ErrorMessageSendingRecoverer(recoveryChannel());
}
@Bean
MessageChannel recoveryChannel() {
return new DirectChannel();
}
@Bean
MessageChannel retryChannel() {
return new DirectChannel();
}
@Bean
IntegrationFlow handleRecovery() {
return IntegrationFlows.from("recoveryChannel")
.log(Level.ERROR, "error", m -> m.getPayload())
.<RuntimeException>handle((message) -> {
MessagingException exception = (MessagingException) message.getPayload();
Message<CreditRequest> originalCreditRequest = (Message<CreditRequest>) exception.getFailedMessage();
// String token = gateway.getToken(configProperties);
String token = UUID.randomUUID().toString();
Message<CreditRequest> c = MessageBuilder.fromMessage(originalCreditRequest)
.setHeader(ApiConstants.AUTHORIZATION, String.join(" ", "Bearer", token))
.copyHeaders(message.getHeaders())
.build();
retryChannel().send(c);
})
.get();
}
@Bean
IntegrationFlow creditRequestFlow() {
return IntegrationFlows.from(retryChannel())
.log(Level.INFO, "info", m -> m.getPayload())
.handle(Http.outboundGateway("https://localhost/v3/sync")
.httpMethod(HttpMethod.POST)
.expectedResponseType(CreditResponse.class))
.get();
}
Headers are enriched with the appropriate http header, Then i have an advice that retries the request with default simple policy , the issue with RequestHandlerAdvice approach is that it defaults the Exception Message in the handleRecovery Flow to a none HttpException class (MessageException), hence i cant check for HttpStatus code to re-route the message. So my question is basically how do i design a flow that retries a HttpOutBoundRequest based on HttpStatus 401.