|
22 | 22 | import java.net.URI;
|
23 | 23 | import java.nio.charset.StandardCharsets;
|
24 | 24 | import java.time.Duration;
|
| 25 | +import java.util.Arrays; |
25 | 26 | import java.util.Collections;
|
26 | 27 | import java.util.List;
|
27 | 28 | import java.util.Locale;
|
28 | 29 | import java.util.Map;
|
29 |
| -import java.util.concurrent.ConcurrentHashMap; |
30 |
| -import java.util.concurrent.atomic.AtomicInteger; |
31 | 30 | import java.util.function.Predicate;
|
32 | 31 |
|
33 | 32 | import com.github.benmanes.caffeine.cache.Caffeine;
|
|
40 | 39 | import jakarta.servlet.ServletRequest;
|
41 | 40 | import jakarta.servlet.ServletResponse;
|
42 | 41 | import jakarta.servlet.http.HttpServletRequest;
|
43 |
| -import org.apache.commons.logging.Log; |
44 |
| -import org.apache.commons.logging.LogFactory; |
45 | 42 | import org.assertj.core.api.Assertions;
|
46 | 43 | import org.junit.jupiter.api.Test;
|
47 | 44 |
|
|
79 | 76 | import org.springframework.util.LinkedMultiValueMap;
|
80 | 77 | import org.springframework.util.MultiValueMap;
|
81 | 78 | import org.springframework.util.StreamUtils;
|
82 |
| -import org.springframework.web.bind.annotation.GetMapping; |
83 | 79 | import org.springframework.web.bind.annotation.PostMapping;
|
84 | 80 | import org.springframework.web.bind.annotation.RequestBody;
|
85 |
| -import org.springframework.web.bind.annotation.RequestParam; |
86 | 81 | import org.springframework.web.bind.annotation.RestController;
|
87 | 82 | import org.springframework.web.servlet.function.HandlerFunction;
|
88 | 83 | import org.springframework.web.servlet.function.RouterFunction;
|
|
117 | 112 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.addRequestHeader;
|
118 | 113 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.addRequestHeadersIfNotPresent;
|
119 | 114 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.addRequestParameter;
|
120 |
| -import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.prefixPath; |
121 | 115 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.redirectTo;
|
122 | 116 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.removeRequestHeader;
|
123 | 117 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.rewritePath;
|
|
126 | 120 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.setRequestHostHeader;
|
127 | 121 | import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.stripPrefix;
|
128 | 122 | import static org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lb;
|
129 |
| -import static org.springframework.cloud.gateway.server.mvc.filter.RetryFilterFunctions.retry; |
130 | 123 | import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
|
131 | 124 | import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.forward;
|
132 | 125 | import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
|
@@ -393,20 +386,6 @@ public void circuitBreakerInvalidFallbackThrowsException() {
|
393 | 386 | // @formatter:on
|
394 | 387 | }
|
395 | 388 |
|
396 |
| - @Test |
397 |
| - public void retryWorks() { |
398 |
| - restClient.get().uri("/retry?key=get").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("3"); |
399 |
| - // test for: java.lang.IllegalArgumentException: You have already selected another |
400 |
| - // retry policy |
401 |
| - restClient.get() |
402 |
| - .uri("/retry?key=get2") |
403 |
| - .exchange() |
404 |
| - .expectStatus() |
405 |
| - .isOk() |
406 |
| - .expectBody(String.class) |
407 |
| - .isEqualTo("3"); |
408 |
| - } |
409 |
| - |
410 | 389 | @Test
|
411 | 390 | public void rateLimitWorks() {
|
412 | 391 | restClient.get().uri("/anything/ratelimit").exchange().expectStatus().isOk();
|
@@ -484,7 +463,7 @@ public void rewritePathPostWorks() {
|
484 | 463 | @Test
|
485 | 464 | public void rewritePathPostLocalWorks() {
|
486 | 465 | restClient.post()
|
487 |
| - .uri("/baz/post") |
| 466 | + .uri("/baz/localpost") |
488 | 467 | .bodyValue("hello")
|
489 | 468 | .header("Host", "www.rewritepathpostlocal.org")
|
490 | 469 | .exchange()
|
@@ -636,8 +615,21 @@ private MultiValueMap<String, HttpEntity<?>> createMultipartData() {
|
636 | 615 | private void assertMultipartData(Map responseBody) {
|
637 | 616 | Map<String, Object> files = (Map<String, Object>) responseBody.get("files");
|
638 | 617 | assertThat(files).containsKey("imgpart");
|
639 |
| - String file = (String) files.get("imgpart"); |
640 |
| - assertThat(file).startsWith("data:").contains(";base64,"); |
| 618 | + Object imgpart = files.get("imgpart"); |
| 619 | + if (imgpart instanceof List l) { |
| 620 | + String file = (String) l.get(0); |
| 621 | + assertThat(isPNG(file.getBytes())); |
| 622 | + } |
| 623 | + else { |
| 624 | + String file = (String) imgpart; |
| 625 | + assertThat(file).startsWith("data:").contains(";base64,"); |
| 626 | + } |
| 627 | + } |
| 628 | + |
| 629 | + private static boolean isPNG(byte[] bytes) { |
| 630 | + byte[] pngSignature = { (byte) 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; |
| 631 | + byte[] header = Arrays.copyOf(bytes, pngSignature.length); |
| 632 | + return Arrays.equals(pngSignature, header); |
641 | 633 | }
|
642 | 634 |
|
643 | 635 | @Test
|
@@ -991,11 +983,6 @@ TestHandler testHandler() {
|
991 | 983 | return new TestHandler();
|
992 | 984 | }
|
993 | 985 |
|
994 |
| - @Bean |
995 |
| - RetryController retryController() { |
996 |
| - return new RetryController(); |
997 |
| - } |
998 |
| - |
999 | 986 | @Bean
|
1000 | 987 | EventController eventController() {
|
1001 | 988 | return new EventController();
|
@@ -1180,19 +1167,6 @@ public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerNoFall
|
1180 | 1167 | // @formatter:on
|
1181 | 1168 | }
|
1182 | 1169 |
|
1183 |
| - @Bean |
1184 |
| - public RouterFunction<ServerResponse> gatewayRouterFunctionsRetry() { |
1185 |
| - // @formatter:off |
1186 |
| - return route("testretry") |
1187 |
| - .route(path("/retry"), http()) |
1188 |
| - .before(new LocalServerPortUriResolver()) |
1189 |
| - .filter(retry(3)) |
1190 |
| - //.filter(retry(config -> config.setRetries(3).setSeries(Set.of(HttpStatus.Series.SERVER_ERROR)).setMethods(Set.of(HttpMethod.GET, HttpMethod.POST)))) |
1191 |
| - .filter(prefixPath("/do")) |
1192 |
| - .build(); |
1193 |
| - // @formatter:on |
1194 |
| - } |
1195 |
| - |
1196 | 1170 | @Bean
|
1197 | 1171 | public RouterFunction<ServerResponse> gatewayRouterFunctionsRateLimit() {
|
1198 | 1172 | // @formatter:off
|
@@ -1279,8 +1253,7 @@ public RouterFunction<ServerResponse> gatewayRouterFunctionsForm() {
|
1279 | 1253 | // @formatter:off
|
1280 | 1254 | return route("testform")
|
1281 | 1255 | .POST("/post", host("**.testform.org"), http())
|
1282 |
| - .before(new LocalServerPortUriResolver()) |
1283 |
| - .filter(prefixPath("/test")) |
| 1256 | + .filter(new HttpbinUriResolver()) |
1284 | 1257 | .filter(addRequestHeader("X-Test", "form"))
|
1285 | 1258 | .build();
|
1286 | 1259 | // @formatter:on
|
@@ -1677,37 +1650,6 @@ public ResponseEntity<Event> messageChannelEvents(@RequestBody Event e) {
|
1677 | 1650 |
|
1678 | 1651 | }
|
1679 | 1652 |
|
1680 |
| - @RestController |
1681 |
| - protected static class RetryController { |
1682 |
| - |
1683 |
| - Log log = LogFactory.getLog(getClass()); |
1684 |
| - |
1685 |
| - ConcurrentHashMap<String, AtomicInteger> map = new ConcurrentHashMap<>(); |
1686 |
| - |
1687 |
| - @GetMapping("/do/retry") |
1688 |
| - public ResponseEntity<String> retry(@RequestParam("key") String key, |
1689 |
| - @RequestParam(name = "count", defaultValue = "3") int count, |
1690 |
| - @RequestParam(name = "failStatus", required = false) Integer failStatus) { |
1691 |
| - AtomicInteger num = getCount(key); |
1692 |
| - int i = num.incrementAndGet(); |
1693 |
| - log.warn("Retry count: " + i); |
1694 |
| - String body = String.valueOf(i); |
1695 |
| - if (i < count) { |
1696 |
| - HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; |
1697 |
| - if (failStatus != null) { |
1698 |
| - httpStatus = HttpStatus.resolve(failStatus); |
1699 |
| - } |
1700 |
| - return ResponseEntity.status(httpStatus).header("X-Retry-Count", body).body("temporarily broken"); |
1701 |
| - } |
1702 |
| - return ResponseEntity.status(HttpStatus.OK).header("X-Retry-Count", body).body(body); |
1703 |
| - } |
1704 |
| - |
1705 |
| - AtomicInteger getCount(String key) { |
1706 |
| - return map.computeIfAbsent(key, s -> new AtomicInteger()); |
1707 |
| - } |
1708 |
| - |
1709 |
| - } |
1710 |
| - |
1711 | 1653 | protected static class TestHandler implements HandlerFunction<ServerResponse> {
|
1712 | 1654 |
|
1713 | 1655 | @Override
|
|
0 commit comments