spring-projects / spring-integration-samples

You are looking for examples, code snippets, sample applications for Spring Integration? This is the place.

Home Page:http://www.springsource.org/spring-integration

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Any example of dsl integration with circuit breaker and retry

ankitgoelvirgo opened this issue · comments

Hi, Do you have any example of dsl integration with circuit breaker and retry.

Thank you.

@artembilan @garyrussell , any help would be highly appreciated. I am struggling to do retries to a http outbound webservice call using dsl integration

That was holiday period and we have come back to work only today, so sorry for the late reply if that.

The solution is like a RequestHandlerRetryAdvice injected into the endpoint configurer in the .handle() EIP-method for the mentioned http outbound:

.handle(Http.outboundGateway("/service/internal?{params}")
									.uriVariable("params", "payload")
									.expectedResponseType(String.class),
							e -> e.id("serviceInternalGateway")
									.advice(retryAdvice()))

Where retryAdvice() is a regular @Bean definition for the RequestHandlerRetryAdvice. The same is applied for the RequestHandlerCircuitBreakerAdvice and you can specify both of them in the mentioned .advice() configurer method.

I think we can just go ahead and add a Spring Boot, Java DSL-based configuration variant into the existing Retry sample: https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/retry-and-more

Hi @artembilan , thank you for your reply.
I did try the following code.

IntegrationFlows
                .from(emailDemoChannel)
                  .log(LoggingHandler.Level.INFO, "customer", m -> m.getPayload().toString())
                .handle(Http.outboundGateway(EMAIL_PROVIDER_URI)
                        .httpMethod(HttpMethod.GET)
                        .requestFactory(simpleClientHttpRequestFactory())
                        .expectedResponseType(String.class), e -> e.advice(this.retryAdvice(retryPolicy(),fixedBackOffPolicy())))
                .log(LoggingHandler.Level.DEBUG, "response", m -> m.getPayload())
                .log(LoggingHandler.Level.DEBUG, "response", m -> m.getHeaders())
                .channel(responseChannel)
                .get();

In the logs I was expecting to see connection refused exceptions and retries as my third party email service was down. But I could only see that exception once and even if I switched the third party service on , it still didn't retry and hit the url.

So, here is a simple Spring Boot application with such a retry advice:

@SpringBootApplication
public class SpringIntegrationDslHttpRetryApplication {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext =
				SpringApplication.run(SpringIntegrationDslHttpRetryApplication.class, args);
		Function<Object, Object> function = applicationContext.getBean(Function.class);
		function.apply("foo");
	}

	@Bean
	public IntegrationFlow httpRetryFlow() {
		return IntegrationFlows.from(Function.class)
				.handle(Http.outboundGateway("http://localhost:11111")
								.httpMethod(HttpMethod.GET)
								.expectedResponseType(String.class),
						e -> e.advice(retryAdvice()))
				.get();
	}

	@Bean
	public RequestHandlerRetryAdvice retryAdvice() {
		return new RequestHandlerRetryAdvice();
	}

}

In the application.properties I have something like this:

logging.level.org.springframework.retry=debug

And after running this application I get this logs:

2019-01-03 14:15:12.123  INFO 508 --- [           main] SpringIntegrationDslHttpRetryApplication : Started SpringIntegrationDslHttpRetryApplication in 1.075 seconds (JVM running for 2.742)
2019-01-03 14:15:12.132 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Retry: count=0
2019-01-03 14:15:13.156 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Checking for rethrow: count=1
2019-01-03 14:15:13.156 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Retry: count=1
2019-01-03 14:15:14.160 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Checking for rethrow: count=2
2019-01-03 14:15:14.160 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Retry: count=2
2019-01-03 14:15:15.161 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Checking for rethrow: count=3
2019-01-03 14:15:15.161 DEBUG 508 --- [           main] o.s.retry.support.RetryTemplate          : Retry failed last attempt: count=3
Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:11111": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:743)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:709)
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:597)
	at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.exchange(HttpRequestExecutingMessageHandler.java:165)

So, retry works well on this service activator and I really see an exception in logs only after the last failed attempt.
If the service is available, we are not going to retry at all and will succeed just on the Retry: count=0.

Does it make sense?

Not sure what you expect from here, but maybe you need to make you familiar with the retry framework first of all: https://github.com/spring-projects/spring-retry

Thank you. I will play around.

@artembilan thx for that! Would be great to add it to the dsl examples...