diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactory.java index 90c18cc8..3bfe4f54 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactory.java @@ -41,6 +41,8 @@ import org.springframework.util.Assert; import org.springframework.web.server.ServerWebExchange; public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory { + + public static final String RETRY_ITERATION_KEY = "retry_iteration"; private static final Log log = LogFactory.getLog(RetryGatewayFilterFactory.class); public RetryGatewayFilterFactory() { @@ -51,7 +53,7 @@ public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory> predicate = context -> { + Predicate> repeatPredicate = context -> { ServerWebExchange exchange = context.applicationContext(); if (exceedsMaxIterations(exchange, retryConfig)) { return false; @@ -72,7 +74,7 @@ public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory repeat = Repeat.onlyIf(predicate) + Repeat repeat = Repeat.onlyIf(repeatPredicate) .doOnRepeat(context -> reset(context.applicationContext())); //TODO: support timeout, backoff, jitter, etc... in Builder @@ -97,7 +99,7 @@ public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory= retryConfig.getRetries(); @@ -117,10 +119,11 @@ public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory { log.trace("Entering retry-filter"); - int iteration = exchange.getAttributeOrDefault("retry_iteration", -1); - exchange.getAttributes().put("retry_iteration", iteration + 1); - return Mono.fromDirect(chain.filter(exchange) + .doOnSuccessOrError((aVoid, throwable) -> { + int iteration = exchange.getAttributeOrDefault(RETRY_ITERATION_KEY, -1); + exchange.getAttributes().put(RETRY_ITERATION_KEY, iteration + 1); + }) .log("retry-filter", Level.INFO) .retryWhen(retry.withApplicationContext(exchange)) .repeatWhen(repeat.withApplicationContext(exchange))); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryConfigGatewayFilterFactoryIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java similarity index 85% rename from spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryConfigGatewayFilterFactoryIntegrationTests.java rename to spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java index bb2d2a7f..1eac3a9a 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryConfigGatewayFilterFactoryIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java @@ -53,7 +53,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) @DirtiesContext -public class RetryConfigGatewayFilterFactoryIntegrationTests extends BaseWebClientTests { +public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTests { @Test public void retryFilterGet() { @@ -64,6 +64,18 @@ public class RetryConfigGatewayFilterFactoryIntegrationTests extends BaseWebClie .expectBody(String.class).isEqualTo("3"); } + @Test + public void retryFilterFailure() { + testClient.get() + .uri("/retryalwaysfail?key=getjavafailure&count=4") + .header(HttpHeaders.HOST, "www.retryjava.org") + .exchange() + .expectStatus().is5xxServerError() + .expectBody(String.class).consumeWith(result -> { + assertThat(result.getResponseBody()).contains("permanently broken"); + }); + } + @Test public void retryFilterGetJavaDsl() { testClient.get() @@ -115,6 +127,14 @@ public class RetryConfigGatewayFilterFactoryIntegrationTests extends BaseWebClie ConcurrentHashMap map = new ConcurrentHashMap<>(); + @RequestMapping("/httpbin/retryalwaysfail") + public String retryalwaysfail(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count) { + AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger()); + int i = num.incrementAndGet(); + log.warn("Retry count: "+i); + throw new RuntimeException("permanently broken"); + } + @RequestMapping("/httpbin/retry") public String retry(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count) { AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger());