Skip to content

Commit

Permalink
Use RequestPredicate instead of Predicate<ServerWebExchange>
Browse files Browse the repository at this point in the history
renames RoutePredicate -> RequestPredicateFactory
  • Loading branch information
spencergibb committed Mar 15, 2017
1 parent 69cb823 commit cd7767e
Show file tree
Hide file tree
Showing 28 changed files with 375 additions and 294 deletions.
50 changes: 25 additions & 25 deletions docs/src/main/asciidoc/spring-cloud-gateway.adoc
Expand Up @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down
Expand Up @@ -27,18 +27,18 @@
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;
Expand All @@ -51,19 +51,19 @@
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;
Expand Down Expand Up @@ -119,10 +119,10 @@ public FilteringWebHandler filteringWebHandler(GatewayProperties properties, Lis
}

@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
Expand Down Expand Up @@ -159,56 +159,56 @@ public WriteResponseFilter writeResponseFilter() {
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
Expand Down
Expand Up @@ -20,12 +20,12 @@
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;
Expand Down Expand Up @@ -56,7 +56,7 @@ public Flux<Route> getRoutes() {

// 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);

Expand Down
Expand Up @@ -20,12 +20,12 @@
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
Expand All @@ -39,7 +39,7 @@ public WebFilter apply(String... args) {
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();
Expand Down

0 comments on commit cd7767e

Please sign in to comment.