diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index 58f89126a..b1a95ed3f 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -18,7 +18,6 @@ package org.springframework.cloud.gateway.config; import java.util.List; -import java.util.Map; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -114,13 +113,13 @@ public class GatewayAutoConfiguration { @Bean public FilteringWebHandler filteringWebHandler(GatewayProperties properties, List globalFilters, - Map routeFilters) { + List routeFilters) { return new FilteringWebHandler(properties, globalFilters, routeFilters); } @Bean public RequestPredicateHandlerMapping requestPredicateHandlerMapping(FilteringWebHandler webHandler, - Map predicates, + List predicates, RouteLocator routeLocator) { return new RequestPredicateHandlerMapping(webHandler, predicates, routeLocator); } @@ -161,69 +160,69 @@ public class GatewayAutoConfiguration { // Request Predicate beans - @Bean(name = "AfterRequestPredicateFactory") + @Bean public AfterRequestPredicateFactory afterRequestPredicateFactory() { return new AfterRequestPredicateFactory(); } - @Bean(name = "BeforeRequestPredicateFactory") + @Bean public BeforeRequestPredicateFactory beforeRequestPredicateFactory() { return new BeforeRequestPredicateFactory(); } - @Bean(name = "BetweenRequestPredicateFactory") + @Bean public BetweenRequestPredicateFactory betweenRequestPredicateFactory() { return new BetweenRequestPredicateFactory(); } - @Bean(name = "CookieRequestPredicateFactory") + @Bean public CookieRequestPredicateFactory cookieRequestPredicateFactory() { return new CookieRequestPredicateFactory(); } - @Bean(name = "HeaderRequestPredicateFactory") + @Bean public HeaderRequestPredicateFactory headerRequestPredicateFactory() { return new HeaderRequestPredicateFactory(); } - @Bean(name = "HostRequestPredicateFactory") + @Bean public HostRequestPredicateFactory hostRequestPredicateFactory() { return new HostRequestPredicateFactory(); } - @Bean(name = "MethodRequestPredicateFactory") + @Bean public MethodRequestPredicateFactory methodRequestPredicateFactory() { return new MethodRequestPredicateFactory(); } - @Bean(name = "PathRequestPredicateFactory") + @Bean public PathRequestPredicateFactory pathRequestPredicateFactory() { return new PathRequestPredicateFactory(); } - @Bean(name = "QueryRequestPredicateFactory") + @Bean public QueryRequestPredicateFactory queryRequestPredicateFactory() { return new QueryRequestPredicateFactory(); } - @Bean(name = "RemoteAddrRequestPredicateFactory") + @Bean public RemoteAddrRequestPredicateFactory remoteAddrRequestPredicateFactory() { return new RemoteAddrRequestPredicateFactory(); } // Filter Factory beans - @Bean(name = "AddRequestHeaderRouteFilter") + @Bean public AddRequestHeaderRouteFilter addRequestHeaderRouteFilter() { return new AddRequestHeaderRouteFilter(); } - @Bean(name = "AddRequestParameterRouteFilter") + @Bean public AddRequestParameterRouteFilter addRequestParameterRouteFilter() { return new AddRequestParameterRouteFilter(); } - @Bean(name = "AddResponseHeaderRouteFilter") + @Bean public AddResponseHeaderRouteFilter addResponseHeaderRouteFilter() { return new AddResponseHeaderRouteFilter(); } @@ -231,58 +230,58 @@ public class GatewayAutoConfiguration { @Configuration @ConditionalOnClass({HystrixObservableCommand.class, RxReactiveStreams.class}) protected static class HystrixConfiguration { - @Bean(name = "HystrixRouteFilter") + @Bean public HystrixRouteFilter hystrixRouteFilter() { return new HystrixRouteFilter(); } } - @Bean(name = "PrefixPathRouteFilter") + @Bean public PrefixPathRouteFilter prefixPathRouteFilter() { return new PrefixPathRouteFilter(); } - @Bean(name = "RedirectToRouteFilter") + @Bean public RedirectToRouteFilter redirectToRouteFilter() { return new RedirectToRouteFilter(); } - @Bean(name = "RemoveNonProxyHeadersRouteFilter") + @Bean public RemoveNonProxyHeadersRouteFilter removeNonProxyHeadersRouteFilter() { return new RemoveNonProxyHeadersRouteFilter(); } - @Bean(name = "RemoveRequestHeaderRouteFilter") + @Bean public RemoveRequestHeaderRouteFilter removeRequestHeaderRouteFilter() { return new RemoveRequestHeaderRouteFilter(); } - @Bean(name = "RemoveResponseHeaderRouteFilter") + @Bean public RemoveResponseHeaderRouteFilter removeResponseHeaderRouteFilter() { return new RemoveResponseHeaderRouteFilter(); } - @Bean(name = "RewritePathRouteFilter") + @Bean public RewritePathRouteFilter rewritePathRouteFilter() { return new RewritePathRouteFilter(); } - @Bean(name = "SetPathRouteFilter") + @Bean public SetPathRouteFilter setPathRouteFilter() { return new SetPathRouteFilter(); } - @Bean(name = "SecureHeadersRouteFilter") + @Bean public SecureHeadersRouteFilter secureHeadersRouteFilter(SecureHeadersProperties properties) { return new SecureHeadersRouteFilter(properties); } - @Bean(name = "SetResponseHeaderRouteFilter") + @Bean public SetResponseHeaderRouteFilter setResponseHeaderRouteFilter() { return new SetResponseHeaderRouteFilter(); } - @Bean(name = "SetStatusRouteFilter") + @Bean public SetStatusRouteFilter setStatusRouteFilter() { return new SetStatusRouteFilter(); } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/route/RouteFilter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/route/RouteFilter.java index a1b187aa4..ffa9eec17 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/route/RouteFilter.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/route/RouteFilter.java @@ -17,6 +17,7 @@ package org.springframework.cloud.gateway.filter.route; +import org.springframework.cloud.gateway.support.NameUtils; import org.springframework.util.Assert; import org.springframework.web.server.WebFilter; @@ -27,6 +28,10 @@ public interface RouteFilter { WebFilter apply(String... args); + default String name() { + return NameUtils.normalizeFilterName(getClass()); + } + default void validate(int requiredSize, String... args) { Assert.isTrue(args != null && args.length == requiredSize, "args must have "+ requiredSize +" entry(s)"); diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/FilteringWebHandler.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/FilteringWebHandler.java index 8708e3eb5..05b12a024 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/FilteringWebHandler.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/FilteringWebHandler.java @@ -69,20 +69,16 @@ public class FilteringWebHandler extends WebHandlerDecorator { private final ConcurrentMap> combinedFiltersForRoute = new ConcurrentHashMap<>(); public FilteringWebHandler(GatewayProperties gatewayProperties, List globalFilters, - Map routeFilters) { + List routeFilters) { this(new EmptyWebHandler(), gatewayProperties, globalFilters, routeFilters); } public FilteringWebHandler(WebHandler targetHandler, GatewayProperties gatewayProperties, List globalFilters, - Map routeFilters) { + List routeFilters) { super(targetHandler); this.gatewayProperties = gatewayProperties; this.globalFilters = initList(globalFilters); - routeFilters.forEach((name, def) -> this.routeFilters.put(normalizeName(name), def)); - } - - private String normalizeName(String name) { - return name.replace(RouteFilter.class.getSimpleName(), ""); + routeFilters.forEach(routeFilter -> this.routeFilters.put(routeFilter.name(), routeFilter)); } private static List initList(List list) { diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java index 96e5c670f..92ca0fcd6 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java @@ -48,23 +48,23 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping { private final RouteLocator routeLocator; private final WebHandler webHandler; - private final Map routePredicates = new LinkedHashMap<>(); + private final Map requestPredicates = new LinkedHashMap<>(); //TODO: define semeantics for refresh (ie clearing and recalculating combinedPredicates) private final Map combinedPredicates = new ConcurrentHashMap<>(); - public RequestPredicateHandlerMapping(WebHandler webHandler, Map routePredicates, + public RequestPredicateHandlerMapping(WebHandler webHandler, List requestPredicates, RouteLocator routeLocator) { this.webHandler = webHandler; this.routeLocator = routeLocator; - routePredicates.forEach((name, factory) -> { - String key = normalizeName(name); - if (this.routePredicates.containsKey(key)) { + requestPredicates.forEach(factory -> { + String key = factory.name(); + if (this.requestPredicates.containsKey(key)) { this.logger.warn("A RequestPredicateFactory named "+ key - + " already exists, class: " + this.routePredicates.get(key) + + " already exists, class: " + this.requestPredicates.get(key) + ". It will be overwritten."); } - this.routePredicates.put(key, factory); + this.requestPredicates.put(key, factory); if (logger.isInfoEnabled()) { logger.info("Loaded RequestPredicateFactory [" + key + "]"); } @@ -73,10 +73,6 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping { setOrder(1); } - private String normalizeName(String name) { - return name.replace(RequestPredicateFactory.class.getSimpleName(), ""); - } - @Override protected Mono getHandlerInternal(ServerWebExchange exchange) { exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getClass().getSimpleName()); @@ -161,7 +157,7 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping { //TODO: decouple from HandlerMapping? private RequestPredicate lookup(Route route, PredicateDefinition predicate) { - RequestPredicateFactory found = this.routePredicates.get(predicate.getName()); + RequestPredicateFactory found = this.requestPredicates.get(predicate.getName()); if (found == null) { throw new IllegalArgumentException("Unable to find RequestPredicateFactory with name " + predicate.getName()); } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RequestPredicateFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RequestPredicateFactory.java index f1a909195..d0625b8d4 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RequestPredicateFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RequestPredicateFactory.java @@ -20,6 +20,7 @@ package org.springframework.cloud.gateway.handler.predicate; import java.util.Collections; import java.util.List; +import org.springframework.cloud.gateway.support.NameUtils; import org.springframework.tuple.Tuple; import org.springframework.util.Assert; import org.springframework.web.reactive.function.server.RequestPredicate; @@ -31,6 +32,10 @@ public interface RequestPredicateFactory { RequestPredicate apply(Tuple args); + default String name() { + return NameUtils.normalizePredicateName(getClass()); + } + /** * Returns hints about the number of args and the order for shortcut parsing. * @return @@ -39,6 +44,11 @@ public interface RequestPredicateFactory { return Collections.emptyList(); } + /** + * Validate supplied argument size against {@see #argNames} size. + * Useful for variable arg predicates. + * @return + */ default boolean validateArgSize() { return true; }