From c0ec9cdd168dde3173377429acca6e8e4c92ac4a Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 27 Jan 2017 17:06:42 -0700 Subject: [PATCH] Change RouteReader.getRoutes() from List to Flux --- .../gateway/actuate/GatewayEndpoint.java | 19 +++++---- .../gateway/api/CompositeRouteReader.java | 22 ++++++++++ .../cloud/gateway/api/RouteReader.java | 4 +- .../gateway/config/PropertiesRouteReader.java | 6 +-- .../handler/RoutePredicateHandlerMapping.java | 4 +- .../gateway/test/GatewayIntegrationTests.java | 40 ++++++++++--------- 6 files changed, 63 insertions(+), 32 deletions(-) create mode 100644 src/main/java/org/springframework/cloud/gateway/api/CompositeRouteReader.java diff --git a/src/main/java/org/springframework/cloud/gateway/actuate/GatewayEndpoint.java b/src/main/java/org/springframework/cloud/gateway/actuate/GatewayEndpoint.java index 5d1295ca..25705d1b 100644 --- a/src/main/java/org/springframework/cloud/gateway/actuate/GatewayEndpoint.java +++ b/src/main/java/org/springframework/cloud/gateway/actuate/GatewayEndpoint.java @@ -16,6 +16,8 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + /** * @author Spencer Gibb */ @@ -70,22 +72,23 @@ public class GatewayEndpoint {/*extends AbstractEndpoint> {* } @GetMapping("/routes") - public List routes() { - return this.routeReader.getRoutes(); + public Mono> routes() { + return this.routeReader.getRoutes().collectList(); } @GetMapping("/routes/{id}") - public Route route(@PathVariable String id) { - return this.routeReader.getRoutes().stream() + public Mono route(@PathVariable String id) { + return this.routeReader.getRoutes() .filter(route -> route.getId().equals(id)) - .findFirst().get(); + .singleOrEmpty(); } @GetMapping("/routes/{id}/combinedfilters") public Map combinedfilters(@PathVariable String id) { - final Optional route = this.routeReader.getRoutes().stream() + Mono route = this.routeReader.getRoutes() .filter(r -> r.getId().equals(id)) - .findFirst(); - return getNamesToOrders(this.filteringWebHandler.combineFiltersForRoute(route)); + .singleOrEmpty(); + Optional optional = Optional.ofNullable(route.block()); //TODO: remove block(); + return getNamesToOrders(this.filteringWebHandler.combineFiltersForRoute(optional)); } } diff --git a/src/main/java/org/springframework/cloud/gateway/api/CompositeRouteReader.java b/src/main/java/org/springframework/cloud/gateway/api/CompositeRouteReader.java new file mode 100644 index 00000000..c2b4d76b --- /dev/null +++ b/src/main/java/org/springframework/cloud/gateway/api/CompositeRouteReader.java @@ -0,0 +1,22 @@ +package org.springframework.cloud.gateway.api; + +import org.springframework.cloud.gateway.config.Route; + +import reactor.core.publisher.Flux; + +/** + * @author Spencer Gibb + */ +public class CompositeRouteReader implements RouteReader { + + private final Flux delegates; + + public CompositeRouteReader(Flux delegates) { + this.delegates = delegates; + } + + @Override + public Flux getRoutes() { + return this.delegates.flatMap(RouteReader::getRoutes); + } +} diff --git a/src/main/java/org/springframework/cloud/gateway/api/RouteReader.java b/src/main/java/org/springframework/cloud/gateway/api/RouteReader.java index c0944fa1..de3dd1cd 100644 --- a/src/main/java/org/springframework/cloud/gateway/api/RouteReader.java +++ b/src/main/java/org/springframework/cloud/gateway/api/RouteReader.java @@ -2,12 +2,12 @@ package org.springframework.cloud.gateway.api; import org.springframework.cloud.gateway.config.Route; -import java.util.List; +import reactor.core.publisher.Flux; /** * @author Spencer Gibb */ public interface RouteReader { - List getRoutes(); + Flux getRoutes(); } diff --git a/src/main/java/org/springframework/cloud/gateway/config/PropertiesRouteReader.java b/src/main/java/org/springframework/cloud/gateway/config/PropertiesRouteReader.java index 07a8d5a8..5be5c23b 100644 --- a/src/main/java/org/springframework/cloud/gateway/config/PropertiesRouteReader.java +++ b/src/main/java/org/springframework/cloud/gateway/config/PropertiesRouteReader.java @@ -2,7 +2,7 @@ package org.springframework.cloud.gateway.config; import org.springframework.cloud.gateway.api.RouteReader; -import java.util.List; +import reactor.core.publisher.Flux; /** * @author Spencer Gibb @@ -16,7 +16,7 @@ public class PropertiesRouteReader implements RouteReader { } @Override - public List getRoutes() { - return this.properties.getRoutes(); + public Flux getRoutes() { + return Flux.fromIterable(this.properties.getRoutes()); } } diff --git a/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java b/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java index bb2a07ee..3f42ed92 100644 --- a/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java +++ b/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java @@ -16,6 +16,7 @@ import org.springframework.web.reactive.handler.AbstractHandlerMapping; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebHandler; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_HANDLER_MAPPER_ATTR; @@ -60,7 +61,8 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { @Override protected void initApplicationContext() throws BeansException { super.initApplicationContext(); - registerHandlers(this.routeReader.getRoutes()); + Flux routes = this.routeReader.getRoutes(); + registerHandlers(routes.collectList().block()); //TODO: convert rest of class to Reactive } protected void registerHandlers(List routes) { diff --git a/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java b/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java index 2a1dc046..1435a790 100644 --- a/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java +++ b/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java @@ -44,7 +44,7 @@ public class GatewayIntegrationTests { private static final String HANDLER_MAPPER_HEADER = "X-Gateway-Handler-Mapper-Class"; private static final String ROUTE_ID_HEADER = "X-Gateway-Route-Id"; - public static final Duration DURATION = Duration.ofSeconds(3); + public static final Duration DURATION = Duration.ofSeconds(5); @LocalServerPort private int port; @@ -65,7 +65,7 @@ public class GatewayIntegrationTests { @Test public void addRequestHeaderFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers") + GET(baseUrl() + "/headers") .header("Host", "www.addrequestheader.org") .build() ).then(response -> response.body(toMono(Map.class))); @@ -93,7 +93,7 @@ public class GatewayIntegrationTests { private void testRequestParameterFilter(String query) { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/get" + query) + GET(baseUrl() + "/get" + query) .header("Host", "www.addrequestparameter.org") .build() ).then(response -> response.body(toMono(Map.class))); @@ -112,7 +112,7 @@ public class GatewayIntegrationTests { @Test public void addResponseHeaderFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers") + GET(baseUrl() + "/headers") .header("Host", "www.addresponseheader.org") .build() ); @@ -131,7 +131,7 @@ public class GatewayIntegrationTests { @Test public void compositeRouteWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers?foo=bar&baz") + GET(baseUrl() + "/headers?foo=bar&baz") .header("Host", "www.foo.org") .header("X-Request-Id", "123") .cookie("chocolate", "chip") @@ -158,7 +158,7 @@ public class GatewayIntegrationTests { @Test public void hostRouteWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/get") + GET(baseUrl() + "/get") .header("Host", "www.example.org") .build() ); @@ -181,7 +181,7 @@ public class GatewayIntegrationTests { @Test public void hystrixFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/get") + GET(baseUrl() + "/get") .header("Host", "www.hystrixsuccess.org") .build() ); @@ -202,7 +202,7 @@ public class GatewayIntegrationTests { @Test public void hystrixFilterTimesout() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/delay/3") + GET(baseUrl() + "/delay/3") .header("Host", "www.hystrixfailure.org") .build() ); @@ -215,7 +215,7 @@ public class GatewayIntegrationTests { @Test public void loadBalancerFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/get") + GET(baseUrl() + "/get") .header("Host", "www.loadbalancerclient.org") .build() ); @@ -235,7 +235,7 @@ public class GatewayIntegrationTests { @Test public void postWorks() { - ClientRequest> request = POST("http://localhost:" + port + "/post") + ClientRequest> request = POST(baseUrl() + "/post") .header("Host", "www.example.org") .body(Mono.just("testdata"), String.class); @@ -251,7 +251,7 @@ public class GatewayIntegrationTests { @Test public void redirectToFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port) + GET(baseUrl()) .header("Host", "www.redirectto.org") .build() ); @@ -273,7 +273,7 @@ public class GatewayIntegrationTests { @SuppressWarnings("unchecked") public void removeRequestHeaderFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers") + GET(baseUrl() + "/headers") .header("Host", "www.removerequestheader.org") .header("X-Request-Foo", "Bar") .build() @@ -293,7 +293,7 @@ public class GatewayIntegrationTests { @Test public void removeResponseHeaderFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers") + GET(baseUrl() + "/headers") .header("Host", "www.removereresponseheader.org") .build() ); @@ -311,7 +311,7 @@ public class GatewayIntegrationTests { @Test public void rewritePathFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/foo/get") + GET(baseUrl() + "/foo/get") .header("Host", "www.baz.org") .build() ); @@ -329,7 +329,7 @@ public class GatewayIntegrationTests { @Test public void setPathFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/foo/get") + GET(baseUrl() + "/foo/get") .header("Host", "www.setpath.org") .build() ); @@ -347,7 +347,7 @@ public class GatewayIntegrationTests { @Test public void setResponseHeaderFilterWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers") + GET(baseUrl() + "/headers") .header("Host", "www.setreresponseheader.org") .build() ); @@ -375,7 +375,7 @@ public class GatewayIntegrationTests { private void setStatusStringTest(String host, HttpStatus status) { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/headers") + GET(baseUrl() + "/headers") .header("Host", host) .build() ); @@ -393,7 +393,7 @@ public class GatewayIntegrationTests { @Test public void urlRouteWorks() { Mono result = webClient.exchange( - GET("http://localhost:" + port + "/get").build() + GET(baseUrl() + "/get").build() ); StepVerifier.create(result) @@ -411,6 +411,10 @@ public class GatewayIntegrationTests { .verify(DURATION); } + private String baseUrl() { + return "http://localhost:" + port; + } + @EnableAutoConfiguration @SpringBootConfiguration public static class TestConfig {