From 2bbf748fcdcda955bf50213d132adfb7556ccaea Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 7 Aug 2018 13:20:16 -0400 Subject: [PATCH] Calls to filter(collection) will now transform non-Ordered filters to Ordered filters. fixes gh-445 --- .../route/builder/GatewayFilterSpec.java | 26 +++++++++++++++---- .../route/builder/GatewayFilterSpecTests.java | 23 +++++++++++++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java index 32c40dcf7..a64af9334 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java @@ -20,12 +20,18 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.Collection; +import java.util.List; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import reactor.retry.Repeat; +import reactor.retry.Retry; + import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.OrderedGatewayFilter; @@ -59,9 +65,6 @@ import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.web.server.ServerWebExchange; -import reactor.retry.Repeat; -import reactor.retry.Retry; - /** * Applies specific filters to routes. */ @@ -109,17 +112,30 @@ public class GatewayFilterSpec extends UriSpec { * @return a {@link GatewayFilterSpec} that can be used to apply additional filters */ public GatewayFilterSpec filters(GatewayFilter... gatewayFilters) { - this.routeBuilder.filters(gatewayFilters); + List filters = transformToOrderedFilters(Stream.of(gatewayFilters)); + this.routeBuilder.filters(filters); return this; } + public List transformToOrderedFilters(Stream stream) { + return stream + .map(filter -> { + if (filter instanceof Ordered) { + return filter; + } else { + return new OrderedGatewayFilter(filter, 0); + } + }).collect(Collectors.toList()); + } + /** * Applies the list of filters to the route. * @param gatewayFilters the filters to apply * @return a {@link GatewayFilterSpec} that can be used to apply additional filters */ public GatewayFilterSpec filters(Collection gatewayFilters) { - this.routeBuilder.filters(gatewayFilters); + List filters = transformToOrderedFilters(gatewayFilters.stream()); + this.routeBuilder.filters(filters); return this; } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpecTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpecTests.java index 9b0c89f31..80e26d568 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpecTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpecTests.java @@ -39,12 +39,33 @@ public class GatewayFilterSpecTests { Route route = routeBuilder.build(); assertThat(route.getFilters()).hasSize(1); - GatewayFilter filter = route.getFilters().get(0); + assertFilter(route.getFilters().get(0), type, order); + } + + private void assertFilter(GatewayFilter filter, Class type, int order) { assertThat(filter).isInstanceOf(type); Ordered ordered = (Ordered) filter; assertThat(ordered.getOrder()).isEqualTo(order); } + @Test + public void testFilters() { + ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class); + Route.AsyncBuilder routeBuilder = Route.async() + .id("123") + .uri("abc:123") + .predicate(exchange -> true); + RouteLocatorBuilder.Builder routes = new RouteLocatorBuilder(context).routes(); + GatewayFilterSpec spec = new GatewayFilterSpec(routeBuilder, routes); + spec.filters(new MyUnorderedFilter(), new MyOrderedFilter()); + + Route route = routeBuilder.build(); + assertThat(route.getFilters()).hasSize(2); + + assertFilter(route.getFilters().get(0), OrderedGatewayFilter.class, 0); + assertFilter(route.getFilters().get(1), MyOrderedFilter.class, 1000); + } + protected static class MyOrderedFilter implements GatewayFilter, Ordered { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {