From d17630f4f2ec8cb8a0b5266a1b915ed145fbf323 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Wed, 3 Jul 2019 15:23:03 -0400 Subject: [PATCH 1/2] Verify body is still sent during post retry --- ...yGatewayFilterFactoryIntegrationTests.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java index f81d5b20..f5511e03 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java @@ -46,6 +46,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -83,7 +84,7 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest @Test public void retryFilterPost() { - testClient.post().uri("/retry?key=post") + testClient.post().uri("/retrypost?key=post&expectedbody=Hello") .header(HttpHeaders.HOST, "www.retryjava.org").syncBody("Hello") .exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("3"); } @@ -119,7 +120,7 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest @RequestMapping("/httpbin/retryalwaysfail") public ResponseEntity retryalwaysfail(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count) { - AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger()); + AtomicInteger num = getCount(key); int i = num.incrementAndGet(); log.warn("Retry count: " + i); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) @@ -127,10 +128,24 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest .body("permanently broken"); } + @RequestMapping("/httpbin/retrypost") + public ResponseEntity retry(@RequestParam("key") String key, + @RequestParam(name = "count", defaultValue = "3") int count, + @RequestParam("expectedbody") String expectedbody, @RequestBody String body) { + ResponseEntity response = retry(key, count); + if (!expectedbody.equals(body)) { + AtomicInteger num = getCount(key); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .header("X-Retry-Count", String.valueOf(num)) + .body("bodys did not match on try" + num); + } + return response; + } + @RequestMapping("/httpbin/retry") public ResponseEntity retry(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count) { - AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger()); + AtomicInteger num = getCount(key); int i = num.incrementAndGet(); log.warn("Retry count: " + i); String body = String.valueOf(i); @@ -142,6 +157,10 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest .body(body); } + AtomicInteger getCount(@RequestParam("key") String key) { + return map.computeIfAbsent(key, s -> new AtomicInteger()); + } + @Bean public RouteLocator hystrixRouteLocator(RouteLocatorBuilder builder) { return builder.routes() From dc4ed76b57f8276dd807141fa57de3e8f0a0f76a Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Wed, 10 Jul 2019 17:06:34 -0500 Subject: [PATCH 2/2] Set routeId on configurations from route definitions. fixes gh-1160 --- .../gateway/route/RouteDefinitionRouteLocator.java | 8 ++++++++ .../RetryGatewayFilterFactoryIntegrationTests.java | 11 ++++++++++- .../src/test/resources/application.yml | 10 ++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocator.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocator.java index 54463142..72b9ed44 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocator.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocator.java @@ -41,6 +41,7 @@ import org.springframework.cloud.gateway.handler.AsyncPredicate; import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory; import org.springframework.cloud.gateway.support.ConfigurationUtils; +import org.springframework.cloud.gateway.support.HasRouteId; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.core.Ordered; @@ -173,6 +174,13 @@ public class RouteDefinitionRouteLocator ConfigurationUtils.bind(configuration, properties, factory.shortcutFieldPrefix(), definition.getName(), validator); + // some filters require routeId + // TODO: is there a better place to apply this? + if (configuration instanceof HasRouteId) { + HasRouteId hasRouteId = (HasRouteId) configuration; + hasRouteId.setRouteId(id); + } + GatewayFilter gatewayFilter = factory.apply(configuration); if (this.publisher != null) { this.publisher.publishEvent(new FilterArgsEvent(this, id, properties)); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java index f5511e03..4267b218 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java @@ -84,6 +84,14 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest @Test public void retryFilterPost() { + testClient.post().uri("/retrypost?key=postconfig&expectedbody=HelloConfig") + .header(HttpHeaders.HOST, "www.retrypostconfig.org") + .syncBody("HelloConfig").exchange().expectStatus().isOk() + .expectBody(String.class).isEqualTo("3"); + } + + @Test + public void retryFilterPostJavaDsl() { testClient.post().uri("/retrypost?key=post&expectedbody=Hello") .header(HttpHeaders.HOST, "www.retryjava.org").syncBody("Hello") .exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("3"); @@ -131,7 +139,8 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest @RequestMapping("/httpbin/retrypost") public ResponseEntity retry(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count, - @RequestParam("expectedbody") String expectedbody, @RequestBody String body) { + @RequestParam("expectedbody") String expectedbody, + @RequestBody String body) { ResponseEntity response = retry(key, count); if (!expectedbody.equals(body)) { AtomicInteger num = getCount(key); diff --git a/spring-cloud-gateway-core/src/test/resources/application.yml b/spring-cloud-gateway-core/src/test/resources/application.yml index 29f27f06..06ccc646 100644 --- a/spring-cloud-gateway-core/src/test/resources/application.yml +++ b/spring-cloud-gateway-core/src/test/resources/application.yml @@ -251,6 +251,16 @@ spring: filters: - Retry + # ===================================== + - id: retry_post_test + uri: ${test.uri} + predicates: + - Host=**.retrypostconfig.org + filters: + - name: Retry + args: + methods: GET,POST + # ===================================== - id: secure_headers_test uri: ${test.uri}