Browse Source

Use RequestPredicate instead of Predicate<ServerWebExchange>

renames RoutePredicate -> RequestPredicateFactory
pull/41/head
Spencer Gibb 8 years ago
parent
commit
cd7767e30e
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 50
      docs/src/main/asciidoc/spring-cloud-gateway.adoc
  2. 98
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
  3. 8
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/discovery/DiscoveryClientRouteLocator.java
  4. 6
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/route/SetPathRouteFilter.java
  5. 45
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java
  6. 11
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/AfterRequestPredicateFactory.java
  7. 11
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/BeforeRequestPredicateFactory.java
  8. 9
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactory.java
  9. 14
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRequestPredicateFactory.java
  10. 15
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HeaderRequestPredicateFactory.java
  11. 15
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HostRequestPredicateFactory.java
  12. 14
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/MethodRequestPredicateFactory.java
  13. 36
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRequestPredicateFactory.java
  14. 70
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicate.java
  15. 34
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRequestPredicateFactory.java
  16. 36
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRequestPredicateFactory.java
  17. 9
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RequestPredicateFactory.java
  18. 6
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/NameUtils.java
  19. 46
      spring-cloud-gateway-core/src/main/java/org/springframework/web/reactive/function/server/PublicDefaultServerRequest.java
  20. 4
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/route/SetPathRouteFilterTests.java
  21. 14
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/AfterRequestPredicateFactoryTests.java
  22. 14
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BeforeRequestPredicateFactoryTests.java
  23. 11
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactoryTests.java
  24. 4
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/HostRoutePredicateIntegrationTests.java
  25. 72
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/MethodRequestPredicateFactoryTests.java
  26. 6
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRequestPredicateFactoryTests.java
  27. 4
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java
  28. 7
      spring-cloud-gateway-core/src/test/resources/application.yml

50
docs/src/main/asciidoc/spring-cloud-gateway.adoc

@ -29,22 +29,22 @@ TODO: document the meaning of terms to follow, like Route, Predicate and Filter @@ -29,22 +29,22 @@ TODO: document the meaning of terms to follow, like Route, Predicate and Filter
TODO: give an overview of how the gateway works with maybe a ascii diagram
[[gateway-route-predicates]]
== Route Predicates
[[gateway-request-predicates-factories]]
== Request Predicate Factories
Spring Cloud Gateway matches routes as part of the Spring WebFlux `HandlerMapping` infrastructure. Spring Cloud Gateway includes many built-in Route Predicates. All of these predicates match on different attributes of the HTTP request. Multiple Route Predicates can be combined and are combined via logical `and`.
Spring Cloud Gateway matches routes as part of the Spring WebFlux `HandlerMapping` infrastructure. Spring Cloud Gateway includes many built-in Request Predicate Factorys. All of these predicates match on different attributes of the HTTP request. Multiple Request Predicate Factorys can be combined and are combined via logical `and`.
=== After Route Predicate
TODO: document After Route Predicate
=== After Request Predicate Factory
TODO: document After Request Predicate Factory
=== Before Route Predicate
TODO: document Before Route Predicate
=== Before Request Predicate Factory
TODO: document Before Request Predicate Factory
=== Between Route Predicate
TODO: document Between Route Predicate
=== Between Request Predicate Factory
TODO: document Between Request Predicate Factory
=== Cookie Route Predicate
The Cookie Route Predicate takes two parameters, the cookie name and a regular expression. This predicate matches cookies that have the given name and the value matches the regular expression.
=== Cookie Request Predicate Factory
The Cookie Request Predicate Factory takes two parameters, the cookie name and a regular expression. This predicate matches cookies that have the given name and the value matches the regular expression.
.application.yml
[source,yaml]
@ -62,8 +62,8 @@ spring: @@ -62,8 +62,8 @@ spring:
This route matches the request has a cookie named `chocolate` who's value matches the `ch.p` regular expression.
=== Header Route Predicate
The Header Route Predicate takes two parameters, the header name and a regular expression. This predicate matches with a header that has the given name and the value matches the regular expression.
=== Header Request Predicate Factory
The Header Request Predicate Factory takes two parameters, the header name and a regular expression. This predicate matches with a header that has the given name and the value matches the regular expression.
.application.yml
[source,yaml]
@ -81,8 +81,8 @@ spring: @@ -81,8 +81,8 @@ spring:
This route matches if the request has a header named `X-Request-Id` whos value matches the `\d+` regular expression (has a value of one or more digits).
=== Host Route Predicate
The Host Route Predicate takes one parameter: the host name pattern. The pattern is an Ant style pattern with `.` as the separator. This predicates matches the `Host` header that matches the pattern.
=== Host Request Predicate Factory
The Host Request Predicate Factory takes one parameter: the host name pattern. The pattern is an Ant style pattern with `.` as the separator. This predicates matches the `Host` header that matches the pattern.
.application.yml
[source,yaml]
@ -101,8 +101,8 @@ spring: @@ -101,8 +101,8 @@ spring:
This route would match if the request has a `Host` header has the value `www.somehost.org` or `beta.somehost.org`.
=== Method Route Predicate
The Method Route Predicate takes one parameter: the HTTP method to match.
=== Method Request Predicate Factory
The Method Request Predicate Factory takes one parameter: the HTTP method to match.
.application.yml
[source,yaml]
@ -120,8 +120,8 @@ spring: @@ -120,8 +120,8 @@ spring:
This route would match if the request method was a `GET`.
=== Path Route Predicate
The Path Route Predicate takes one parameter: a Spring `PathMatcher` pattern.
=== Path Request Predicate Factory
The Path Request Predicate Factory takes one parameter: a Spring `PathMatcher` pattern.
.application.yml
[source,yaml]
@ -141,11 +141,11 @@ This route would match if the request path was, for example: `/foo/1` or `/foo/b @@ -141,11 +141,11 @@ This route would match if the request path was, for example: `/foo/1` or `/foo/b
This predicate extracts the URI template variables (like `segment` defined in the example above) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `PathRoutePredicate.URL_PREDICATE_VARS_ATTR`. Those values are then available for use by <<gateway-route-filters,Route Filters>>
=== Query Route Predicate
TODO: document Query Route Predicate
=== Query Request Predicate Factory
TODO: document Query Request Predicate Factory
=== RemoteAddr Route Predicate
TODO: document RemoteAddr Route Predicate
=== RemoteAddr Request Predicate Factory
TODO: document RemoteAddr Request Predicate Factory
[[gateway-route-filters]]
== Route Filters
@ -210,9 +210,9 @@ TODO: document the `/gateway` actuator endpoint @@ -210,9 +210,9 @@ TODO: document the `/gateway` actuator endpoint
TODO: overview of writing custom integrations
=== Writing Custom Route Predicates
=== Writing Custom Request Predicate Factorys
TODO: document writing Custom Route Predicates
TODO: document writing Custom Request Predicate Factorys
=== Writing Custom Route Filters

98
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@ -27,18 +27,18 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean @@ -27,18 +27,18 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.actuate.GatewayEndpoint;
import org.springframework.cloud.gateway.filter.route.PrefixPathRouteFilter;
import org.springframework.cloud.gateway.api.RouteLocator;
import org.springframework.cloud.gateway.api.RouteWriter;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
import org.springframework.cloud.gateway.filter.NettyRoutingFilter;
import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
import org.springframework.cloud.gateway.filter.WriteResponseFilter;
import org.springframework.cloud.gateway.filter.route.AddRequestHeaderRouteFilter;
import org.springframework.cloud.gateway.filter.route.AddRequestParameterRouteFilter;
import org.springframework.cloud.gateway.filter.route.AddResponseHeaderRouteFilter;
import org.springframework.cloud.gateway.filter.route.HystrixRouteFilter;
import org.springframework.cloud.gateway.filter.route.PrefixPathRouteFilter;
import org.springframework.cloud.gateway.filter.route.RedirectToRouteFilter;
import org.springframework.cloud.gateway.filter.route.RemoveNonProxyHeadersRouteFilter;
import org.springframework.cloud.gateway.filter.route.RemoveRequestHeaderRouteFilter;
@ -51,19 +51,19 @@ import org.springframework.cloud.gateway.filter.route.SetPathRouteFilter; @@ -51,19 +51,19 @@ import org.springframework.cloud.gateway.filter.route.SetPathRouteFilter;
import org.springframework.cloud.gateway.filter.route.SetResponseHeaderRouteFilter;
import org.springframework.cloud.gateway.filter.route.SetStatusRouteFilter;
import org.springframework.cloud.gateway.handler.FilteringWebHandler;
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
import org.springframework.cloud.gateway.handler.NettyRoutingWebHandler;
import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.CookieRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.HeaderRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.MethodRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.QueryRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.RemoteAddrRoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicate;
import org.springframework.cloud.gateway.handler.RequestPredicateHandlerMapping;
import org.springframework.cloud.gateway.handler.predicate.AfterRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.BeforeRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.CookieRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.HeaderRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.HostRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.MethodRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.QueryRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.RemoteAddrRequestPredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.RequestPredicateFactory;
import org.springframework.cloud.gateway.support.CachingRouteLocator;
import org.springframework.cloud.gateway.support.InMemoryRouteRepository;
import org.springframework.context.annotation.Bean;
@ -119,10 +119,10 @@ public class GatewayAutoConfiguration { @@ -119,10 +119,10 @@ public class GatewayAutoConfiguration {
}
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
Map<String, RoutePredicate> predicates,
RouteLocator routeLocator) {
return new RoutePredicateHandlerMapping(webHandler, predicates, routeLocator);
public RequestPredicateHandlerMapping requestPredicateHandlerMapping(FilteringWebHandler webHandler,
Map<String, RequestPredicateFactory> predicates,
RouteLocator routeLocator) {
return new RequestPredicateHandlerMapping(webHandler, predicates, routeLocator);
}
// ConfigurationProperty beans
@ -159,56 +159,56 @@ public class GatewayAutoConfiguration { @@ -159,56 +159,56 @@ public class GatewayAutoConfiguration {
return new WriteResponseFilter();
}
// Predicate beans
// Request Predicate beans
@Bean(name = "AfterRoutePredicate")
public AfterRoutePredicate afterRoutePredicate() {
return new AfterRoutePredicate();
@Bean(name = "AfterRequestPredicateFactory")
public AfterRequestPredicateFactory afterRequestPredicateFactory() {
return new AfterRequestPredicateFactory();
}
@Bean(name = "BeforeRoutePredicate")
public BeforeRoutePredicate beforeRoutePredicate() {
return new BeforeRoutePredicate();
@Bean(name = "BeforeRequestPredicateFactory")
public BeforeRequestPredicateFactory beforeRequestPredicateFactory() {
return new BeforeRequestPredicateFactory();
}
@Bean(name = "BetweenRoutePredicate")
public BetweenRoutePredicate betweenRoutePredicate() {
return new BetweenRoutePredicate();
@Bean(name = "BetweenRequestPredicateFactory")
public BetweenRequestPredicateFactory betweenRequestPredicateFactory() {
return new BetweenRequestPredicateFactory();
}
@Bean(name = "CookieRoutePredicate")
public CookieRoutePredicate cookieRoutePredicate() {
return new CookieRoutePredicate();
@Bean(name = "CookieRequestPredicateFactory")
public CookieRequestPredicateFactory cookieRequestPredicateFactory() {
return new CookieRequestPredicateFactory();
}
@Bean(name = "HeaderRoutePredicate")
public HeaderRoutePredicate headerRoutePredicate() {
return new HeaderRoutePredicate();
@Bean(name = "HeaderRequestPredicateFactory")
public HeaderRequestPredicateFactory headerRequestPredicateFactory() {
return new HeaderRequestPredicateFactory();
}
@Bean(name = "HostRoutePredicate")
public HostRoutePredicate hostRoutePredicate() {
return new HostRoutePredicate();
@Bean(name = "HostRequestPredicateFactory")
public HostRequestPredicateFactory hostRequestPredicateFactory() {
return new HostRequestPredicateFactory();
}
@Bean(name = "MethodRoutePredicate")
public MethodRoutePredicate methodRoutePredicate() {
return new MethodRoutePredicate();
@Bean(name = "MethodRequestPredicateFactory")
public MethodRequestPredicateFactory methodRequestPredicateFactory() {
return new MethodRequestPredicateFactory();
}
@Bean(name = "PathRoutePredicate")
public PathRoutePredicate pathRoutePredicate() {
return new PathRoutePredicate();
@Bean(name = "PathRequestPredicateFactory")
public PathRequestPredicateFactory pathRequestPredicateFactory() {
return new PathRequestPredicateFactory();
}
@Bean(name = "QueryRoutePredicate")
public QueryRoutePredicate queryRoutePredicate() {
return new QueryRoutePredicate();
@Bean(name = "QueryRequestPredicateFactory")
public QueryRequestPredicateFactory queryRequestPredicateFactory() {
return new QueryRequestPredicateFactory();
}
@Bean(name = "RemoteAddrRoutePredicate")
public RemoteAddrRoutePredicate remoteAddrRoutePredicate() {
return new RemoteAddrRoutePredicate();
@Bean(name = "RemoteAddrRequestPredicateFactory")
public RemoteAddrRequestPredicateFactory remoteAddrRequestPredicateFactory() {
return new RemoteAddrRequestPredicateFactory();
}
// Filter Factory beans

8
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/discovery/DiscoveryClientRouteLocator.java

@ -20,12 +20,12 @@ package org.springframework.cloud.gateway.discovery; @@ -20,12 +20,12 @@ package org.springframework.cloud.gateway.discovery;
import java.net.URI;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.api.RouteLocator;
import org.springframework.cloud.gateway.filter.route.RewritePathRouteFilter;
import org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateFactory;
import org.springframework.cloud.gateway.model.FilterDefinition;
import org.springframework.cloud.gateway.model.PredicateDefinition;
import org.springframework.cloud.gateway.model.Route;
import org.springframework.cloud.gateway.api.RouteLocator;
import org.springframework.cloud.gateway.filter.route.RewritePathRouteFilter;
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicate;
import static org.springframework.cloud.gateway.support.NameUtils.normalizeFilterName;
import static org.springframework.cloud.gateway.support.NameUtils.normalizePredicateName;
@ -56,7 +56,7 @@ public class DiscoveryClientRouteLocator implements RouteLocator { @@ -56,7 +56,7 @@ public class DiscoveryClientRouteLocator implements RouteLocator {
// add a predicate that matches the url at /serviceId/**
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(normalizePredicateName(PathRoutePredicate.class));
predicate.setName(normalizePredicateName(PathRequestPredicateFactory.class));
predicate.setArgs("/" + serviceId + "/**");
route.getPredicates().add(predicate);

6
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/route/SetPathRouteFilter.java

@ -20,12 +20,12 @@ package org.springframework.cloud.gateway.filter.route; @@ -20,12 +20,12 @@ package org.springframework.cloud.gateway.filter.route;
import java.net.URI;
import java.util.Map;
import org.springframework.web.server.WebFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.WebFilter;
import org.springframework.web.util.UriTemplate;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
import static org.springframework.cloud.gateway.handler.predicate.PathRoutePredicate.URL_PREDICATE_VARS_ATTR;
import static org.springframework.web.reactive.function.server.RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
/**
* @author Spencer Gibb
@ -39,7 +39,7 @@ public class SetPathRouteFilter implements RouteFilter { @@ -39,7 +39,7 @@ public class SetPathRouteFilter implements RouteFilter {
UriTemplate uriTemplate = new UriTemplate(args[0]);
return (exchange, chain) -> {
Map<String, String> variables = getAttribute(exchange, URL_PREDICATE_VARS_ATTR, Map.class);
Map<String, String> variables = getAttribute(exchange, URI_TEMPLATE_VARIABLES_ATTRIBUTE, Map.class);
ServerHttpRequest req = exchange.getRequest();
URI uri = uriTemplate.expand(variables);
String newPath = uri.getPath();

45
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/RequestPredicateHandlerMapping.java

@ -24,12 +24,13 @@ import java.util.List; @@ -24,12 +24,13 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import org.springframework.cloud.gateway.api.RouteLocator;
import org.springframework.cloud.gateway.handler.predicate.RequestPredicateFactory;
import org.springframework.cloud.gateway.model.Route;
import org.springframework.cloud.gateway.model.PredicateDefinition;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicate;
import org.springframework.web.reactive.function.server.PublicDefaultServerRequest;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.handler.AbstractHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
@ -42,29 +43,29 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G @@ -42,29 +43,29 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G
/**
* @author Spencer Gibb
*/
public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
public class RequestPredicateHandlerMapping extends AbstractHandlerMapping {
private final RouteLocator routeLocator;
private final WebHandler webHandler;
private final Map<String, RoutePredicate> routePredicates = new LinkedHashMap<>();
private final Map<String, RequestPredicateFactory> routePredicates = new LinkedHashMap<>();
//TODO: define semeantics for refresh (ie clearing and recalculating combinedPredicates)
private final Map<String, Predicate<ServerWebExchange>> combinedPredicates = new ConcurrentHashMap<>();
private final Map<String, RequestPredicate> combinedPredicates = new ConcurrentHashMap<>();
public RoutePredicateHandlerMapping(WebHandler webHandler, Map<String, RoutePredicate> routePredicates,
RouteLocator routeLocator) {
public RequestPredicateHandlerMapping(WebHandler webHandler, Map<String, RequestPredicateFactory> routePredicates,
RouteLocator routeLocator) {
this.webHandler = webHandler;
this.routeLocator = routeLocator;
routePredicates.forEach((name, factory) -> {
String key = normalizeName(name);
if (this.routePredicates.containsKey(key)) {
this.logger.warn("A RoutePredicate named "+ key
this.logger.warn("A RequestPredicateFactory named "+ key
+ " already exists, class: " + this.routePredicates.get(key)
+ ". It will be overwritten.");
}
this.routePredicates.put(key, factory);
if (logger.isInfoEnabled()) {
logger.info("Loaded RoutePredicate [" + key + "]");
logger.info("Loaded RequestPredicateFactory [" + key + "]");
}
});
@ -72,7 +73,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { @@ -72,7 +73,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
}
private String normalizeName(String name) {
return name.replace(RoutePredicate.class.getSimpleName(), "");
return name.replace(RequestPredicateFactory.class.getSimpleName(), "");
}
@Override
@ -109,9 +110,9 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { @@ -109,9 +110,9 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes()
//TODO: cache predicate
.map(route -> getRouteCombinedPredicates(route))
.filter(rcp -> rcp.combinedPredicate.test(exchange))
.map(this::getRouteCombinedPredicates)
//TODO: fix PublicDefaultServerRequest?
.filter(rcp -> rcp.combinedPredicate.test(new PublicDefaultServerRequest(exchange)))
.next()
//TODO: error handling
.map(rcp -> {
@ -129,7 +130,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { @@ -129,7 +130,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
}
private RouteCombinedPredicates getRouteCombinedPredicates(Route route) {
Predicate<ServerWebExchange> predicate = this.combinedPredicates
RequestPredicate predicate = this.combinedPredicates
.computeIfAbsent(route.getId(), k -> combinePredicates(route));
return new RouteCombinedPredicates(route, predicate);
@ -137,31 +138,31 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { @@ -137,31 +138,31 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
private class RouteCombinedPredicates {
private Route route;
private Predicate<ServerWebExchange> combinedPredicate;
private RequestPredicate combinedPredicate;
public RouteCombinedPredicates(Route route, Predicate<ServerWebExchange> combinedPredicate) {
public RouteCombinedPredicates(Route route, RequestPredicate combinedPredicate) {
this.route = route;
this.combinedPredicate = combinedPredicate;
}
}
private Predicate<ServerWebExchange> combinePredicates(Route route) {
private RequestPredicate combinePredicates(Route route) {
List<PredicateDefinition> predicates = route.getPredicates();
Predicate<ServerWebExchange> predicate = lookup(route, predicates.get(0));
RequestPredicate predicate = lookup(route, predicates.get(0));
for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
Predicate<ServerWebExchange> found = lookup(route, andPredicate);
RequestPredicate found = lookup(route, andPredicate);
predicate = predicate.and(found);
}
return predicate;
}
private Predicate<ServerWebExchange> lookup(Route route, PredicateDefinition predicate) {
RoutePredicate found = this.routePredicates.get(predicate.getName());
private RequestPredicate lookup(Route route, PredicateDefinition predicate) {
RequestPredicateFactory found = this.routePredicates.get(predicate.getName());
if (found == null) {
throw new IllegalArgumentException("Unable to find RoutePredicate with name " + predicate.getName());
throw new IllegalArgumentException("Unable to find RequestPredicateFactory with name " + predicate.getName());
}
if (logger.isDebugEnabled()) {
List<String> args;

11
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/AfterRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/AfterRequestPredicateFactory.java

@ -18,23 +18,22 @@ @@ -18,23 +18,22 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.time.ZonedDateTime;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicate.parseZonedDateTime;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory.parseZonedDateTime;
/**
* @author Spencer Gibb
*/
public class AfterRoutePredicate implements RoutePredicate {
public class AfterRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(1, args);
final ZonedDateTime dateTime = parseZonedDateTime(args[0]);
return exchange -> {
return request -> {
final ZonedDateTime now = ZonedDateTime.now();
return now.isAfter(dateTime);
};

11
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/BeforeRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/BeforeRequestPredicateFactory.java

@ -18,23 +18,22 @@ @@ -18,23 +18,22 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.time.ZonedDateTime;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicate.parseZonedDateTime;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory.parseZonedDateTime;
/**
* @author Spencer Gibb
*/
public class BeforeRoutePredicate implements RoutePredicate {
public class BeforeRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(1, args);
final ZonedDateTime dateTime = parseZonedDateTime(args[0]);
return exchange -> {
return request -> {
final ZonedDateTime now = ZonedDateTime.now();
return now.isBefore(dateTime);
};

9
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/BetweenRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactory.java

@ -20,18 +20,17 @@ package org.springframework.cloud.gateway.handler.predicate; @@ -20,18 +20,17 @@ package org.springframework.cloud.gateway.handler.predicate;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.function.Predicate;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
/**
* @author Spencer Gibb
*/
public class BetweenRoutePredicate implements RoutePredicate {
public class BetweenRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(2, args);
//TODO: is ZonedDateTime the right thing to use?
@ -39,7 +38,7 @@ public class BetweenRoutePredicate implements RoutePredicate { @@ -39,7 +38,7 @@ public class BetweenRoutePredicate implements RoutePredicate {
final ZonedDateTime dateTime2 = parseZonedDateTime(args[1]);
Assert.isTrue(dateTime1.isBefore(dateTime2), args[0] + " must be before " + args[1]);
return exchange -> {
return request -> {
final ZonedDateTime now = ZonedDateTime.now();
return now.isAfter(dateTime1) && now.isBefore(dateTime2);
};

14
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/CookieRequestPredicateFactory.java

@ -18,24 +18,26 @@ @@ -18,24 +18,26 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.http.HttpCookie;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.PublicDefaultServerRequest;
import org.springframework.web.reactive.function.server.RequestPredicate;
/**
* @author Spencer Gibb
*/
public class CookieRoutePredicate implements RoutePredicate {
public class CookieRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(2, args);
String name = args[0];
String regexp = args[1];
return exchange -> {
List<HttpCookie> cookies = exchange.getRequest().getCookies().get(name);
return request -> {
//TODO: bad cast?
PublicDefaultServerRequest req = (PublicDefaultServerRequest) request;
List<HttpCookie> cookies = req.getCookies().get(name);
for (HttpCookie cookie : cookies) {
if (cookie.getValue().matches(regexp)) {
return true;

15
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HeaderRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HeaderRequestPredicateFactory.java

@ -18,30 +18,29 @@ @@ -18,30 +18,29 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RequestPredicates;
/**
* @author Spencer Gibb
*/
public class HeaderRoutePredicate implements RoutePredicate {
public class HeaderRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(2, args);
String header = args[0];
String regexp = args[1];
return exchange -> {
List<String> values = exchange.getRequest().getHeaders().get(header);
return RequestPredicates.headers(headers -> {
List<String> values = headers.asHttpHeaders().get(header);
for (String value : values) {
if (value.matches(regexp)) {
return true;
}
}
return false;
};
});
}
}

15
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HostRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HostRequestPredicateFactory.java

@ -17,16 +17,15 @@ @@ -17,16 +17,15 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.util.function.Predicate;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RequestPredicates;
/**
* @author Spencer Gibb
*/
public class HostRoutePredicate implements RoutePredicate {
public class HostRequestPredicateFactory implements RequestPredicateFactory {
private PathMatcher pathMatcher = new AntPathMatcher(".");
@ -35,13 +34,13 @@ public class HostRoutePredicate implements RoutePredicate { @@ -35,13 +34,13 @@ public class HostRoutePredicate implements RoutePredicate {
}
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(1, args);
String pattern = args[0];
return exchange -> {
String host = exchange.getRequest().getHeaders().getFirst("Host");
return RequestPredicates.headers(headers -> {
String host = headers.asHttpHeaders().getFirst("Host");
return this.pathMatcher.match(pattern, host);
};
});
}
}

14
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/MethodRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/MethodRequestPredicateFactory.java

@ -17,23 +17,19 @@ @@ -17,23 +17,19 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.util.function.Predicate;
import org.springframework.http.HttpMethod;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RequestPredicates;
/**
* @author Spencer Gibb
*/
public class MethodRoutePredicate implements RoutePredicate {
public class MethodRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(1, args);
String method = args[0];
return exchange -> {
HttpMethod requestMethod = exchange.getRequest().getMethod();
return requestMethod.matches(method);
};
return RequestPredicates.method(HttpMethod.resolve(method));
}
}

36
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRequestPredicateFactory.java

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.gateway.handler.predicate;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RequestPredicates;
/**
* @author Spencer Gibb
*/
public class PathRequestPredicateFactory implements RequestPredicateFactory {
@Override
public RequestPredicate apply(String... args) {
validate(1, args);
String pattern = args[0];
//TODO: support custom PathPatternParser
return RequestPredicates.path(pattern);
}
}

70
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicate.java

@ -1,70 +0,0 @@ @@ -1,70 +0,0 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.gateway.handler.predicate;
import java.util.Map;
import java.util.function.Predicate;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.support.HttpRequestPathHelper;
import org.springframework.web.util.ParsingPathMatcher;
/**
* @author Spencer Gibb
*/
public class PathRoutePredicate implements RoutePredicate {
public static final String URL_PREDICATE_VARS_ATTR = "urlPredicateVars";
private PathMatcher pathMatcher = new ParsingPathMatcher();
private HttpRequestPathHelper pathHelper = new HttpRequestPathHelper();
public PathMatcher getPathMatcher() {
return pathMatcher;
}
public void setPathMatcher(PathMatcher pathMatcher) {
this.pathMatcher = pathMatcher;
}
public HttpRequestPathHelper getPathHelper() {
return pathHelper;
}
public void setPathHelper(HttpRequestPathHelper pathHelper) {
this.pathHelper = pathHelper;
}
@Override
public Predicate<ServerWebExchange> apply(String... args) {
validate(1, args);
String pattern = args[0];
return exchange -> {
String lookupPath = getPathHelper().getLookupPathForRequest(exchange);
boolean match = getPathMatcher().match(pattern, lookupPath);
if (match) {
Map<String, String> variables = getPathMatcher().extractUriTemplateVariables(pattern, lookupPath);
exchange.getAttributes().put(URL_PREDICATE_VARS_ATTR, variables);
}
return match;
//TODO: support trailingSlashMatch
};
}
}

34
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/QueryRequestPredicateFactory.java

@ -17,36 +17,30 @@ @@ -17,36 +17,30 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.PublicDefaultServerRequest;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RequestPredicates;
/**
* @author Spencer Gibb
*/
public class QueryRoutePredicate implements RoutePredicate {
public class QueryRequestPredicateFactory implements RequestPredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(1, args);
String param = args[0];
return exchange -> {
if (args.length < 2) {
// check existence of header
return exchange.getRequest().getQueryParams().containsKey(param);
}
if (args.length < 2) {
return req -> {
//TODO: ServerRequest support for query params with no value
PublicDefaultServerRequest request = (PublicDefaultServerRequest) req;
return request.getExchange().getRequest().getQueryParams().containsKey(param);
};
}
String regexp = args[1];
String regexp = args[1];
List<String> values = exchange.getRequest().getQueryParams().get(param);
for (String value : values) {
if (value.matches(regexp)) {
return true;
}
}
return false;
};
return RequestPredicates.queryParam(param, value -> value.matches(regexp));
}
}

36
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RemoteAddrRequestPredicateFactory.java

@ -20,23 +20,23 @@ package org.springframework.cloud.gateway.handler.predicate; @@ -20,23 +20,23 @@ package org.springframework.cloud.gateway.handler.predicate;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.Optional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.support.SubnetUtils;
import org.springframework.http.server.reactive.ReactorServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.PublicDefaultServerRequest;
import org.springframework.web.reactive.function.server.RequestPredicate;
/**
* @author Spencer Gibb
*/
public class RemoteAddrRoutePredicate implements RoutePredicate {
public class RemoteAddrRequestPredicateFactory implements RequestPredicateFactory {
private static final Log log = LogFactory.getLog(RemoteAddrRoutePredicate.class);
private static final Log log = LogFactory.getLog(RemoteAddrRequestPredicateFactory.class);
@Override
public Predicate<ServerWebExchange> apply(String... args) {
public RequestPredicate apply(String... args) {
validate(1, args);
List<SubnetUtils> sources = new ArrayList<>();
@ -46,19 +46,21 @@ public class RemoteAddrRoutePredicate implements RoutePredicate { @@ -46,19 +46,21 @@ public class RemoteAddrRoutePredicate implements RoutePredicate {
}
}
return exchange -> {
ReactorServerHttpRequest request = (ReactorServerHttpRequest) exchange.getRequest();
InetSocketAddress remoteAddress = request.getReactorRequest().remoteAddress();
String hostAddress = remoteAddress.getAddress().getHostAddress();
String host = exchange.getRequest().getURI().getHost();
return req -> {
PublicDefaultServerRequest serverRequest = (PublicDefaultServerRequest) req;
Optional<InetSocketAddress> remoteAddress = serverRequest.getExchange().getRequest().getRemoteAddress();
if (remoteAddress.isPresent()) {
String hostAddress = remoteAddress.get().getAddress().getHostAddress();
String host = req.uri().getHost();
if (!hostAddress.equals(host)) {
log.warn("Remote addresses didn't match " + hostAddress + " != " + host);
}
if (!hostAddress.equals(host)) {
log.warn("Remote addresses didn't match " + hostAddress + " != " + host);
}
for (SubnetUtils source : sources) {
if (source.getInfo().isInRange(hostAddress)) {
return true;
for (SubnetUtils source : sources) {
if (source.getInfo().isInRange(hostAddress)) {
return true;
}
}
}

9
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RoutePredicate.java → spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/RequestPredicateFactory.java

@ -17,17 +17,16 @@ @@ -17,17 +17,16 @@
package org.springframework.cloud.gateway.handler.predicate;
import java.util.function.Predicate;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.RequestPredicate;
/**
* @author Spencer Gibb
*/
public interface RoutePredicate {
public interface RequestPredicateFactory {
Predicate<ServerWebExchange> apply(String... args);
//TODO: use tuple instead of String array
RequestPredicate apply(String... args);
default void validate(int minimumSize, String... args) {
Assert.isTrue(args != null && args.length >= minimumSize,

6
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/NameUtils.java

@ -18,15 +18,15 @@ @@ -18,15 +18,15 @@
package org.springframework.cloud.gateway.support;
import org.springframework.cloud.gateway.filter.route.RouteFilter;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicate;
import org.springframework.cloud.gateway.handler.predicate.RequestPredicateFactory;
/**
* @author Spencer Gibb
*/
public class NameUtils {
public static String normalizePredicateName(Class<? extends RoutePredicate> clazz) {
return clazz.getSimpleName().replace(RoutePredicate.class.getSimpleName(), "");
public static String normalizePredicateName(Class<? extends RequestPredicateFactory> clazz) {
return clazz.getSimpleName().replace(RequestPredicateFactory.class.getSimpleName(), "");
}
public static String normalizeFilterName(Class<? extends RouteFilter> clazz) {

46
spring-cloud-gateway-core/src/main/java/org/springframework/web/reactive/function/server/PublicDefaultServerRequest.java

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.web.reactive.function.server;
import org.springframework.http.HttpCookie;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class PublicDefaultServerRequest extends DefaultServerRequest {
private ServerWebExchange exchange;
public PublicDefaultServerRequest(ServerWebExchange exchange) {
this(exchange, HandlerStrategies.withDefaults());
}
public PublicDefaultServerRequest(ServerWebExchange exchange, HandlerStrategies strategies) {
super(exchange, strategies);
this.exchange = exchange;
}
public MultiValueMap<String, HttpCookie> getCookies() {
return this.exchange.getRequest().getCookies();
}
public ServerWebExchange getExchange() {
return exchange;
}
}

4
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/route/SetPathRouteFilterTests.java

@ -22,9 +22,9 @@ import java.util.HashMap; @@ -22,9 +22,9 @@ import java.util.HashMap;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicate;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerHttpResponse;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
@ -61,7 +61,7 @@ public class SetPathRouteFilterTests { @@ -61,7 +61,7 @@ public class SetPathRouteFilterTests {
.build();
DefaultServerWebExchange exchange = new DefaultServerWebExchange(request, new MockServerHttpResponse());
exchange.getAttributes().put(PathRoutePredicate.URL_PREDICATE_VARS_ATTR, variables);
exchange.getAttributes().put(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, variables);
WebFilterChain filterChain = mock(WebFilterChain.class);

14
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/AfterRoutePredicateTests.java → spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/AfterRequestPredicateFactoryTests.java

@ -20,16 +20,16 @@ package org.springframework.cloud.gateway.handler.predicate; @@ -20,16 +20,16 @@ package org.springframework.cloud.gateway.handler.predicate;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.getExchange;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.minusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.minusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.plusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.plusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.getRequest;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.minusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.minusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.plusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.plusHoursMillis;
/**
* @author Spencer Gibb
*/
public class AfterRoutePredicateTests {
public class AfterRequestPredicateFactoryTests {
@Test
public void beforeStringWorks() {
@ -68,6 +68,6 @@ public class AfterRoutePredicateTests { @@ -68,6 +68,6 @@ public class AfterRoutePredicateTests {
}
private boolean runPredicate(String dateString) {
return new AfterRoutePredicate().apply(dateString).test(getExchange());
return new AfterRequestPredicateFactory().apply(dateString).test(getRequest());
}
}

14
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BeforeRoutePredicateTests.java → spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BeforeRequestPredicateFactoryTests.java

@ -20,16 +20,16 @@ package org.springframework.cloud.gateway.handler.predicate; @@ -20,16 +20,16 @@ package org.springframework.cloud.gateway.handler.predicate;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.getExchange;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.minusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.minusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.plusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateTests.plusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.getRequest;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.minusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.minusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.plusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests.plusHoursMillis;
/**
* @author Spencer Gibb
*/
public class BeforeRoutePredicateTests {
public class BeforeRequestPredicateFactoryTests {
@Test
public void beforeStringWorks() {
@ -68,6 +68,6 @@ public class BeforeRoutePredicateTests { @@ -68,6 +68,6 @@ public class BeforeRoutePredicateTests {
}
private boolean runPredicate(String dateString) {
return new BeforeRoutePredicate().apply(dateString).test(getExchange());
return new BeforeRequestPredicateFactory().apply(dateString).test(getRequest());
}
}

11
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRoutePredicateTests.java → spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/BetweenRequestPredicateFactoryTests.java

@ -23,7 +23,8 @@ import java.time.format.DateTimeFormatter; @@ -23,7 +23,8 @@ import java.time.format.DateTimeFormatter;
import org.junit.Test;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.reactive.function.server.PublicDefaultServerRequest;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
@ -31,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -31,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
public class BetweenRoutePredicateTests {
public class BetweenRequestPredicateFactoryTests {
@Test
public void beforeStringWorks() {
@ -94,7 +95,7 @@ public class BetweenRoutePredicateTests { @@ -94,7 +95,7 @@ public class BetweenRoutePredicateTests {
}
boolean runPredicate(String dateString1, String dateString2) {
return new BetweenRoutePredicate().apply(dateString1, dateString2).test(getExchange());
return new BetweenRequestPredicateFactory().apply(dateString1, dateString2).test(getRequest());
}
static String minusHoursMillis(int hours) {
@ -115,8 +116,8 @@ public class BetweenRoutePredicateTests { @@ -115,8 +116,8 @@ public class BetweenRoutePredicateTests {
return ZonedDateTime.now().plusHours(hours).format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
static ServerWebExchange getExchange() {
static ServerRequest getRequest() {
final MockServerHttpRequest request = MockServerHttpRequest.get("http://example.com").build();
return new DefaultServerWebExchange(request, new MockServerHttpResponse());
return new PublicDefaultServerRequest(new DefaultServerWebExchange(request, new MockServerHttpResponse()));
}
}

4
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/HostRoutePredicateIntegrationTests.java

@ -22,7 +22,7 @@ import org.junit.runner.RunWith; @@ -22,7 +22,7 @@ import org.junit.runner.RunWith;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
import org.springframework.cloud.gateway.handler.RequestPredicateHandlerMapping;
import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
@ -56,7 +56,7 @@ public class HostRoutePredicateIntegrationTests extends BaseWebClientTests { @@ -56,7 +56,7 @@ public class HostRoutePredicateIntegrationTests extends BaseWebClientTests {
assertStatus(response, HttpStatus.OK);
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
.isEqualTo("host_example_to_httpbin");
})

72
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/MethodRequestPredicateFactoryTests.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.gateway.handler.predicate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.handler.RequestPredicateHandlerMapping;
import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.reactive.function.client.ClientResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.gateway.test.TestUtils.assertStatus;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class MethodRequestPredicateFactoryTests extends BaseWebClientTests {
@Test
public void hostRouteWorks() {
Mono<ClientResponse> result = webClient.get()
.uri("/get")
.header("Host", "www.method.org")
.exchange();
StepVerifier.create(result)
.consumeNextWith(
response -> {
assertStatus(response, HttpStatus.OK);
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
.isEqualTo("method_test");
})
.expectComplete()
.verify(DURATION);
}
@EnableAutoConfiguration
@SpringBootConfiguration
@Import(DefaultTestConfig.class)
public static class TestConfig { }
}

6
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateIntegrationTests.java → spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRequestPredicateFactoryTests.java

@ -22,7 +22,7 @@ import org.junit.runner.RunWith; @@ -22,7 +22,7 @@ import org.junit.runner.RunWith;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
import org.springframework.cloud.gateway.handler.RequestPredicateHandlerMapping;
import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
@ -41,7 +41,7 @@ import reactor.test.StepVerifier; @@ -41,7 +41,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class PathRoutePredicateIntegrationTests extends BaseWebClientTests {
public class PathRequestPredicateFactoryTests extends BaseWebClientTests {
@Test
public void pathRouteWorks() {
@ -55,7 +55,7 @@ public class PathRoutePredicateIntegrationTests extends BaseWebClientTests { @@ -55,7 +55,7 @@ public class PathRoutePredicateIntegrationTests extends BaseWebClientTests {
assertStatus(response, HttpStatus.OK);
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
.isEqualTo("default_path_to_httpbin");
})

4
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java

@ -29,7 +29,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -29,7 +29,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
import org.springframework.cloud.gateway.handler.RequestPredicateHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
@ -93,7 +93,7 @@ public class GatewayIntegrationTests extends BaseWebClientTests { @@ -93,7 +93,7 @@ public class GatewayIntegrationTests extends BaseWebClientTests {
assertStatus(response, HttpStatus.OK);
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
.isEqualTo("host_foo_path_headers_to_httpbin");
assertThat(httpHeaders.getFirst("X-Response-Foo"))

7
spring-cloud-gateway-core/src/test/resources/application.yml

@ -80,6 +80,13 @@ spring: @@ -80,6 +80,13 @@ spring:
predicates:
- Host=**.loadbalancerclient.org
# =====================================
- id: method_test
uri: ${test.uri}
predicates:
- Method=GET
- Host=**.method.org
# =====================================
- id: redirect_to_test
uri: ${test.uri}

Loading…
Cancel
Save