Move back to Predicate<ServerWebExchange>
Stick to webflux class as this project is currently built on webflux. fixes gh-35
This commit is contained in:
@@ -30,21 +30,21 @@ 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-request-predicates-factories]]
|
||||
== Request Predicate Factories
|
||||
== Route Predicate Factories
|
||||
|
||||
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`.
|
||||
Spring Cloud Gateway matches routes as part of the Spring WebFlux `HandlerMapping` infrastructure. Spring Cloud Gateway includes many built-in Route Predicate Factorys. All of these predicates match on different attributes of the HTTP request. Multiple Route Predicate Factorys can be combined and are combined via logical `and`.
|
||||
|
||||
=== After Request Predicate Factory
|
||||
TODO: document After Request Predicate Factory
|
||||
=== After Route Predicate Factory
|
||||
TODO: document After Route Predicate Factory
|
||||
|
||||
=== Before Request Predicate Factory
|
||||
TODO: document Before Request Predicate Factory
|
||||
=== Before Route Predicate Factory
|
||||
TODO: document Before Route Predicate Factory
|
||||
|
||||
=== Between Request Predicate Factory
|
||||
TODO: document Between Request Predicate Factory
|
||||
=== Between Route Predicate Factory
|
||||
TODO: document Between Route Predicate Factory
|
||||
|
||||
=== 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.
|
||||
=== Cookie Route Predicate Factory
|
||||
The Cookie Route 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:
|
||||
|
||||
This route matches the request has a cookie named `chocolate` who's value matches the `ch.p` 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.
|
||||
=== Header Route Predicate Factory
|
||||
The Header Route 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:
|
||||
|
||||
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 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.
|
||||
=== Host Route Predicate Factory
|
||||
The Host Route 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:
|
||||
This route would match if the request has a `Host` header has the value `www.somehost.org` or `beta.somehost.org`.
|
||||
|
||||
|
||||
=== Method Request Predicate Factory
|
||||
The Method Request Predicate Factory takes one parameter: the HTTP method to match.
|
||||
=== Method Route Predicate Factory
|
||||
The Method Route Predicate Factory takes one parameter: the HTTP method to match.
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
@@ -120,8 +120,8 @@ spring:
|
||||
|
||||
This route would match if the request method was a `GET`.
|
||||
|
||||
=== Path Request Predicate Factory
|
||||
The Path Request Predicate Factory takes one parameter: a Spring `PathMatcher` pattern.
|
||||
=== Path Route Predicate Factory
|
||||
The Path Route 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
|
||||
|
||||
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,WebFilter Factorys>>
|
||||
|
||||
=== Query Request Predicate Factory
|
||||
TODO: document Query Request Predicate Factory
|
||||
=== Query Route Predicate Factory
|
||||
TODO: document Query Route Predicate Factory
|
||||
|
||||
=== RemoteAddr Request Predicate Factory
|
||||
TODO: document RemoteAddr Request Predicate Factory
|
||||
=== RemoteAddr Route Predicate Factory
|
||||
TODO: document RemoteAddr Route Predicate Factory
|
||||
|
||||
[[gateway-route-filters]]
|
||||
== WebFilter Factorys
|
||||
@@ -210,9 +210,9 @@ TODO: document the `/gateway` actuator endpoint
|
||||
|
||||
TODO: overview of writing custom integrations
|
||||
|
||||
=== Writing Custom Request Predicate Factorys
|
||||
=== Writing Custom Route Predicate Factorys
|
||||
|
||||
TODO: document writing Custom Request Predicate Factorys
|
||||
TODO: document writing Custom Route Predicate Factorys
|
||||
|
||||
=== Writing Custom WebFilter Factorys
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.gateway.actuate.GatewayEndpoint;
|
||||
import org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.MethodRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RemoteAddrRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
|
||||
@@ -54,18 +60,12 @@ import org.springframework.cloud.gateway.filter.factory.SetStatusWebFilterFactor
|
||||
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
|
||||
import org.springframework.cloud.gateway.handler.FilteringWebHandler;
|
||||
import org.springframework.cloud.gateway.handler.NettyRoutingWebHandler;
|
||||
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.handler.RoutePredicateHandlerMapping;
|
||||
import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.CookieRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.HeaderRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.QueryRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.route.CachingRouteLocator;
|
||||
import org.springframework.cloud.gateway.route.CompositeRouteDefinitionLocator;
|
||||
import org.springframework.cloud.gateway.route.CompositeRouteLocator;
|
||||
@@ -135,7 +135,7 @@ public class GatewayAutoConfiguration {
|
||||
@Bean
|
||||
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
|
||||
List<WebFilterFactory> webFilterFactories,
|
||||
List<RequestPredicateFactory> predicates,
|
||||
List<RoutePredicateFactory> predicates,
|
||||
RouteDefinitionLocator routeDefinitionLocator) {
|
||||
return new CachingRouteLocator(new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, webFilterFactories, properties));
|
||||
}
|
||||
@@ -153,9 +153,9 @@ public class GatewayAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestPredicateHandlerMapping requestPredicateHandlerMapping(FilteringWebHandler webHandler,
|
||||
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
|
||||
RouteLocator routeLocator) {
|
||||
return new RequestPredicateHandlerMapping(webHandler, routeLocator);
|
||||
return new RoutePredicateHandlerMapping(webHandler, routeLocator);
|
||||
}
|
||||
|
||||
// ConfigurationProperty beans
|
||||
@@ -185,53 +185,53 @@ public class GatewayAutoConfiguration {
|
||||
// Request Predicate beans
|
||||
|
||||
@Bean
|
||||
public AfterRequestPredicateFactory afterRequestPredicateFactory() {
|
||||
return new AfterRequestPredicateFactory();
|
||||
public AfterRoutePredicateFactory afterRoutePredicateFactory() {
|
||||
return new AfterRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BeforeRequestPredicateFactory beforeRequestPredicateFactory() {
|
||||
return new BeforeRequestPredicateFactory();
|
||||
public BeforeRoutePredicateFactory beforeRoutePredicateFactory() {
|
||||
return new BeforeRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BetweenRequestPredicateFactory betweenRequestPredicateFactory() {
|
||||
return new BetweenRequestPredicateFactory();
|
||||
public BetweenRoutePredicateFactory betweenRoutePredicateFactory() {
|
||||
return new BetweenRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CookieRequestPredicateFactory cookieRequestPredicateFactory() {
|
||||
return new CookieRequestPredicateFactory();
|
||||
public CookieRoutePredicateFactory cookieRoutePredicateFactory() {
|
||||
return new CookieRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HeaderRequestPredicateFactory headerRequestPredicateFactory() {
|
||||
return new HeaderRequestPredicateFactory();
|
||||
public HeaderRoutePredicateFactory headerRoutePredicateFactory() {
|
||||
return new HeaderRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HostRequestPredicateFactory hostRequestPredicateFactory() {
|
||||
return new HostRequestPredicateFactory();
|
||||
public HostRoutePredicateFactory hostRoutePredicateFactory() {
|
||||
return new HostRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MethodRequestPredicateFactory methodRequestPredicateFactory() {
|
||||
return new MethodRequestPredicateFactory();
|
||||
public MethodRoutePredicateFactory methodRoutePredicateFactory() {
|
||||
return new MethodRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PathRequestPredicateFactory pathRequestPredicateFactory() {
|
||||
return new PathRequestPredicateFactory();
|
||||
public PathRoutePredicateFactory pathRoutePredicateFactory() {
|
||||
return new PathRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public QueryRequestPredicateFactory queryRequestPredicateFactory() {
|
||||
return new QueryRequestPredicateFactory();
|
||||
public QueryRoutePredicateFactory queryRoutePredicateFactory() {
|
||||
return new QueryRoutePredicateFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RemoteAddrRequestPredicateFactory remoteAddrRequestPredicateFactory() {
|
||||
return new RemoteAddrRequestPredicateFactory();
|
||||
public RemoteAddrRoutePredicateFactory remoteAddrRoutePredicateFactory() {
|
||||
return new RemoteAddrRoutePredicateFactory();
|
||||
}
|
||||
|
||||
// Filter Factory beans
|
||||
|
||||
@@ -22,14 +22,14 @@ import java.net.URI;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
|
||||
import org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.filter.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
|
||||
import static org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory.REGEXP_KEY;
|
||||
import static org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory.REPLACEMENT_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateFactory.PATTERN_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory.PATTERN_KEY;
|
||||
import static org.springframework.cloud.gateway.support.NameUtils.normalizeFilterName;
|
||||
import static org.springframework.cloud.gateway.support.NameUtils.normalizePredicateName;
|
||||
|
||||
@@ -59,7 +59,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
|
||||
|
||||
// add a predicate that matches the url at /serviceId*
|
||||
PredicateDefinition predicate = new PredicateDefinition();
|
||||
predicate.setName(normalizePredicateName(PathRequestPredicateFactory.class));
|
||||
predicate.setName(normalizePredicateName(PathRoutePredicateFactory.class));
|
||||
predicate.addArg(PATTERN_KEY, "/" + serviceId + "*");
|
||||
routeDefinition.getPredicates().add(predicate);
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
|
||||
@@ -20,7 +20,6 @@ package org.springframework.cloud.gateway.handler;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest;
|
||||
import org.springframework.cloud.gateway.route.Route;
|
||||
import org.springframework.web.reactive.handler.AbstractHandlerMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
@@ -34,12 +33,12 @@ import reactor.core.publisher.Mono;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RequestPredicateHandlerMapping extends AbstractHandlerMapping {
|
||||
public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
|
||||
|
||||
private final WebHandler webHandler;
|
||||
private final RouteLocator routeLocator;
|
||||
|
||||
public RequestPredicateHandlerMapping(WebHandler webHandler, RouteLocator routeLocator) {
|
||||
public RoutePredicateHandlerMapping(WebHandler webHandler, RouteLocator routeLocator) {
|
||||
this.webHandler = webHandler;
|
||||
this.routeLocator = routeLocator;
|
||||
|
||||
@@ -80,7 +79,7 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping {
|
||||
|
||||
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
|
||||
return this.routeLocator.getRoutes()
|
||||
.filter(route -> route.getRequestPredicate().test(new ExchangeServerRequest(exchange)))
|
||||
.filter(route -> route.getPredicate().test(exchange))
|
||||
.next()
|
||||
//TODO: error handling
|
||||
.map(route -> {
|
||||
@@ -20,16 +20,17 @@ package org.springframework.cloud.gateway.handler.predicate;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory.parseZonedDateTime;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory.parseZonedDateTime;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AfterRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class AfterRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String DATETIME_KEY = "datetime";
|
||||
|
||||
@@ -39,10 +40,10 @@ public class AfterRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
final ZonedDateTime dateTime = parseZonedDateTime(args.getString(DATETIME_KEY));
|
||||
|
||||
return request -> {
|
||||
return exchange -> {
|
||||
final ZonedDateTime now = ZonedDateTime.now();
|
||||
return now.isAfter(dateTime);
|
||||
};
|
||||
@@ -20,16 +20,17 @@ package org.springframework.cloud.gateway.handler.predicate;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory.parseZonedDateTime;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory.parseZonedDateTime;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class BeforeRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class BeforeRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String DATETIME_KEY = "datetime";
|
||||
|
||||
@@ -39,10 +40,10 @@ public class BeforeRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
final ZonedDateTime dateTime = parseZonedDateTime(args.getString(DATETIME_KEY));
|
||||
|
||||
return request -> {
|
||||
return exchange -> {
|
||||
final ZonedDateTime now = ZonedDateTime.now();
|
||||
return now.isBefore(dateTime);
|
||||
};
|
||||
@@ -20,28 +20,29 @@ 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.tuple.Tuple;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class BetweenRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class BetweenRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String DATETIME1_KEY = "datetime1";
|
||||
public static final String DATETIME2_KEY = "datetime2";
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
//TODO: is ZonedDateTime the right thing to use?
|
||||
final ZonedDateTime dateTime1 = parseZonedDateTime(args.getString(DATETIME1_KEY));
|
||||
final ZonedDateTime dateTime2 = parseZonedDateTime(args.getString(DATETIME2_KEY));
|
||||
Assert.isTrue(dateTime1.isBefore(dateTime2), args.getString(DATETIME1_KEY) +
|
||||
" must be before " + args.getString(DATETIME2_KEY));
|
||||
|
||||
return request -> {
|
||||
return exchange -> {
|
||||
final ZonedDateTime now = ZonedDateTime.now();
|
||||
return now.isAfter(dateTime1) && now.isBefore(dateTime2);
|
||||
};
|
||||
@@ -19,17 +19,16 @@ package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class CookieRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class CookieRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String NAME_KEY = "name";
|
||||
public static final String REGEXP_KEY = "regexp";
|
||||
@@ -40,13 +39,12 @@ public class CookieRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
String name = args.getString(NAME_KEY);
|
||||
String regexp = args.getString(REGEXP_KEY);
|
||||
|
||||
return request -> {
|
||||
Optional<ServerWebExchange> exchange = request.attribute("exchange");
|
||||
List<HttpCookie> cookies = exchange.get().getRequest().getCookies().get(name);
|
||||
return exchange -> {
|
||||
List<HttpCookie> cookies = exchange.getRequest().getCookies().get(name);
|
||||
for (HttpCookie cookie : cookies) {
|
||||
if (cookie.getValue().matches(regexp)) {
|
||||
return true;
|
||||
@@ -1,58 +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 org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
|
||||
import static org.springframework.cloud.gateway.handler.predicate.RequestPredicateFactory.PATTERN_KEY;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class GatewayRequestPredicates {
|
||||
|
||||
//TODO: add support for AfterRequestPredicateFactory
|
||||
|
||||
//TODO: add support for BeforeRequestPredicateFactory
|
||||
|
||||
//TODO: add support for BetweenRequestPredicateFactory
|
||||
|
||||
//TODO: add support for CookieRequestPredicateFactory
|
||||
|
||||
//TODO: add support for GatewayRequestPredicates
|
||||
|
||||
//TODO: add support for HeaderRequestPredicateFactory
|
||||
|
||||
public static RequestPredicate host(String pattern) {
|
||||
return new HostRequestPredicateFactory().apply(tuple().of(PATTERN_KEY, pattern));
|
||||
}
|
||||
|
||||
//TODO: add support for MethodRequestPredicateFactory
|
||||
|
||||
public static RequestPredicate path(String pattern) {
|
||||
return new PathRequestPredicateFactory().apply(tuple().of(PATTERN_KEY, pattern));
|
||||
}
|
||||
|
||||
//TODO: add support for PredicateDefinition
|
||||
|
||||
//TODO: add support for QueryRequestPredicateFactory
|
||||
|
||||
//TODO: add support for RemoteAddrRequestPredicateFactory
|
||||
|
||||
}
|
||||
@@ -19,15 +19,15 @@ package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HeaderRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class HeaderRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String HEADER_KEY = "header";
|
||||
public static final String REGEXP_KEY = "regexp";
|
||||
@@ -38,18 +38,18 @@ public class HeaderRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
String header = args.getString(HEADER_KEY);
|
||||
String regexp = args.getString(REGEXP_KEY);
|
||||
|
||||
return RequestPredicates.headers(headers -> {
|
||||
List<String> values = headers.asHttpHeaders().get(header);
|
||||
return exchange -> {
|
||||
List<String> values = exchange.getRequest().getHeaders().get(header);
|
||||
for (String value : values) {
|
||||
if (value.matches(regexp)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -19,17 +19,17 @@ package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HostRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class HostRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
private PathMatcher pathMatcher = new AntPathMatcher(".");
|
||||
|
||||
@@ -43,12 +43,12 @@ public class HostRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
String pattern = args.getString(PATTERN_KEY);
|
||||
|
||||
return RequestPredicates.headers(headers -> {
|
||||
String host = headers.asHttpHeaders().getFirst("Host");
|
||||
return exchange -> {
|
||||
String host = exchange.getRequest().getHeaders().getFirst("Host");
|
||||
return this.pathMatcher.match(pattern, host);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -17,18 +17,18 @@
|
||||
|
||||
package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class MethodRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class MethodRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String METHOD_KEY = "method";
|
||||
|
||||
@@ -38,8 +38,11 @@ public class MethodRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
String method = args.getString(METHOD_KEY);
|
||||
return RequestPredicates.method(HttpMethod.resolve(method));
|
||||
return exchange -> {
|
||||
HttpMethod requestMethod = exchange.getRequest().getMethod();
|
||||
return requestMethod.matches(method);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,54 +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 org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class PathRequestPredicateFactory implements RequestPredicateFactory {
|
||||
|
||||
private PathPatternParser pathPatternParser;
|
||||
|
||||
public void setPathPatternParser(PathPatternParser pathPatternParser) {
|
||||
this.pathPatternParser = pathPatternParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> argNames() {
|
||||
return Collections.singletonList(PATTERN_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
String pattern = args.getString(PATTERN_KEY);
|
||||
|
||||
if (this.pathPatternParser != null) {
|
||||
return RequestPredicates.pathPredicates(this.pathPatternParser).apply(pattern);
|
||||
}
|
||||
|
||||
return RequestPredicates.path(pattern);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.patterns.PathPattern;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
import static org.springframework.cloud.gateway.handler.support.RoutePredicateFactoryUtils.traceMatch;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class PathRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
private PathPatternParser pathPatternParser = new PathPatternParser();
|
||||
|
||||
public void setPathPatternParser(PathPatternParser pathPatternParser) {
|
||||
this.pathPatternParser = pathPatternParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> argNames() {
|
||||
return Collections.singletonList(PATTERN_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
String unparsedPattern = args.getString(PATTERN_KEY);
|
||||
PathPattern pattern;
|
||||
synchronized (this.pathPatternParser) {
|
||||
pattern = this.pathPatternParser.parse(unparsedPattern);
|
||||
}
|
||||
|
||||
return exchange -> {
|
||||
String path = exchange.getRequest().getURI().getPath();
|
||||
boolean match = pattern.matches(path);
|
||||
traceMatch("Pattern", pattern.getPatternString(), path, match);
|
||||
if (match) {
|
||||
Map<String, String> uriTemplateVariables = pattern.matchAndExtract(path);
|
||||
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -19,17 +19,15 @@ package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class QueryRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class QueryRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
public static final String PARAM_KEY = "param";
|
||||
public static final String REGEXP_KEY = "regexp";
|
||||
@@ -45,20 +43,25 @@ public class QueryRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
validateMin(1, args);
|
||||
String param = args.getString(PARAM_KEY);
|
||||
|
||||
if (!args.hasFieldName(REGEXP_KEY)) {
|
||||
return req -> {
|
||||
//TODO: ServerRequest support for query params with no value
|
||||
Optional<ServerWebExchange> exchange = req.attribute("exchange");
|
||||
return exchange.get().getRequest().getQueryParams().containsKey(param);
|
||||
};
|
||||
}
|
||||
return exchange -> {
|
||||
if (!args.hasFieldName(REGEXP_KEY)) {
|
||||
// check existence of header
|
||||
return exchange.getRequest().getQueryParams().containsKey(param);
|
||||
}
|
||||
|
||||
String regexp = args.getString(REGEXP_KEY);
|
||||
String regexp = args.getString(REGEXP_KEY);
|
||||
|
||||
return RequestPredicates.queryParam(param, value -> value.matches(regexp));
|
||||
List<String> values = exchange.getRequest().getQueryParams().get(param);
|
||||
for (String value : values) {
|
||||
if (value.matches(regexp)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -21,23 +21,23 @@ import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.gateway.support.SubnetUtils;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RemoteAddrRequestPredicateFactory implements RequestPredicateFactory {
|
||||
public class RemoteAddrRoutePredicateFactory implements RoutePredicateFactory {
|
||||
|
||||
private static final Log log = LogFactory.getLog(RemoteAddrRequestPredicateFactory.class);
|
||||
private static final Log log = LogFactory.getLog(RemoteAddrRoutePredicateFactory.class);
|
||||
|
||||
@Override
|
||||
public RequestPredicate apply(Tuple args) {
|
||||
public Predicate<ServerWebExchange> apply(Tuple args) {
|
||||
validate(1, args);
|
||||
|
||||
List<SubnetUtils> sources = new ArrayList<>();
|
||||
@@ -47,12 +47,11 @@ public class RemoteAddrRequestPredicateFactory implements RequestPredicateFactor
|
||||
}
|
||||
}
|
||||
|
||||
return request -> {
|
||||
Optional<ServerWebExchange> exchange = request.attribute("exchange");
|
||||
Optional<InetSocketAddress> remoteAddress = exchange.get().getRequest().getRemoteAddress();
|
||||
return exchange -> {
|
||||
Optional<InetSocketAddress> remoteAddress = exchange.getRequest().getRemoteAddress();
|
||||
if (remoteAddress.isPresent()) {
|
||||
String hostAddress = remoteAddress.get().getAddress().getHostAddress();
|
||||
String host = request.uri().getHost();
|
||||
String host = exchange.getRequest().getURI().getHost();
|
||||
|
||||
if (!hostAddress.equals(host)) {
|
||||
log.warn("Remote addresses didn't match " + hostAddress + " != " + host);
|
||||
@@ -17,19 +17,21 @@
|
||||
|
||||
package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.cloud.gateway.support.ArgumentHints;
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RequestPredicateFactory extends ArgumentHints {
|
||||
public interface RoutePredicateFactory extends ArgumentHints {
|
||||
String PATTERN_KEY = "pattern";
|
||||
|
||||
RequestPredicate apply(Tuple args);
|
||||
Predicate<ServerWebExchange> apply(Tuple args);
|
||||
|
||||
default String name() {
|
||||
return NameUtils.normalizePredicateName(getClass());
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.function.Predicate;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory.PATTERN_KEY;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RoutePredicates {
|
||||
|
||||
//TODO: add support for AfterRoutePredicateFactory
|
||||
|
||||
//TODO: add support for BeforeRoutePredicateFactory
|
||||
|
||||
//TODO: add support for BetweenRoutePredicateFactory
|
||||
|
||||
//TODO: add support for CookieRoutePredicateFactory
|
||||
|
||||
//TODO: add support for RoutePredicates
|
||||
|
||||
//TODO: add support for HeaderRoutePredicateFactory
|
||||
|
||||
public static Predicate<ServerWebExchange> host(String pattern) {
|
||||
return new HostRoutePredicateFactory().apply(tuple().of(PATTERN_KEY, pattern));
|
||||
}
|
||||
|
||||
//TODO: add support for MethodRoutePredicateFactory
|
||||
|
||||
public static Predicate<ServerWebExchange> path(String pattern) {
|
||||
return new PathRoutePredicateFactory().apply(tuple().of(PATTERN_KEY, pattern));
|
||||
}
|
||||
|
||||
//TODO: add support for PredicateDefinition
|
||||
|
||||
//TODO: add support for QueryRoutePredicateFactory
|
||||
|
||||
//TODO: add support for RemoteAddrRoutePredicateFactory
|
||||
|
||||
}
|
||||
@@ -1,233 +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.support;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpRange;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.BodyExtractor;
|
||||
import org.springframework.web.reactive.function.BodyExtractors;
|
||||
import org.springframework.web.reactive.function.UnsupportedMediaTypeException;
|
||||
import org.springframework.web.reactive.function.server.HandlerStrategies;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
import org.springframework.web.server.WebSession;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* {@code ServerRequest} implementation based on a {@link ServerWebExchange}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0
|
||||
*/
|
||||
public class ExchangeServerRequest implements ServerRequest {
|
||||
|
||||
private static final Function<UnsupportedMediaTypeException, UnsupportedMediaTypeStatusException> ERROR_MAPPER =
|
||||
ex -> ex.getContentType()
|
||||
.map(contentType -> new UnsupportedMediaTypeStatusException(contentType,
|
||||
ex.getSupportedMediaTypes()))
|
||||
.orElseGet(() -> new UnsupportedMediaTypeStatusException(ex.getMessage()));
|
||||
|
||||
private final ServerWebExchange exchange;
|
||||
|
||||
private final Headers headers;
|
||||
|
||||
private final HandlerStrategies strategies;
|
||||
|
||||
public ExchangeServerRequest(ServerWebExchange exchange) {
|
||||
this(exchange, HandlerStrategies.withDefaults());
|
||||
}
|
||||
|
||||
public ExchangeServerRequest(ServerWebExchange exchange, HandlerStrategies strategies) {
|
||||
this.exchange = exchange;
|
||||
this.strategies = strategies;
|
||||
this.headers = new ExchangeServerRequest.DefaultHeaders();
|
||||
this.exchange.getAttributes().put("exchange", this.exchange);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public HttpMethod method() {
|
||||
return request().getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI uri() {
|
||||
return request().getURI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers headers() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor) {
|
||||
return body(extractor, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor, Map<String, Object> hints) {
|
||||
Assert.notNull(extractor, "'extractor' must not be null");
|
||||
return extractor.extract(request(),
|
||||
new BodyExtractor.Context() {
|
||||
@Override
|
||||
public Supplier<Stream<HttpMessageReader<?>>> messageReaders() {
|
||||
return ExchangeServerRequest.this.strategies.messageReaders();
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> hints() {
|
||||
return hints;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<T> bodyToMono(Class<? extends T> elementClass) {
|
||||
Mono<T> mono = body(BodyExtractors.toMono(elementClass));
|
||||
return mono.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Flux<T> bodyToFlux(Class<? extends T> elementClass) {
|
||||
Flux<T> flux = body(BodyExtractors.toFlux(elementClass));
|
||||
return flux.mapError(UnsupportedMediaTypeException.class, ERROR_MAPPER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> attribute(String name) {
|
||||
return this.exchange.getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> attributes() {
|
||||
return this.exchange.getAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryParams(String name) {
|
||||
List<String> queryParams = request().getQueryParams().get(name);
|
||||
return queryParams != null ? queryParams : Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> pathVariables() {
|
||||
return this.exchange.<Map<String, String>>getAttribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE).
|
||||
orElseGet(Collections::emptyMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<WebSession> session() {
|
||||
return this.exchange.getSession();
|
||||
}
|
||||
|
||||
private ServerHttpRequest request() {
|
||||
return this.exchange.getRequest();
|
||||
}
|
||||
|
||||
public ServerWebExchange exchange() {
|
||||
return this.exchange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s %s", method(), path());
|
||||
}
|
||||
|
||||
|
||||
private class DefaultHeaders implements Headers {
|
||||
|
||||
private HttpHeaders delegate() {
|
||||
return request().getHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MediaType> accept() {
|
||||
return delegate().getAccept();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Charset> acceptCharset() {
|
||||
return delegate().getAcceptCharset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Locale.LanguageRange> acceptLanguage() {
|
||||
return delegate().getAcceptLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong contentLength() {
|
||||
long value = delegate().getContentLength();
|
||||
return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<MediaType> contentType() {
|
||||
return Optional.ofNullable(delegate().getContentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress host() {
|
||||
return delegate().getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpRange> range() {
|
||||
return delegate().getRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> header(String headerName) {
|
||||
List<String> headerValues = delegate().get(headerName);
|
||||
return (headerValues != null ? headerValues : Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders asHttpHeaders() {
|
||||
return HttpHeaders.readOnlyHttpHeaders(delegate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate().toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.support;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RoutePredicateFactoryUtils {
|
||||
private static final Log logger = LogFactory.getLog(RoutePredicateFactory.class);
|
||||
|
||||
public static void traceMatch(String prefix, Object desired, Object actual, boolean match) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
String message = String.format("%s \"%s\" %s against value \"%s\"",
|
||||
prefix, desired, match ? "matches" : "does not match", actual);
|
||||
logger.trace(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,10 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,7 @@ public class Route {
|
||||
|
||||
private final URI uri;
|
||||
|
||||
private final RequestPredicate requestPredicate;
|
||||
private final Predicate<ServerWebExchange> predicate;
|
||||
|
||||
private final List<WebFilter> webFilters;
|
||||
|
||||
@@ -51,10 +52,10 @@ public class Route {
|
||||
.uri(routeDefinition.getUri());
|
||||
}
|
||||
|
||||
public Route(String id, URI uri, RequestPredicate requestPredicate, List<WebFilter> webFilters) {
|
||||
public Route(String id, URI uri, Predicate<ServerWebExchange> predicate, List<WebFilter> webFilters) {
|
||||
this.id = id;
|
||||
this.uri = uri;
|
||||
this.requestPredicate = requestPredicate;
|
||||
this.predicate = predicate;
|
||||
this.webFilters = webFilters;
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ public class Route {
|
||||
|
||||
private URI uri;
|
||||
|
||||
private RequestPredicate requestPredicate;
|
||||
private Predicate<ServerWebExchange> predicate;
|
||||
|
||||
private List<WebFilter> webFilters = new ArrayList<>();
|
||||
|
||||
@@ -84,8 +85,8 @@ public class Route {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder requestPredicate(RequestPredicate requestPredicate) {
|
||||
this.requestPredicate = requestPredicate;
|
||||
public Builder predicate(Predicate<ServerWebExchange> predicate) {
|
||||
this.predicate = predicate;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -107,9 +108,9 @@ public class Route {
|
||||
public Route build() {
|
||||
Assert.notNull(this.id, "id can not be null");
|
||||
Assert.notNull(this.uri, "uri can not be null");
|
||||
//TODO: Assert.notNull(this.requestPredicate, "requestPredicates can not be null");
|
||||
//TODO: Assert.notNull(this.predicate, "predicate can not be null");
|
||||
|
||||
return new Route(this.id, this.uri, this.requestPredicate, this.webFilters);
|
||||
return new Route(this.id, this.uri, this.predicate, this.webFilters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,8 +122,8 @@ public class Route {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
public RequestPredicate getRequestPredicate() {
|
||||
return this.requestPredicate;
|
||||
public Predicate<ServerWebExchange> getPredicate() {
|
||||
return this.predicate;
|
||||
}
|
||||
|
||||
public List<WebFilter> getWebFilters() {
|
||||
@@ -136,13 +137,13 @@ public class Route {
|
||||
Route route = (Route) o;
|
||||
return Objects.equals(id, route.id) &&
|
||||
Objects.equals(uri, route.uri) &&
|
||||
Objects.equals(requestPredicate, route.requestPredicate) &&
|
||||
Objects.equals(predicate, route.predicate) &&
|
||||
Objects.equals(webFilters, route.webFilters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, uri, requestPredicate, webFilters);
|
||||
return Objects.hash(id, uri, predicate, webFilters);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,7 +151,7 @@ public class Route {
|
||||
final StringBuffer sb = new StringBuffer("Route{");
|
||||
sb.append("id='").append(id).append('\'');
|
||||
sb.append(", uri=").append(uri);
|
||||
sb.append(", requestPredicates=").append(requestPredicate);
|
||||
sb.append(", predicate=").append(predicate);
|
||||
sb.append(", webFilters=").append(webFilters);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -31,17 +32,13 @@ import org.springframework.cloud.gateway.filter.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.filter.OrderedWebFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RequestPredicateFactory;
|
||||
import org.springframework.cloud.gateway.route.Route;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.support.ArgumentHints;
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.tuple.TupleBuilder;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -54,31 +51,31 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final RouteDefinitionLocator routeDefinitionLocator;
|
||||
private final Map<String, RequestPredicateFactory> requestPredicates = new LinkedHashMap<>();
|
||||
private final Map<String, RoutePredicateFactory> predicates = new LinkedHashMap<>();
|
||||
private final Map<String, WebFilterFactory> webFilterFactories = new HashMap<>();
|
||||
private final GatewayProperties gatewayProperties;
|
||||
|
||||
public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,
|
||||
List<RequestPredicateFactory> requestPredicates,
|
||||
List<RoutePredicateFactory> predicates,
|
||||
List<WebFilterFactory> webFilterFactories,
|
||||
GatewayProperties gatewayProperties) {
|
||||
this.routeDefinitionLocator = routeDefinitionLocator;
|
||||
initFactories(requestPredicates);
|
||||
initFactories(predicates);
|
||||
webFilterFactories.forEach(factory -> this.webFilterFactories.put(factory.name(), factory));
|
||||
this.gatewayProperties = gatewayProperties;
|
||||
}
|
||||
|
||||
private void initFactories(List<RequestPredicateFactory> requestPredicates) {
|
||||
requestPredicates.forEach(factory -> {
|
||||
private void initFactories(List<RoutePredicateFactory> predicates) {
|
||||
predicates.forEach(factory -> {
|
||||
String key = factory.name();
|
||||
if (this.requestPredicates.containsKey(key)) {
|
||||
this.logger.warn("A RequestPredicateFactory named "+ key
|
||||
+ " already exists, class: " + this.requestPredicates.get(key)
|
||||
if (this.predicates.containsKey(key)) {
|
||||
this.logger.warn("A RoutePredicateFactory named "+ key
|
||||
+ " already exists, class: " + this.predicates.get(key)
|
||||
+ ". It will be overwritten.");
|
||||
}
|
||||
this.requestPredicates.put(key, factory);
|
||||
this.predicates.put(key, factory);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Loaded RequestPredicateFactory [" + key + "]");
|
||||
logger.info("Loaded RoutePredicateFactory [" + key + "]");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -102,19 +99,16 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
private Route convertToRoute(RouteDefinition routeDefinition) {
|
||||
RequestPredicate requestPredicate = combinePredicates(routeDefinition);
|
||||
Predicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
|
||||
List<WebFilter> webFilters = getFilters(routeDefinition);
|
||||
|
||||
return Route.builder(routeDefinition)
|
||||
.requestPredicate(requestPredicate)
|
||||
.predicate(predicate)
|
||||
.webFilters(webFilters)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<WebFilter> loadWebFilters(String id, List<FilterDefinition> filterDefinitions) {
|
||||
List<WebFilter> filters = filterDefinitions.stream()
|
||||
.map(definition -> {
|
||||
@@ -157,7 +151,7 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
for (Map.Entry<String, String> entry : args.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
|
||||
// RequestPredicateFactory has name hints and this has a fake key name
|
||||
// RoutePredicateFactory has name hints and this has a fake key name
|
||||
// replace with the matching key hint
|
||||
if (key.startsWith(NameUtils.GENERATED_NAME_PREFIX) && !argNames.isEmpty()
|
||||
&& entryIdx < args.size()) {
|
||||
@@ -197,22 +191,22 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
return filters;
|
||||
}
|
||||
|
||||
private RequestPredicate combinePredicates(RouteDefinition routeDefinition) {
|
||||
private Predicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
|
||||
List<PredicateDefinition> predicates = routeDefinition.getPredicates();
|
||||
RequestPredicate predicate = lookup(routeDefinition, predicates.get(0));
|
||||
Predicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0));
|
||||
|
||||
for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
|
||||
RequestPredicate found = lookup(routeDefinition, andPredicate);
|
||||
Predicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
|
||||
predicate = predicate.and(found);
|
||||
}
|
||||
|
||||
return predicate;
|
||||
}
|
||||
|
||||
private RequestPredicate lookup(RouteDefinition routeDefinition, PredicateDefinition predicate) {
|
||||
RequestPredicateFactory found = this.requestPredicates.get(predicate.getName());
|
||||
private Predicate<ServerWebExchange> lookup(RouteDefinition routeDefinition, PredicateDefinition predicate) {
|
||||
RoutePredicateFactory found = this.predicates.get(predicate.getName());
|
||||
if (found == null) {
|
||||
throw new IllegalArgumentException("Unable to find RequestPredicateFactory with name " + predicate.getName());
|
||||
throw new IllegalArgumentException("Unable to find RoutePredicateFactory with name " + predicate.getName());
|
||||
}
|
||||
Map<String, String> args = predicate.getArgs();
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -21,9 +21,10 @@ import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.factory.WebFilterFactories;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -94,13 +95,16 @@ public class Routes {
|
||||
this.locatorBuilder = locatorBuilder;
|
||||
}
|
||||
|
||||
/* TODO: has and, or & negate of RequestPredicate with terminal filters()?
|
||||
public RequestPredicateBuilder host(String pattern) {
|
||||
RequestPredicate requestPredicate = GatewayRequestPredicates.host(pattern);
|
||||
/* TODO: has and, or & negate of Predicate with terminal andFilters()?
|
||||
public RoutePredicateBuilder predicate() {
|
||||
}
|
||||
// this goes in new class
|
||||
public RoutePredicateBuilder host(String pattern) {
|
||||
Predicate<ServerWebExchange> predicate = RoutePredicates.host(pattern);
|
||||
}*/
|
||||
|
||||
public WebFilterSpec predicate(RequestPredicate predicate) {
|
||||
this.routeBuilder.requestPredicate(predicate);
|
||||
public WebFilterSpec predicate(Predicate<ServerWebExchange> predicate) {
|
||||
this.routeBuilder.predicate(predicate);
|
||||
return webFilterBuilder();
|
||||
}
|
||||
|
||||
@@ -138,6 +142,7 @@ public class Routes {
|
||||
return add(WebFilterFactories.addResponseHeader(headerName, headerValue));
|
||||
}
|
||||
|
||||
// TODO: build()?
|
||||
public LocatorBuilder and() {
|
||||
Route route = this.builder.build();
|
||||
this.locatorBuilder.add(route);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package org.springframework.cloud.gateway.support;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RequestPredicateFactory;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -30,8 +30,8 @@ public class NameUtils {
|
||||
return GENERATED_NAME_PREFIX + i;
|
||||
}
|
||||
|
||||
public static String normalizePredicateName(Class<? extends RequestPredicateFactory> clazz) {
|
||||
return clazz.getSimpleName().replace(RequestPredicateFactory.class.getSimpleName(), "");
|
||||
public static String normalizePredicateName(Class<? extends RoutePredicateFactory> clazz) {
|
||||
return clazz.getSimpleName().replace(RoutePredicateFactory.class.getSimpleName(), "");
|
||||
}
|
||||
|
||||
public static String normalizeFilterName(Class<? extends WebFilterFactory> clazz) {
|
||||
|
||||
@@ -26,8 +26,12 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ServerWebExchangeUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ServerWebExchangeUtils.class);
|
||||
|
||||
public static final String URI_TEMPLATE_VARIABLES_ATTRIBUTE =
|
||||
ServerWebExchangeUtils.class.getName() + ".uriTemplateVariables";
|
||||
|
||||
public static final String CLIENT_RESPONSE_ATTR = "webHandlerClientResponse";
|
||||
public static final String GATEWAY_ROUTE_ATTR = "gatewayRoute";
|
||||
public static final String GATEWAY_REQUEST_URL_ATTR = "gatewayRequestUrl";
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.http.server.reactive.MockServerWebExchange;
|
||||
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;
|
||||
@@ -32,6 +31,7 @@ import org.springframework.web.server.WebFilterChain;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.cloud.gateway.filter.factory.SetPathWebFilterFactory.TEMPLATE_KEY;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -62,7 +62,7 @@ public class SetPathWebFilterFactoryTests {
|
||||
.build();
|
||||
|
||||
ServerWebExchange exchange = new MockServerWebExchange(request);
|
||||
exchange.getAttributes().put(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, variables);
|
||||
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, variables);
|
||||
|
||||
WebFilterChain filterChain = mock(WebFilterChain.class);
|
||||
|
||||
|
||||
@@ -20,18 +20,18 @@ 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.AfterRequestPredicateFactory.DATETIME_KEY;
|
||||
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;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory.DATETIME_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.getExchange;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHours;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHoursMillis;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHours;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHoursMillis;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AfterRequestPredicateFactoryTests {
|
||||
public class AfterRoutePredicateFactoryTests {
|
||||
|
||||
@Test
|
||||
public void beforeStringWorks() {
|
||||
@@ -70,6 +70,6 @@ public class AfterRequestPredicateFactoryTests {
|
||||
}
|
||||
|
||||
private boolean runPredicate(String dateString) {
|
||||
return new AfterRequestPredicateFactory().apply(tuple().of(DATETIME_KEY, dateString)).test(getRequest());
|
||||
return new AfterRoutePredicateFactory().apply(tuple().of(DATETIME_KEY, dateString)).test(getExchange());
|
||||
}
|
||||
}
|
||||
@@ -20,18 +20,18 @@ 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.BeforeRequestPredicateFactory.DATETIME_KEY;
|
||||
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;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory.DATETIME_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.getExchange;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHours;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHoursMillis;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHours;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHoursMillis;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class BeforeRequestPredicateFactoryTests {
|
||||
public class BeforeRoutePredicateFactoryTests {
|
||||
|
||||
@Test
|
||||
public void beforeStringWorks() {
|
||||
@@ -70,6 +70,6 @@ public class BeforeRequestPredicateFactoryTests {
|
||||
}
|
||||
|
||||
private boolean runPredicate(String dateString) {
|
||||
return new BeforeRequestPredicateFactory().apply(tuple().of(DATETIME_KEY, dateString)).test(getRequest());
|
||||
return new BeforeRoutePredicateFactory().apply(tuple().of(DATETIME_KEY, dateString)).test(getExchange());
|
||||
}
|
||||
}
|
||||
@@ -21,20 +21,19 @@ import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.gateway.handler.support.ExchangeServerRequest;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.http.server.reactive.MockServerWebExchange;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory.DATETIME1_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactory.DATETIME2_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory.DATETIME1_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory.DATETIME2_KEY;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class BetweenRequestPredicateFactoryTests {
|
||||
public class BetweenRoutePredicateFactoryTests {
|
||||
|
||||
@Test
|
||||
public void beforeStringWorks() {
|
||||
@@ -97,8 +96,8 @@ public class BetweenRequestPredicateFactoryTests {
|
||||
}
|
||||
|
||||
boolean runPredicate(String dateString1, String dateString2) {
|
||||
return new BetweenRequestPredicateFactory().apply(tuple()
|
||||
.of(DATETIME1_KEY, dateString1, DATETIME2_KEY, dateString2)).test(getRequest());
|
||||
return new BetweenRoutePredicateFactory().apply(tuple()
|
||||
.of(DATETIME1_KEY, dateString1, DATETIME2_KEY, dateString2)).test(getExchange());
|
||||
}
|
||||
|
||||
static String minusHoursMillis(int hours) {
|
||||
@@ -119,8 +118,8 @@ public class BetweenRequestPredicateFactoryTests {
|
||||
return ZonedDateTime.now().plusHours(hours).format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
|
||||
}
|
||||
|
||||
static ServerRequest getRequest() {
|
||||
static ServerWebExchange getExchange() {
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("http://example.com").build();
|
||||
return new ExchangeServerRequest(new MockServerWebExchange(request));
|
||||
return new MockServerWebExchange(request);
|
||||
}
|
||||
}
|
||||
@@ -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.RequestPredicateHandlerMapping;
|
||||
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
|
||||
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;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class HostRequestPredicateFactoryTests extends BaseWebClientTests {
|
||||
public class HostRoutePredicateFactoryTests extends BaseWebClientTests {
|
||||
|
||||
@Test
|
||||
public void hostRouteWorks() {
|
||||
@@ -56,7 +56,7 @@ public class HostRequestPredicateFactoryTests extends BaseWebClientTests {
|
||||
assertStatus(response, HttpStatus.OK);
|
||||
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
|
||||
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
|
||||
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
|
||||
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
|
||||
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
|
||||
.isEqualTo("host_example_to_httpbin");
|
||||
})
|
||||
@@ -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.RequestPredicateHandlerMapping;
|
||||
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
|
||||
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;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class MethodRequestPredicateFactoryTests extends BaseWebClientTests {
|
||||
public class MethodRoutePredicateFactoryTests extends BaseWebClientTests {
|
||||
|
||||
@Test
|
||||
public void hostRouteWorks() {
|
||||
@@ -56,7 +56,7 @@ public class MethodRequestPredicateFactoryTests extends BaseWebClientTests {
|
||||
assertStatus(response, HttpStatus.OK);
|
||||
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
|
||||
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
|
||||
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
|
||||
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
|
||||
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
|
||||
.isEqualTo("method_test");
|
||||
})
|
||||
@@ -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.RequestPredicateHandlerMapping;
|
||||
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
|
||||
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;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
public class PathRequestPredicateFactoryTests extends BaseWebClientTests {
|
||||
public class PathRoutePredicateFactoryTests extends BaseWebClientTests {
|
||||
|
||||
@Test
|
||||
public void pathRouteWorks() {
|
||||
@@ -55,7 +55,7 @@ public class PathRequestPredicateFactoryTests extends BaseWebClientTests {
|
||||
assertStatus(response, HttpStatus.OK);
|
||||
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
|
||||
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
|
||||
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
|
||||
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
|
||||
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
|
||||
.isEqualTo("default_path_to_httpbin");
|
||||
})
|
||||
@@ -34,12 +34,12 @@ import org.springframework.cloud.gateway.filter.factory.SetPathWebFilterFactoryI
|
||||
import org.springframework.cloud.gateway.filter.factory.SetPathWebFilterFactoryTests;
|
||||
import org.springframework.cloud.gateway.filter.factory.SetResponseWebFilterFactoryTests;
|
||||
import org.springframework.cloud.gateway.filter.factory.SetStatusWebFilterFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.AfterRequestPredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.BeforeRequestPredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.BetweenRequestPredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.HostRequestPredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.MethodRequestPredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.MethodRoutePredicateFactoryTests;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactoryTests;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -62,13 +62,13 @@ import org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateF
|
||||
SetResponseWebFilterFactoryTests.class,
|
||||
SetStatusWebFilterFactoryTests.class,
|
||||
RewritePathWebFilterFactoryTests.class,
|
||||
// RequestPredicateFactory tests
|
||||
AfterRequestPredicateFactoryTests.class,
|
||||
BeforeRequestPredicateFactoryTests.class,
|
||||
BetweenRequestPredicateFactoryTests.class,
|
||||
HostRequestPredicateFactoryTests.class,
|
||||
MethodRequestPredicateFactoryTests.class,
|
||||
PathRequestPredicateFactoryTests.class,
|
||||
// RoutePredicateFactory tests
|
||||
AfterRoutePredicateFactoryTests.class,
|
||||
BeforeRoutePredicateFactoryTests.class,
|
||||
BetweenRoutePredicateFactoryTests.class,
|
||||
HostRoutePredicateFactoryTests.class,
|
||||
MethodRoutePredicateFactoryTests.class,
|
||||
PathRoutePredicateFactoryTests.class,
|
||||
})
|
||||
public class AdhocTestSuite {
|
||||
}
|
||||
|
||||
@@ -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.RequestPredicateHandlerMapping;
|
||||
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
|
||||
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 {
|
||||
assertStatus(response, HttpStatus.OK);
|
||||
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
|
||||
assertThat(httpHeaders.getFirst(HANDLER_MAPPER_HEADER))
|
||||
.isEqualTo(RequestPredicateHandlerMapping.class.getSimpleName());
|
||||
.isEqualTo(RoutePredicateHandlerMapping.class.getSimpleName());
|
||||
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
|
||||
.isEqualTo("host_foo_path_headers_to_httpbin");
|
||||
assertThat(httpHeaders.getFirst("X-Response-Foo"))
|
||||
|
||||
0
spring-cloud-gateway-sample/.jdk8
Normal file
0
spring-cloud-gateway-sample/.jdk8
Normal file
@@ -26,9 +26,8 @@ import org.springframework.cloud.gateway.route.Routes;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import static org.springframework.cloud.gateway.filter.factory.WebFilterFactories.addResponseHeader;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.GatewayRequestPredicates.host;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.GatewayRequestPredicates.path;
|
||||
// import static org.springframework.web.reactive.function.server.RequestPredicates.path;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
|
||||
Reference in New Issue
Block a user