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 20753f7f..b1bec476 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 @@ -43,6 +43,7 @@ import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory import org.springframework.cloud.gateway.support.ConfigurationUtils; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.validation.Validator; @@ -162,7 +163,13 @@ public class RouteDefinitionRouteLocator implements RouteLocator, BeanFactoryAwa ArrayList ordered = new ArrayList<>(filters.size()); for (int i = 0; i < filters.size(); i++) { - ordered.add(new OrderedGatewayFilter(filters.get(i), i+1)); + GatewayFilter gatewayFilter = filters.get(i); + if (gatewayFilter instanceof Ordered) { + ordered.add(gatewayFilter); + } + else { + ordered.add(new OrderedGatewayFilter(gatewayFilter, i + 1)); + } } return ordered; diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocatorTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocatorTests.java index d5801b74..e619bc55 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocatorTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/route/RouteDefinitionRouteLocatorTests.java @@ -1,21 +1,80 @@ package org.springframework.cloud.gateway.route; +import java.net.URI; +import java.util.Arrays; +import java.util.List; + import org.junit.Test; -import org.junit.runner.RunWith; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.config.PropertiesRouteDefinitionLocator; +import org.springframework.cloud.gateway.filter.FilterDefinition; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.OrderedGatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory; +import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory; +import org.springframework.cloud.gateway.filter.factory.RemoveResponseHeaderGatewayFilterFactory; +import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactory; +import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; +import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; +import static org.assertj.core.api.Assertions.assertThat; -@RunWith(SpringRunner.class) -@SpringBootTest +/** + * @author Toshiaki Maki + */ public class RouteDefinitionRouteLocatorTests { @Test public void contextLoads() { + List predicates = Arrays + .asList(new HostRoutePredicateFactory()); + List gatewayFilterFactories = Arrays.asList( + new RemoveResponseHeaderGatewayFilterFactory(), + new AddResponseHeaderGatewayFilterFactory(), + new TestOrderedGatewayFilterFactory()); + GatewayProperties gatewayProperties = new GatewayProperties(); + gatewayProperties.setRoutes(Arrays.asList(new RouteDefinition() { + { + setId("foo"); + setUri(URI.create("http://foo.example.com")); + setPredicates( + Arrays.asList(new PredicateDefinition("Host=*.example.com"))); + setFilters(Arrays.asList( + new FilterDefinition("RemoveResponseHeader=Server"), + new FilterDefinition("TestOrdered="), + new FilterDefinition("AddResponseHeader=X-Response-Foo, Bar"))); + } + })); + + RouteDefinitionRouteLocator routeDefinitionRouteLocator = new RouteDefinitionRouteLocator( + new PropertiesRouteDefinitionLocator(gatewayProperties), predicates, + gatewayFilterFactories, gatewayProperties); + + List routes = routeDefinitionRouteLocator.getRoutes().collectList() + .block(); + List filters = routes.get(0).getFilters(); + assertThat(filters).hasSize(3); + assertThat(getFilterClassName(filters.get(0))).startsWith("RemoveResponseHeader"); + assertThat(getFilterClassName(filters.get(1))).startsWith("AddResponseHeader"); + assertThat(getFilterClassName(filters.get(2))) + .startsWith("RouteDefinitionRouteLocatorTests$TestOrderedGateway"); } - @SpringBootConfiguration - protected static class TestConfig { + private String getFilterClassName(GatewayFilter target) { + if (target instanceof OrderedGatewayFilter) { + return getFilterClassName(((OrderedGatewayFilter) target).getDelegate()); + } + else { + return target.getClass().getSimpleName(); + } + } + + static class TestOrderedGatewayFilterFactory extends AbstractGatewayFilterFactory { + @Override + public GatewayFilter apply(Object config) { + return new OrderedGatewayFilter((exchange, chain) -> chain.filter(exchange), + 9999); + } } }