Spring integration Java DSL http outbound

196 Views Asked by At

How to resend same or modified message from outbound http call in case of specific client error responses like 400, 413 etc

@Bean
private IntegrationFlow myChannel() {
    IntegrationFlowBuilder builder = 
             IntegrationFlows.from(queue)
              .handle(//http post method config)
                    ...
                  .expectedResponseType(String.class))
              .channel(MessageChannels.publishSubscribe(channel2));
   return builder.get();
}

@Bean
private IntegrationFlow defaultErrorChannel() {
    
}

EDIT: Added end point to handle method

@Bean
private IntegrationFlow myChannel() {
    IntegrationFlowBuilder builder = 
             IntegrationFlows.from(queue)
              .handle(//http post method config)
                    ...
                  .expectedResponseType(String.class), 
                               e -> e.advice(myRetryAdvice()))
              .channel(MessageChannels.publishSubscribe(channel2));
   return builder.get();
}

@Bean
public Advice myRetryAdvice(){
 ... // set custom retry policy
}

Custom Retry policy:

class InternalServerExceptionClassifierRetryPolicy extends 
      ExceptionClassifierRetryPolicy {
    public InternalServerExceptionClassifierRetryPolicy() {
       final SimpleRetryPolicy simpleRetryPolicy = 
                  new SimpleRetryPolicy();
    simpleRetryPolicy.setMaxAttempts(2);

    this.setExceptionClassifier(new Classifier<Throwable, RetryPolicy>() {
        @Override
        public RetryPolicy classify(Throwable classifiable) {
            if (classifiable instanceof HttpServerErrorException) {
                // For specifically 500 and 504
                if (((HttpServerErrorException) classifiable).getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR
                        || ((HttpServerErrorException) classifiable)
                                .getStatusCode() == HttpStatus.GATEWAY_TIMEOUT) {
                    return simpleRetryPolicy;
                }
                return new NeverRetryPolicy();
            }
            return new NeverRetryPolicy();
        }
    }); 
}}

EDIT 2: Override open() to modify the original message

    RequestHandlerRetryAdvice retryAdvice = new 
    RequestHandlerRetryAdvice(){
    @Override
    public<T, E extends Throwable> boolean open(RetryContext 
    retryContext, RetryCallback<T,E> callback){
    Message<String> originalMsg = 
(Message)  retryContext.getAttribute(ErrorMessageUtils.FAILED_MESSAGE_CONTEXT); 
   Message<String> updatedMsg = //some updated message

retryContext.setAttribute(ErrorMessageUtils.FAILED_MESSAGE_CONTEXT,up datedMsg); return super.open(retryContext, callback); }

1

There are 1 best solutions below

7
Artem Bilan On

See a RequestHandlerRetryAdvice: https://docs.spring.io/spring-integration/reference/html/messaging-endpoints.html#message-handler-advice-chain. So, you configure some RetryPolicy to check those HttpClientErrorException for retry and the framework will re-send for you.

Java DSL allows us to configure it via second handle() argument - endpoint configurer: .handle(..., e -> e.advice(myRetryAdvice)): https://docs.spring.io/spring-integration/reference/html/dsl.html#java-dsl-endpoints