Change from using WebFliter to custom GatewayFilter.

This avoids any confusion with how WebFilters are using in WebFlux.
This commit is contained in:
Spencer Gibb
2017-10-13 11:56:15 -04:00
parent 40f2528a3e
commit 5a23335375
62 changed files with 556 additions and 513 deletions

View File

@@ -25,7 +25,7 @@ If you include the starter, but, for some reason, you do not want the gateway to
* *Route*: Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true.
* *Predicate*: This is a http://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html[Java 8 Function Predicate]. The input type is a http://docs.spring.io/spring/docs/5.0.x/javadoc-api/org/springframework/web/server/ServerWebExchange.html[Spring Framework `ServerWebExchange`]. This allows developers to match on anything from the HTTP request, such as headers or parameters.
* *Filter*: These are instances http://docs.spring.io/spring/docs/5.0.x/javadoc-api/org/springframework/web/server/WebFilter.html[Spring Framework `WebFilter`] constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request.
* *Filter*: These are instances http://docs.spring.io/spring/docs/5.0.x/javadoc-api/org/springframework/web/server/GatewayFilter.html[Spring Framework `GatewayFilter`] constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request.
[[gateway-how-it-works]]
== How It Works
@@ -192,7 +192,7 @@ spring:
This route would match if the request path was, for example: `/foo/1` or `/foo/bar`.
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 Factories>>
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,GatewayFilter Factories>>
=== Query Route Predicate Factory
The Query Route Predicate Factory takes two parameters: a required `param` and an optional `regexp`.
@@ -250,12 +250,12 @@ spring:
This route would match if the remote address of the request was, for example, `192.168.1.10`.
[[gateway-route-filters]]
== WebFilter Factories
== GatewayFilter Factories
Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in WebFilter Factories.
Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories.
=== AddRequestHeader WebFilter Factory
The AddRequestHeader WebFilter Factory takes a name and value parameter.
=== AddRequestHeader GatewayFilter Factory
The AddRequestHeader GatewayFilter Factory takes a name and value parameter.
.application.yml
[source,yaml]
@@ -273,8 +273,8 @@ spring:
This will add `X-Request-Foo:Bar` header to the downstream request's headers for all matching requests.
=== AddRequestParameter WebFilter Factory
The AddRequestParameter WebFilter Factory takes a name and value parameter.
=== AddRequestParameter GatewayFilter Factory
The AddRequestParameter GatewayFilter Factory takes a name and value parameter.
.application.yml
[source,yaml]
@@ -292,8 +292,8 @@ spring:
This will add `foo=bar` to the downstream request's query string for all matching requests.
=== AddResponseHeader WebFilter Factory
The AddResponseHeader WebFilter Factory takes a name and value parameter.
=== AddResponseHeader GatewayFilter Factory
The AddResponseHeader GatewayFilter Factory takes a name and value parameter.
.application.yml
[source,yaml]
@@ -311,8 +311,8 @@ spring:
This will add `X-Response-Foo:Bar` header to the downstream response's headers for all matching requests.
=== Hystrix WebFilter Factory
The Hystrix WebFilter Factory takes a single `name` parameters, which is the name of the `HystrixCommand`. (More options might be added in future releases).
=== Hystrix GatewayFilter Factory
The Hystrix GatewayFilter Factory takes a single `name` parameters, which is the name of the `HystrixCommand`. (More options might be added in future releases).
.application.yml
[source,yaml]
@@ -330,8 +330,8 @@ spring:
This wraps the remaining filters in a `HystrixCommand` with command name `myCommandName`.
=== PrefixPath WebFilter Factory
The PrefixPath WebFilter Factory takes a single `prefix` parameter.
=== PrefixPath GatewayFilter Factory
The PrefixPath GatewayFilter Factory takes a single `prefix` parameter.
.application.yml
[source,yaml]
@@ -349,9 +349,9 @@ spring:
This will prefix `/mypath` to the path of all matching requests. So a request to `/hello`, would be sent to `/mypath/hello`.
=== RequestRateLimiter WebFilter Factory
=== RequestRateLimiter GatewayFilter Factory
The RequestRateLimiter WebFilter Factory takes three parameters: `replenishRate`, `burstCapacity` & `keyResolverName`.
The RequestRateLimiter GatewayFilter Factory takes three parameters: `replenishRate`, `burstCapacity` & `keyResolverName`.
`replenishRate` is how many requests per second do you want a user to be allowed to do.
@@ -397,8 +397,8 @@ KeyResolver userKeyResolver() {
This defines a request rate limit of 10 per user. The `KeyResolver` is a simple one that gets the `user` request parameter (note: this is not recommended for production).
=== RedirectTo WebFilter Factory
The RedirectTo WebFilter Factory takes a `status` and a `url` parameter. The status should be a 300 series redirect http code, such as 301. The url should be a valid url. This will be the value of the `Location` header.
=== RedirectTo GatewayFilter Factory
The RedirectTo GatewayFilter Factory takes a `status` and a `url` parameter. The status should be a 300 series redirect http code, such as 301. The url should be a valid url. This will be the value of the `Location` header.
.application.yml
[source,yaml]
@@ -416,8 +416,8 @@ spring:
This will send a status 302 with a `Location:http://acme.org` header to perform a redirect.
=== RemoveNonProxyHeaders WebFilter Factory
The RemoveNonProxyHeaders WebFilter Factory removes headers from forwarded requests. The default list of headers that is removed comes from the https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3[IETF].
=== RemoveNonProxyHeaders GatewayFilter Factory
The RemoveNonProxyHeaders GatewayFilter Factory removes headers from forwarded requests. The default list of headers that is removed comes from the https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3[IETF].
.The default removed headers are:
* Connection
@@ -431,8 +431,8 @@ The RemoveNonProxyHeaders WebFilter Factory removes headers from forwarded reque
To change this, set the `spring.cloud.gateway.filter.remove-non-proxy-headers.headers` property to the list of header names to remove.
=== RemoveRequestHeader WebFilter Factory
The RemoveRequestHeader WebFilter Factory takes a `name` parameter. It is the name of the header to be removed.
=== RemoveRequestHeader GatewayFilter Factory
The RemoveRequestHeader GatewayFilter Factory takes a `name` parameter. It is the name of the header to be removed.
.application.yml
[source,yaml]
@@ -450,8 +450,8 @@ spring:
This will remove the `X-Request-Foo` header before it is sent downstream.
=== RemoveResponseHeader WebFilter Factory
The RemoveResponseHeader WebFilter Factory takes a `name` parameter. It is the name of the header to be removed.
=== RemoveResponseHeader GatewayFilter Factory
The RemoveResponseHeader GatewayFilter Factory takes a `name` parameter. It is the name of the header to be removed.
.application.yml
[source,yaml]
@@ -469,8 +469,8 @@ spring:
This will remove the `X-Response-Foo` header from the response before it is returned to the gateway client.
=== RewritePath WebFilter Factory
The RewritePath WebFilter Factory takes a path `regexp` parameter and a `replacement` parameter. This uses Java regular expressions for a flexible way to rewrite the request path.
=== RewritePath GatewayFilter Factory
The RewritePath GatewayFilter Factory takes a path `regexp` parameter and a `replacement` parameter. This uses Java regular expressions for a flexible way to rewrite the request path.
.application.yml
[source,yaml]
@@ -489,8 +489,8 @@ spring:
For a request path of `/foo/bar`, this will set the path to `/bar` before making the downstream request. Notice the `$\` which is replaced with `$` because of the YAML spec.
=== SecureHeaders WebFilter Factory
The SecureHeaders WebFilter Factory adds a number of headers to the response at the reccomendation from https://blog.appcanary.com/2017/http-security-headers.html[this blog post].
=== SecureHeaders GatewayFilter Factory
The SecureHeaders GatewayFilter Factory adds a number of headers to the response at the reccomendation from https://blog.appcanary.com/2017/http-security-headers.html[this blog post].
.The following headers are added (allong with default values):
* `X-Xss-Protection:1; mode=block`
@@ -515,8 +515,8 @@ To change the default values set the appropriate property in the `spring.cloud.g
* `permitted-cross-domain-policies`
=== SetPath WebFilter Factory
The SetPath WebFilter Factory takes a path `template` parameter. It offers a simple way to manipulate the request path by allowing templated segments of the path. This uses the uri templates from Spring Framework. Multiple matching segments are allowed.
=== SetPath GatewayFilter Factory
The SetPath GatewayFilter Factory takes a path `template` parameter. It offers a simple way to manipulate the request path by allowing templated segments of the path. This uses the uri templates from Spring Framework. Multiple matching segments are allowed.
.application.yml
[source,yaml]
@@ -536,8 +536,8 @@ spring:
For a request path of `/foo/bar`, this will set the path to `/bar` before making the downstream request.
=== SetResponseHeader WebFilter Factory
The SetResponseHeader WebFilter Factory takes `name` and `value` parameters.
=== SetResponseHeader GatewayFilter Factory
The SetResponseHeader GatewayFilter Factory takes `name` and `value` parameters.
.application.yml
[source,yaml]
@@ -553,10 +553,10 @@ spring:
- SetResponseHeader=X-Response-Foo, Bar
----
This WebFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a `X-Response-Foo:1234`, this would be replaced with `X-Response-Foo:Bar`, which is what the gateway client would receive.
This GatewayFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a `X-Response-Foo:1234`, this would be replaced with `X-Response-Foo:Bar`, which is what the gateway client would receive.
=== SetStatus WebFilter Factory
The SetStatus WebFilter Factory takes a single `status` parameter. It must be a valid Spring `HttpStatus`. It may be the integer value `404` or the string representation of the enumeration `NOT_FOUND`.
=== SetStatus GatewayFilter Factory
The SetStatus GatewayFilter Factory takes a single `status` parameter. It must be a valid Spring `HttpStatus`. It may be the integer value `404` or the string representation of the enumeration `NOT_FOUND`.
.application.yml
[source,yaml]
@@ -580,9 +580,9 @@ In either case, the HTTP status of the response will be set to 401.
== Global Filters
The `GlobalFilter` interface has the same signature as `WebFilter`. These are special filters that are conditionally applied to all routes. (This interface and usage are subject to change in future milestones).
The `GlobalFilter` interface has the same signature as `GatewayFilter`. These are special filters that are conditionally applied to all routes. (This interface and usage are subject to change in future milestones).
=== Combined Global Filter and WebFilter Ordering
=== Combined Global Filter and GatewayFilter Ordering
TODO: document ordering
@@ -654,9 +654,9 @@ To allow for simple configuration in Java, there is a fluent API defined in the
.Config.java
[source,java]
----
// static imports from WebFilterFactories and RoutePredicates
// static imports from GatewayFilters and RoutePredicates
@Bean
public RouteLocator customRouteLocator(ThrottleWebFilterFactory throttle) {
public RouteLocator customRouteLocator(ThrottleGatewayFilterFactory throttle) {
return Routes.locator()
.route("test")
.uri("http://httpbin.org:80")
@@ -686,9 +686,9 @@ TODO: overview of writing custom integrations
TODO: document writing Custom Route Predicate Factories
=== Writing Custom WebFilter Factories
=== Writing Custom GatewayFilter Factories
TODO: document writing Custom WebFilter Factories
TODO: document writing Custom GatewayFilter Factories
=== Writing Custom Global Filters

View File

@@ -25,7 +25,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.route.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteDefinition;
@@ -59,17 +59,17 @@ public class GatewayWebfluxEndpoint implements ApplicationEventPublisherAware {
private RouteDefinitionLocator routeDefinitionLocator;
private List<GlobalFilter> globalFilters;
private List<WebFilterFactory> webFilterFactories;
private List<GatewayFilterFactory> GatewayFilters;
private RouteDefinitionWriter routeDefinitionWriter;
private RouteLocator routeLocator;
private ApplicationEventPublisher publisher;
public GatewayWebfluxEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,
List<WebFilterFactory> webFilterFactories, RouteDefinitionWriter routeDefinitionWriter,
List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
this.routeDefinitionLocator = routeDefinitionLocator;
this.globalFilters = globalFilters;
this.webFilterFactories = webFilterFactories;
this.GatewayFilters = GatewayFilters;
this.routeDefinitionWriter = routeDefinitionWriter;
this.routeLocator = routeLocator;
}
@@ -95,7 +95,7 @@ public class GatewayWebfluxEndpoint implements ApplicationEventPublisherAware {
@GetMapping("/routefilters")
public Mono<HashMap<String, Object>> routefilers() {
return getNamesToOrders(this.webFilterFactories);
return getNamesToOrders(this.GatewayFilters);
}
private <T> Mono<HashMap<String, Object>> getNamesToOrders(List<T> list) {

View File

@@ -38,23 +38,23 @@ import org.springframework.cloud.gateway.filter.NettyRoutingFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
import org.springframework.cloud.gateway.filter.WebsocketRoutingFilter;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.HystrixWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.PrefixPathWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RedirectToWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveRequestHeaderWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveResponseHeaderWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.PrefixPathGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveRequestHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SecureHeadersProperties;
import org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetPathWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetResponseHeaderWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetStatusWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetPathGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SetStatusGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
@@ -160,10 +160,10 @@ public class GatewayAutoConfiguration {
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
List<WebFilterFactory> webFilterFactories,
List<GatewayFilterFactory> GatewayFilters,
List<RoutePredicateFactory> predicates,
RouteDefinitionLocator routeDefinitionLocator) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, webFilterFactories, properties);
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
}
@Bean
@@ -282,55 +282,55 @@ public class GatewayAutoConfiguration {
return new RemoteAddrRoutePredicateFactory();
}
// WebFilter Factory beans
// GatewayFilter Factory beans
@Bean
public AddRequestHeaderWebFilterFactory addRequestHeaderWebFilterFactory() {
return new AddRequestHeaderWebFilterFactory();
public AddRequestHeaderGatewayFilterFactory addRequestHeaderGatewayFilterFactory() {
return new AddRequestHeaderGatewayFilterFactory();
}
@Bean
public AddRequestParameterWebFilterFactory addRequestParameterWebFilterFactory() {
return new AddRequestParameterWebFilterFactory();
public AddRequestParameterGatewayFilterFactory addRequestParameterGatewayFilterFactory() {
return new AddRequestParameterGatewayFilterFactory();
}
@Bean
public AddResponseHeaderWebFilterFactory addResponseHeaderWebFilterFactory() {
return new AddResponseHeaderWebFilterFactory();
public AddResponseHeaderGatewayFilterFactory addResponseHeaderGatewayFilterFactory() {
return new AddResponseHeaderGatewayFilterFactory();
}
@Configuration
@ConditionalOnClass({HystrixObservableCommand.class, RxReactiveStreams.class})
protected static class HystrixConfiguration {
@Bean
public HystrixWebFilterFactory hystrixWebFilterFactory() {
return new HystrixWebFilterFactory();
public HystrixGatewayFilterFactory hystrixGatewayFilterFactory() {
return new HystrixGatewayFilterFactory();
}
}
@Bean
public PrefixPathWebFilterFactory prefixPathWebFilterFactory() {
return new PrefixPathWebFilterFactory();
public PrefixPathGatewayFilterFactory prefixPathGatewayFilterFactory() {
return new PrefixPathGatewayFilterFactory();
}
@Bean
public RedirectToWebFilterFactory redirectToWebFilterFactory() {
return new RedirectToWebFilterFactory();
public RedirectToGatewayFilterFactory redirectToGatewayFilterFactory() {
return new RedirectToGatewayFilterFactory();
}
@Bean
public RemoveNonProxyHeadersWebFilterFactory removeNonProxyHeadersWebFilterFactory() {
return new RemoveNonProxyHeadersWebFilterFactory();
public RemoveNonProxyHeadersGatewayFilterFactory removeNonProxyHeadersGatewayFilterFactory() {
return new RemoveNonProxyHeadersGatewayFilterFactory();
}
@Bean
public RemoveRequestHeaderWebFilterFactory removeRequestHeaderWebFilterFactory() {
return new RemoveRequestHeaderWebFilterFactory();
public RemoveRequestHeaderGatewayFilterFactory removeRequestHeaderGatewayFilterFactory() {
return new RemoveRequestHeaderGatewayFilterFactory();
}
@Bean
public RemoveResponseHeaderWebFilterFactory removeResponseHeaderWebFilterFactory() {
return new RemoveResponseHeaderWebFilterFactory();
public RemoveResponseHeaderGatewayFilterFactory removeResponseHeaderGatewayFilterFactory() {
return new RemoveResponseHeaderGatewayFilterFactory();
}
@Bean(name = PrincipalNameKeyResolver.BEAN_NAME)
@@ -341,33 +341,33 @@ public class GatewayAutoConfiguration {
@Bean
@ConditionalOnBean({RateLimiter.class, KeyResolver.class})
public RequestRateLimiterWebFilterFactory requestRateLimiterWebFilterFactory(RateLimiter rateLimiter) {
return new RequestRateLimiterWebFilterFactory(rateLimiter);
public RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory(RateLimiter rateLimiter) {
return new RequestRateLimiterGatewayFilterFactory(rateLimiter);
}
@Bean
public RewritePathWebFilterFactory rewritePathWebFilterFactory() {
return new RewritePathWebFilterFactory();
public RewritePathGatewayFilterFactory rewritePathGatewayFilterFactory() {
return new RewritePathGatewayFilterFactory();
}
@Bean
public SetPathWebFilterFactory setPathWebFilterFactory() {
return new SetPathWebFilterFactory();
public SetPathGatewayFilterFactory setPathGatewayFilterFactory() {
return new SetPathGatewayFilterFactory();
}
@Bean
public SecureHeadersWebFilterFactory secureHeadersWebFilterFactory(SecureHeadersProperties properties) {
return new SecureHeadersWebFilterFactory(properties);
public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
return new SecureHeadersGatewayFilterFactory(properties);
}
@Bean
public SetResponseHeaderWebFilterFactory setResponseHeaderWebFilterFactory() {
return new SetResponseHeaderWebFilterFactory();
public SetResponseHeaderGatewayFilterFactory setResponseHeaderGatewayFilterFactory() {
return new SetResponseHeaderGatewayFilterFactory();
}
@Bean
public SetStatusWebFilterFactory setStatusWebFilterFactory() {
return new SetStatusWebFilterFactory();
public SetStatusGatewayFilterFactory setStatusGatewayFilterFactory() {
return new SetStatusGatewayFilterFactory();
}
@@ -378,9 +378,9 @@ public class GatewayAutoConfiguration {
@Bean
public GatewayWebfluxEndpoint gatewayWebfluxEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,
List<WebFilterFactory> webFilterFactories, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
return new GatewayWebfluxEndpoint(routeDefinitionLocator, globalFilters, webFilterFactories, routeDefinitionWriter, routeLocator);
List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
return new GatewayWebfluxEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
}
}

View File

@@ -25,8 +25,8 @@ import javax.validation.constraints.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersGatewayFilterFactory;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersWebFilterFactory;
import org.springframework.validation.annotation.Validated;
import static org.springframework.cloud.gateway.support.NameUtils.normalizeFilterName;
@@ -53,7 +53,7 @@ public class GatewayProperties {
private ArrayList<FilterDefinition> loadDefaults() {
ArrayList<FilterDefinition> defaults = new ArrayList<>();
FilterDefinition definition = new FilterDefinition();
definition.setName(normalizeFilterName(RemoveNonProxyHeadersWebFilterFactory.class));
definition.setName(normalizeFilterName(RemoveNonProxyHeadersGatewayFilterFactory.class));
defaults.add(definition);
return defaults;
}

View File

@@ -21,14 +21,14 @@ import java.net.URI;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
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.filter.factory.RewritePathGatewayFilterFactory.REGEXP_KEY;
import static org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory.REPLACEMENT_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;
@@ -74,7 +74,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
// add a filter that removes /serviceId by default
FilterDefinition filter = new FilterDefinition();
filter.setName(normalizeFilterName(RewritePathWebFilterFactory.class));
filter.setName(normalizeFilterName(RewritePathGatewayFilterFactory.class));
String regex = "/" + serviceId + "/(?<remaining>.*)";
String replacement = "/${remaining}";
filter.addArg(REGEXP_KEY, regex);

View File

@@ -1,19 +1,19 @@
package org.springframework.cloud.gateway.filter;
import java.net.URI;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.Ordered;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import java.net.URI;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setAlreadyRouted;
import reactor.core.publisher.Mono;
public class ForwardRoutingFilter implements GlobalFilter, Ordered {
private static final Log log = LogFactory.getLog(ForwardRoutingFilter.class);
@@ -30,7 +30,7 @@ public class ForwardRoutingFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();

View File

@@ -0,0 +1,45 @@
package org.springframework.cloud.gateway.filter;
/*
* Copyright 2002-2015 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.
*/
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* Contract for interception-style, chained processing of Web requests that may
* be used to implement cross-cutting, application-agnostic requirements such
* as security, timeouts, and others. Specific to a Gateway
*
* Copied from WebFilter
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public interface GatewayFilter {
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link GatewayFilterChain}.
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

View File

@@ -0,0 +1,22 @@
package org.springframework.cloud.gateway.filter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import reactor.core.publisher.Mono;
/**
* Contract to allow a {@link WebFilter} to delegate to the next in the chain.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public interface GatewayFilterChain {
/**
* Delegate to the next {@code WebFilter} in the chain.
* @param exchange the current server exchange
* @return {@code Mono<Void>} to indicate when request handling is complete
*/
Mono<Void> filter(ServerWebExchange exchange);
}

View File

@@ -18,7 +18,7 @@
package org.springframework.cloud.gateway.filter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import reactor.core.publisher.Mono;
@@ -34,11 +34,11 @@ public interface GlobalFilter {
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link WebFilterChain}.
* {@code WebFilter} through the given {@link GatewayFilterChain}.
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain);
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

View File

@@ -26,7 +26,7 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
@@ -54,7 +54,7 @@ public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
if (url == null || !url.getScheme().equals("lb")) {
return chain.filter(exchange);

View File

@@ -29,7 +29,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
@@ -61,7 +60,7 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();

View File

@@ -24,7 +24,6 @@ import org.springframework.core.io.buffer.NettyDataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
@@ -47,7 +46,7 @@ public class NettyWriteResponseFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added
// until the WebHandler is run
return chain.filter(exchange).then(Mono.defer(() -> {

View File

@@ -19,25 +19,24 @@ package org.springframework.cloud.gateway.filter;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
*/
public class OrderedWebFilter implements WebFilter, Ordered {
public class OrderedGatewayFilter implements GatewayFilter, Ordered {
private final WebFilter delegate;
private final GatewayFilter delegate;
private final int order;
public OrderedWebFilter(WebFilter delegate, int order) {
public OrderedGatewayFilter(GatewayFilter delegate, int order) {
this.delegate = delegate;
this.order = order;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
@@ -48,7 +47,7 @@ public class OrderedWebFilter implements WebFilter, Ordered {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("OrderedWebFilter{");
final StringBuilder sb = new StringBuilder("OrderedGatewayFilter{");
sb.append("delegate=").append(delegate);
sb.append(", order=").append(order);
sb.append('}');

View File

@@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
@@ -46,7 +45,7 @@ public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
if (route == null) {
return chain.filter(exchange);

View File

@@ -29,7 +29,6 @@ import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec;
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
@@ -55,7 +54,7 @@ public class WebClientHttpRoutingFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();

View File

@@ -24,7 +24,6 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
@@ -45,7 +44,7 @@ public class WebClientWriteResponseFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added
// until the WebHandler is run
return chain.filter(exchange).then(Mono.defer(() -> {

View File

@@ -14,7 +14,6 @@ import org.springframework.web.reactive.socket.client.WebSocketClient;
import org.springframework.web.reactive.socket.server.WebSocketService;
import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;
@@ -47,7 +46,7 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();

View File

@@ -18,7 +18,7 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import java.util.Arrays;
@@ -27,7 +27,7 @@ import java.util.List;
/**
* @author Spencer Gibb
*/
public class AddRequestHeaderWebFilterFactory implements WebFilterFactory {
public class AddRequestHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -35,7 +35,7 @@ public class AddRequestHeaderWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
String name = args.getString(NAME_KEY);
String value = args.getString(VALUE_KEY);

View File

@@ -25,12 +25,12 @@ import java.util.List;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
import org.springframework.util.StringUtils;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
/**
* @author Spencer Gibb
*/
public class AddRequestParameterWebFilterFactory implements WebFilterFactory {
public class AddRequestParameterGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -38,7 +38,7 @@ public class AddRequestParameterWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
String parameter = args.getString(NAME_KEY);
String value = args.getString(VALUE_KEY);

View File

@@ -18,7 +18,7 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import java.util.Arrays;
import java.util.List;
@@ -26,7 +26,7 @@ import java.util.List;
/**
* @author Spencer Gibb
*/
public class AddResponseHeaderWebFilterFactory implements WebFilterFactory {
public class AddResponseHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -34,7 +34,7 @@ public class AddResponseHeaderWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
final String value = args.getString(VALUE_KEY);

View File

@@ -17,21 +17,21 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.support.ArgumentHints;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
/**
* @author Spencer Gibb
*/
@FunctionalInterface
public interface WebFilterFactory extends ArgumentHints {
public interface GatewayFilterFactory extends ArgumentHints {
String NAME_KEY = "name";
String VALUE_KEY = "value";
WebFilter apply(Tuple args);
GatewayFilter apply(Tuple args);
default String name() {
return NameUtils.normalizeFilterName(getClass());

View File

@@ -0,0 +1,126 @@
/*
* 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.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import java.net.URI;
import java.util.Arrays;
import static org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactory.STATUS_KEY;
import static org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactory.URL_KEY;
import static org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory.REGEXP_KEY;
import static org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory.REPLACEMENT_KEY;
import static org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory.NAME_KEY;
import static org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory.VALUE_KEY;
import static org.springframework.tuple.TupleBuilder.tuple;
/**
* @author Spencer Gibb
*/
public class GatewayFilters {
public static final Tuple EMPTY_TUPLE = tuple().build();
public static GatewayFilter addRequestHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new AddRequestHeaderGatewayFilterFactory().apply(args);
}
public static GatewayFilter addRequestParameter(String param, String value) {
Tuple args = tuple().of(NAME_KEY, param, VALUE_KEY, value);
return new AddRequestParameterGatewayFilterFactory().apply(args);
}
public static GatewayFilter addResponseHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new AddResponseHeaderGatewayFilterFactory().apply(args);
}
public static GatewayFilter hystrix(String commandName) {
Tuple args = tuple().of(NAME_KEY, commandName);
return new HystrixGatewayFilterFactory().apply(args);
}
public static GatewayFilter prefixPath(String prefix) {
Tuple args = tuple().of(PrefixPathGatewayFilterFactory.PREFIX_KEY, prefix);
return new PrefixPathGatewayFilterFactory().apply(args);
}
public static GatewayFilter redirect(int status, URI url) {
return redirect(String.valueOf(status), url.toString());
}
public static GatewayFilter redirect(int status, String url) {
return redirect(String.valueOf(status), url);
}
public static GatewayFilter redirect(String status, URI url) {
return redirect(status, url.toString());
}
public static GatewayFilter redirect(String status, String url) {
Tuple args = tuple().of(STATUS_KEY, status, URL_KEY, url);
return new RedirectToGatewayFilterFactory().apply(args);
}
public static GatewayFilter removeNonProxyHeaders(String... headersToRemove) {
RemoveNonProxyHeadersGatewayFilterFactory filterFactory = new RemoveNonProxyHeadersGatewayFilterFactory();
filterFactory.setHeaders(Arrays.asList(headersToRemove));
return filterFactory.apply(EMPTY_TUPLE);
}
public static GatewayFilter removeRequestHeader(String headerName) {
Tuple args = tuple().of(NAME_KEY, headerName);
return new RemoveRequestHeaderGatewayFilterFactory().apply(args);
}
public static GatewayFilter removeResponseHeader(String headerName) {
Tuple args = tuple().of(NAME_KEY, headerName);
return new RemoveResponseHeaderGatewayFilterFactory().apply(args);
}
public static GatewayFilter rewritePath(String regex, String replacement) {
Tuple args = tuple().of(REGEXP_KEY, regex, REPLACEMENT_KEY, replacement);
return new RewritePathGatewayFilterFactory().apply(args);
}
public static GatewayFilter secureHeaders(SecureHeadersProperties properties) {
return new SecureHeadersGatewayFilterFactory(properties).apply(EMPTY_TUPLE);
}
public static GatewayFilter setPath(String template) {
Tuple args = tuple().of(SetPathGatewayFilterFactory.TEMPLATE_KEY, template);
return new SetPathGatewayFilterFactory().apply(args);
}
public static GatewayFilter setResponseHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new SetResponseHeaderGatewayFilterFactory().apply(args);
}
public static GatewayFilter setStatus(int status) {
return setStatus(String.valueOf(status));
}
public static GatewayFilter setStatus(String status) {
Tuple args = tuple().of(SetStatusGatewayFilterFactory.STATUS_KEY, status);
return new SetStatusGatewayFilterFactory().apply(args);
}
}

View File

@@ -24,8 +24,8 @@ import java.util.function.Function;
import org.springframework.http.HttpStatus;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
@@ -43,7 +43,7 @@ import rx.Subscription;
/**
* @author Spencer Gibb
*/
public class HystrixWebFilterFactory implements WebFilterFactory {
public class HystrixGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -51,7 +51,7 @@ public class HystrixWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
//TODO: if no name is supplied, generate one from command id (useful for default filter)
final String commandName = args.getString(NAME_KEY);
final HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName());
@@ -83,9 +83,9 @@ public class HystrixWebFilterFactory implements WebFilterFactory {
//TODO: replace with HystrixMonoCommand that we write
private class RouteHystrixCommand extends HystrixObservableCommand<Void> {
private final ServerWebExchange exchange;
private final WebFilterChain chain;
private final GatewayFilterChain chain;
RouteHystrixCommand(Setter setter, ServerWebExchange exchange, WebFilterChain chain) {
RouteHystrixCommand(Setter setter, ServerWebExchange exchange, GatewayFilterChain chain) {
super(setter);
this.exchange = exchange;
this.chain = chain;

View File

@@ -24,7 +24,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
@@ -32,9 +32,9 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.a
/**
* @author Spencer Gibb
*/
public class PrefixPathWebFilterFactory implements WebFilterFactory {
public class PrefixPathGatewayFilterFactory implements GatewayFilterFactory {
private static final Log log = LogFactory.getLog(PrefixPathWebFilterFactory.class);
private static final Log log = LogFactory.getLog(PrefixPathGatewayFilterFactory.class);
public static final String PREFIX_KEY = "prefix";
@@ -45,7 +45,7 @@ public class PrefixPathWebFilterFactory implements WebFilterFactory {
@Override
@SuppressWarnings("unchecked")
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
final String prefix = args.getString(PREFIX_KEY);
return (exchange, chain) -> {

View File

@@ -28,7 +28,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.tuple.Tuple;
import org.springframework.util.Assert;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.parse;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setResponseStatus;
@@ -38,7 +38,7 @@ import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
*/
public class RedirectToWebFilterFactory implements WebFilterFactory {
public class RedirectToGatewayFilterFactory implements GatewayFilterFactory {
public static final String STATUS_KEY = "status";
public static final String URL_KEY = "url";
@@ -49,7 +49,7 @@ public class RedirectToWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
String statusString = args.getRawString(STATUS_KEY);
String urlString = args.getString(URL_KEY);

View File

@@ -20,7 +20,7 @@ package org.springframework.cloud.gateway.filter.factory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import java.util.Arrays;
import java.util.List;
@@ -45,7 +45,7 @@ import java.util.List;
* @author Spencer Gibb
*/
@ConfigurationProperties("spring.cloud.gateway.filter.remove-non-proxy-headers")
public class RemoveNonProxyHeadersWebFilterFactory implements WebFilterFactory {
public class RemoveNonProxyHeadersGatewayFilterFactory implements GatewayFilterFactory {
public static final String[] DEFAULT_HEADERS_TO_REMOVE = new String[] {"Connection", "Keep-Alive",
"Proxy-Authenticate", "Proxy-Authorization", "TE", "Trailer", "Transfer-Encoding", "Upgrade"};
@@ -61,7 +61,7 @@ public class RemoveNonProxyHeadersWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
//TODO: support filter args
return (exchange, chain) -> {

View File

@@ -18,7 +18,7 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import java.util.Arrays;
@@ -27,7 +27,7 @@ import java.util.List;
/**
* @author Spencer Gibb
*/
public class RemoveRequestHeaderWebFilterFactory implements WebFilterFactory {
public class RemoveRequestHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -35,7 +35,7 @@ public class RemoveRequestHeaderWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
return (exchange, chain) -> {

View File

@@ -21,14 +21,14 @@ import java.util.Arrays;
import java.util.List;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
*/
public class RemoveResponseHeaderWebFilterFactory implements WebFilterFactory {
public class RemoveResponseHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -36,7 +36,7 @@ public class RemoveResponseHeaderWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {

View File

@@ -21,12 +21,11 @@ import org.springframework.beans.BeansException;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter.Response;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.http.HttpStatus;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import java.util.Arrays;
import java.util.List;
@@ -35,7 +34,7 @@ import java.util.List;
* User Request Rate Limiter filter.
* See https://stripe.com/blog/rate-limiters and
*/
public class RequestRateLimiterWebFilterFactory implements WebFilterFactory, ApplicationContextAware {
public class RequestRateLimiterGatewayFilterFactory implements GatewayFilterFactory, ApplicationContextAware {
public static final String REPLENISH_RATE_KEY = "replenishRate";
public static final String BURST_CAPACITY_KEY = "burstCapacity";
@@ -44,7 +43,7 @@ public class RequestRateLimiterWebFilterFactory implements WebFilterFactory, App
private final RateLimiter rateLimiter;
private ApplicationContext context;
public RequestRateLimiterWebFilterFactory(RateLimiter rateLimiter) {
public RequestRateLimiterGatewayFilterFactory(RateLimiter rateLimiter) {
this.rateLimiter = rateLimiter;
}
@@ -60,7 +59,7 @@ public class RequestRateLimiterWebFilterFactory implements WebFilterFactory, App
@SuppressWarnings("unchecked")
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
// How many requests per second do you want a user to be allowed to do?
int replenishRate = args.getInt(REPLENISH_RATE_KEY);

View File

@@ -22,7 +22,7 @@ import java.util.List;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
@@ -30,7 +30,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.a
/**
* @author Spencer Gibb
*/
public class RewritePathWebFilterFactory implements WebFilterFactory {
public class RewritePathGatewayFilterFactory implements GatewayFilterFactory {
public static final String REGEXP_KEY = "regexp";
public static final String REPLACEMENT_KEY = "replacement";
@@ -41,7 +41,7 @@ public class RewritePathWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
final String regex = args.getString(REGEXP_KEY);
String replacement = args.getString(REPLACEMENT_KEY).replace("$\\", "$");

View File

@@ -19,13 +19,13 @@ package org.springframework.cloud.gateway.filter.factory;
import org.springframework.http.HttpHeaders;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
/**
* https://blog.appcanary.com/2017/http-security-headers.html
* @author Spencer Gibb
*/
public class SecureHeadersWebFilterFactory implements WebFilterFactory {
public class SecureHeadersGatewayFilterFactory implements GatewayFilterFactory {
public static final String X_XSS_PROTECTION_HEADER = "X-Xss-Protection";
public static final String STRICT_TRANSPORT_SECURITY_HEADER = "Strict-Transport-Security";
@@ -38,12 +38,12 @@ public class SecureHeadersWebFilterFactory implements WebFilterFactory {
private final SecureHeadersProperties properties;
public SecureHeadersWebFilterFactory(SecureHeadersProperties properties) {
public SecureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
this.properties = properties;
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
//TODO: allow args to override properties
return (exchange, chain) -> {

View File

@@ -25,7 +25,7 @@ import java.util.Map;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.web.util.UriTemplate;
import org.springframework.web.util.pattern.PathPattern.PathMatchInfo;
@@ -36,7 +36,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.a
/**
* @author Spencer Gibb
*/
public class SetPathWebFilterFactory implements WebFilterFactory {
public class SetPathGatewayFilterFactory implements GatewayFilterFactory {
public static final String TEMPLATE_KEY = "template";
@@ -48,7 +48,7 @@ public class SetPathWebFilterFactory implements WebFilterFactory {
@Override
@SuppressWarnings("unchecked")
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
String template = args.getString(TEMPLATE_KEY);
UriTemplate uriTemplate = new UriTemplate(template);

View File

@@ -18,7 +18,7 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import reactor.core.publisher.Mono;
import java.util.Arrays;
@@ -27,7 +27,7 @@ import java.util.List;
/**
* @author Spencer Gibb
*/
public class SetResponseHeaderWebFilterFactory implements WebFilterFactory {
public class SetResponseHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
@@ -35,7 +35,7 @@ public class SetResponseHeaderWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
final String value = args.getString(VALUE_KEY);

View File

@@ -20,7 +20,7 @@ package org.springframework.cloud.gateway.filter.factory;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpStatus;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setResponseStatus;
@@ -32,7 +32,7 @@ import java.util.List;
/**
* @author Spencer Gibb
*/
public class SetStatusWebFilterFactory implements WebFilterFactory {
public class SetStatusGatewayFilterFactory implements GatewayFilterFactory {
public static final String STATUS_KEY = "status";
@@ -42,7 +42,7 @@ public class SetStatusWebFilterFactory implements WebFilterFactory {
}
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
String status = args.getRawString(STATUS_KEY);
final HttpStatus httpStatus = ServerWebExchangeUtils.parse(status);

View File

@@ -1,126 +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.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import java.net.URI;
import java.util.Arrays;
import static org.springframework.cloud.gateway.filter.factory.RedirectToWebFilterFactory.STATUS_KEY;
import static org.springframework.cloud.gateway.filter.factory.RedirectToWebFilterFactory.URL_KEY;
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.filter.factory.WebFilterFactory.NAME_KEY;
import static org.springframework.cloud.gateway.filter.factory.WebFilterFactory.VALUE_KEY;
import static org.springframework.tuple.TupleBuilder.tuple;
/**
* @author Spencer Gibb
*/
public class WebFilterFactories {
public static final Tuple EMPTY_TUPLE = tuple().build();
public static WebFilter addRequestHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new AddRequestHeaderWebFilterFactory().apply(args);
}
public static WebFilter addRequestParameter(String param, String value) {
Tuple args = tuple().of(NAME_KEY, param, VALUE_KEY, value);
return new AddRequestParameterWebFilterFactory().apply(args);
}
public static WebFilter addResponseHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new AddResponseHeaderWebFilterFactory().apply(args);
}
public static WebFilter hystrix(String commandName) {
Tuple args = tuple().of(NAME_KEY, commandName);
return new HystrixWebFilterFactory().apply(args);
}
public static WebFilter prefixPath(String prefix) {
Tuple args = tuple().of(PrefixPathWebFilterFactory.PREFIX_KEY, prefix);
return new PrefixPathWebFilterFactory().apply(args);
}
public static WebFilter redirect(int status, URI url) {
return redirect(String.valueOf(status), url.toString());
}
public static WebFilter redirect(int status, String url) {
return redirect(String.valueOf(status), url);
}
public static WebFilter redirect(String status, URI url) {
return redirect(status, url.toString());
}
public static WebFilter redirect(String status, String url) {
Tuple args = tuple().of(STATUS_KEY, status, URL_KEY, url);
return new RedirectToWebFilterFactory().apply(args);
}
public static WebFilter removeNonProxyHeaders(String... headersToRemove) {
RemoveNonProxyHeadersWebFilterFactory filterFactory = new RemoveNonProxyHeadersWebFilterFactory();
filterFactory.setHeaders(Arrays.asList(headersToRemove));
return filterFactory.apply(EMPTY_TUPLE);
}
public static WebFilter removeRequestHeader(String headerName) {
Tuple args = tuple().of(NAME_KEY, headerName);
return new RemoveRequestHeaderWebFilterFactory().apply(args);
}
public static WebFilter removeResponseHeader(String headerName) {
Tuple args = tuple().of(NAME_KEY, headerName);
return new RemoveResponseHeaderWebFilterFactory().apply(args);
}
public static WebFilter rewritePath(String regex, String replacement) {
Tuple args = tuple().of(REGEXP_KEY, regex, REPLACEMENT_KEY, replacement);
return new RewritePathWebFilterFactory().apply(args);
}
public static WebFilter secureHeaders(SecureHeadersProperties properties) {
return new SecureHeadersWebFilterFactory(properties).apply(EMPTY_TUPLE);
}
public static WebFilter setPath(String template) {
Tuple args = tuple().of(SetPathWebFilterFactory.TEMPLATE_KEY, template);
return new SetPathWebFilterFactory().apply(args);
}
public static WebFilter setResponseHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new SetResponseHeaderWebFilterFactory().apply(args);
}
public static WebFilter setStatus(int status) {
return setStatus(String.valueOf(status));
}
public static WebFilter setStatus(String status) {
Tuple args = tuple().of(SetStatusWebFilterFactory.STATUS_KEY, status);
return new SetStatusWebFilterFactory().apply(args);
}
}

View File

@@ -19,22 +19,20 @@ package org.springframework.cloud.gateway.handler;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.OrderedWebFilter;
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.server.WebHandler;
import org.springframework.web.server.handler.WebHandlerDecorator;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
@@ -42,35 +40,30 @@ import reactor.core.publisher.Mono;
/**
* WebHandler that delegates to a chain of {@link GlobalFilter} instances and
* {@link WebFilterFactory} instances then to the target {@link WebHandler}.
* {@link GatewayFilterFactory} instances then to the target {@link WebHandler}.
*
* @author Rossen Stoyanchev
* @author Spencer Gibb
* @since 0.1
*/
public class FilteringWebHandler extends WebHandlerDecorator {
protected final Log logger = LogFactory.getLog(getClass());
public class FilteringWebHandler implements WebHandler {
protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);
private final List<WebFilter> globalFilters;
private final List<GatewayFilter> globalFilters;
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this(new EmptyWebHandler(), globalFilters);
}
public FilteringWebHandler(WebHandler targetHandler, List<GlobalFilter> globalFilters) {
super(targetHandler);
this.globalFilters = loadFilters(globalFilters);
}
private static List<WebFilter> loadFilters(List<GlobalFilter> filters) {
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return filters.stream()
.map(filter -> {
WebFilterAdapter webFilter = new WebFilterAdapter(filter);
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
return new OrderedWebFilter(webFilter, order);
return new OrderedGatewayFilter(gatewayFilter, order);
}
return webFilter;
return gatewayFilter;
}).collect(Collectors.toList());
}
@@ -82,69 +75,59 @@ public class FilteringWebHandler extends WebHandlerDecorator {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
List<WebFilter> webFilters = route.getWebFilters();
List<GatewayFilter> gatewayFilters = route.getFilters();
List<WebFilter> combined = new ArrayList<>(this.globalFilters);
combined.addAll(webFilters);
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
combined.addAll(gatewayFilters);
//TODO: needed or cached?
AnnotationAwareOrderComparator.sort(combined);
logger.debug("Sorted webFilterFactories: "+ combined);
logger.debug("Sorted gatewayFilterFactories: "+ combined);
return new DefaultWebFilterChain(combined, getDelegate()).filter(exchange);
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
private static class DefaultWebFilterChain implements WebFilterChain {
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private int index;
private final List<WebFilter> filters;
private final WebHandler delegate;
private final List<GatewayFilter> filters;
public DefaultWebFilterChain(List<WebFilter> filters, WebHandler delegate) {
public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
this.delegate = delegate;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
if (this.index < filters.size()) {
WebFilter filter = filters.get(this.index++);
GatewayFilter filter = filters.get(this.index++);
return filter.filter(exchange, this);
}
else {
return this.delegate.handle(exchange);
return Mono.empty(); // complete
}
}
}
private static class WebFilterAdapter implements WebFilter {
private static class GatewayFilterAdapter implements GatewayFilter {
private final GlobalFilter delegate;
public WebFilterAdapter(GlobalFilter delegate) {
public GatewayFilterAdapter(GlobalFilter delegate) {
this.delegate = delegate;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WebFilterAdapter{");
final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
sb.append("delegate=").append(delegate);
sb.append('}');
return sb.toString();
}
}
private static class EmptyWebHandler implements WebHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
return Mono.empty();
}
}
}

View File

@@ -28,7 +28,7 @@ import java.util.function.Predicate;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
/**
* @author Spencer Gibb
@@ -43,7 +43,7 @@ public class Route implements Ordered {
private final Predicate<ServerWebExchange> predicate;
private final List<WebFilter> webFilters;
private final List<GatewayFilter> gatewayFilters;
public static Builder builder() {
return new Builder();
@@ -56,12 +56,12 @@ public class Route implements Ordered {
.order(routeDefinition.getOrder());
}
public Route(String id, URI uri, int order, Predicate<ServerWebExchange> predicate, List<WebFilter> webFilters) {
public Route(String id, URI uri, int order, Predicate<ServerWebExchange> predicate, List<GatewayFilter> gatewayFilters) {
this.id = id;
this.uri = uri;
this.order = order;
this.predicate = predicate;
this.webFilters = webFilters;
this.gatewayFilters = gatewayFilters;
}
public static class Builder {
@@ -73,7 +73,7 @@ public class Route implements Ordered {
private Predicate<ServerWebExchange> predicate;
private List<WebFilter> webFilters = new ArrayList<>();
private List<GatewayFilter> gatewayFilters = new ArrayList<>();
private Builder() {}
@@ -102,18 +102,18 @@ public class Route implements Ordered {
return this;
}
public Builder webFilters(List<WebFilter> webFilters) {
this.webFilters = webFilters;
public Builder gatewayFilters(List<GatewayFilter> gatewayFilters) {
this.gatewayFilters = gatewayFilters;
return this;
}
public Builder add(WebFilter webFilter) {
this.webFilters.add(webFilter);
public Builder add(GatewayFilter webFilter) {
this.gatewayFilters.add(webFilter);
return this;
}
public Builder addAll(Collection<WebFilter> webFilters) {
this.webFilters.addAll(webFilters);
public Builder addAll(Collection<GatewayFilter> gatewayFilters) {
this.gatewayFilters.addAll(gatewayFilters);
return this;
}
@@ -122,7 +122,7 @@ public class Route implements Ordered {
Assert.notNull(this.uri, "uri can not be null");
//TODO: Assert.notNull(this.predicate, "predicate can not be null");
return new Route(this.id, this.uri, this.order, this.predicate, this.webFilters);
return new Route(this.id, this.uri, this.order, this.predicate, this.gatewayFilters);
}
}
@@ -142,8 +142,8 @@ public class Route implements Ordered {
return this.predicate;
}
public List<WebFilter> getWebFilters() {
return Collections.unmodifiableList(this.webFilters);
public List<GatewayFilter> getFilters() {
return Collections.unmodifiableList(this.gatewayFilters);
}
@Override
@@ -155,12 +155,12 @@ public class Route implements Ordered {
Objects.equals(uri, route.uri) &&
Objects.equals(order, route.order) &&
Objects.equals(predicate, route.predicate) &&
Objects.equals(webFilters, route.webFilters);
Objects.equals(gatewayFilters, route.gatewayFilters);
}
@Override
public int hashCode() {
return Objects.hash(id, uri, predicate, webFilters);
return Objects.hash(id, uri, predicate, gatewayFilters);
}
@Override
@@ -170,7 +170,7 @@ public class Route implements Ordered {
sb.append(", uri=").append(uri);
sb.append(", order=").append(order);
sb.append(", predicate=").append(predicate);
sb.append(", webFilters=").append(webFilters);
sb.append(", gatewayFilters=").append(gatewayFilters);
sb.append('}');
return sb.toString();
}

View File

@@ -29,8 +29,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.config.GatewayProperties;
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.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
import org.springframework.cloud.gateway.support.ArgumentHints;
@@ -39,7 +40,6 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.tuple.Tuple;
import org.springframework.tuple.TupleBuilder;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import reactor.core.publisher.Flux;
@@ -52,16 +52,16 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
private final RouteDefinitionLocator routeDefinitionLocator;
private final Map<String, RoutePredicateFactory> predicates = new LinkedHashMap<>();
private final Map<String, WebFilterFactory> webFilterFactories = new HashMap<>();
private final Map<String, GatewayFilterFactory> gatewayFilterFactories = new HashMap<>();
private final GatewayProperties gatewayProperties;
public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,
List<RoutePredicateFactory> predicates,
List<WebFilterFactory> webFilterFactories,
List<GatewayFilterFactory> gatewayFilterFactories,
GatewayProperties gatewayProperties) {
this.routeDefinitionLocator = routeDefinitionLocator;
initFactories(predicates);
webFilterFactories.forEach(factory -> this.webFilterFactories.put(factory.name(), factory));
gatewayFilterFactories.forEach(factory -> this.gatewayFilterFactories.put(factory.name(), factory));
this.gatewayProperties = gatewayProperties;
}
@@ -101,20 +101,20 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
private Route convertToRoute(RouteDefinition routeDefinition) {
Predicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
List<WebFilter> webFilters = getFilters(routeDefinition);
List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);
return Route.builder(routeDefinition)
.predicate(predicate)
.webFilters(webFilters)
.gatewayFilters(gatewayFilters)
.build();
}
private List<WebFilter> loadWebFilters(String id, List<FilterDefinition> filterDefinitions) {
List<WebFilter> filters = filterDefinitions.stream()
private List<GatewayFilter> loadGatewayFilters(String id, List<FilterDefinition> filterDefinitions) {
List<GatewayFilter> filters = filterDefinitions.stream()
.map(definition -> {
WebFilterFactory filter = this.webFilterFactories.get(definition.getName());
GatewayFilterFactory filter = this.gatewayFilterFactories.get(definition.getName());
if (filter == null) {
throw new IllegalArgumentException("Unable to find WebFilterFactory with name " + definition.getName());
throw new IllegalArgumentException("Unable to find GatewayFilterFactory with name " + definition.getName());
}
Map<String, String> args = definition.getArgs();
if (logger.isDebugEnabled()) {
@@ -127,9 +127,9 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
})
.collect(Collectors.toList());
ArrayList<WebFilter> ordered = new ArrayList<>(filters.size());
ArrayList<GatewayFilter> ordered = new ArrayList<>(filters.size());
for (int i = 0; i < filters.size(); i++) {
ordered.add(new OrderedWebFilter(filters.get(i), i+1));
ordered.add(new OrderedGatewayFilter(filters.get(i), i+1));
}
return ordered;
@@ -174,17 +174,17 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
return tuple;
}
private List<WebFilter> getFilters(RouteDefinition routeDefinition) {
List<WebFilter> filters = new ArrayList<>();
private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
List<GatewayFilter> filters = new ArrayList<>();
//TODO: support option to apply defaults after route specific filters?
if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
filters.addAll(loadWebFilters("defaultFilters",
filters.addAll(loadGatewayFilters("defaultFilters",
this.gatewayProperties.getDefaultFilters()));
}
if (!routeDefinition.getFilters().isEmpty()) {
filters.addAll(loadWebFilters(routeDefinition.getId(), routeDefinition.getFilters()));
filters.addAll(loadGatewayFilters(routeDefinition.getId(), routeDefinition.getFilters()));
}
AnnotationAwareOrderComparator.sort(filters);

View File

@@ -23,10 +23,10 @@ import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.cloud.gateway.filter.OrderedWebFilter;
import org.springframework.cloud.gateway.filter.factory.WebFilterFactories;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilters;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import reactor.core.publisher.Flux;
@@ -109,51 +109,51 @@ public class Routes {
Predicate<ServerWebExchange> predicate = RoutePredicates.host(pattern);
}*/
public WebFilterSpec predicate(Predicate<ServerWebExchange> predicate) {
public GatewayFilterSpec predicate(Predicate<ServerWebExchange> predicate) {
this.routeBuilder.predicate(predicate);
return webFilterBuilder();
return gatewayFilterBuilder();
}
private WebFilterSpec webFilterBuilder() {
return new WebFilterSpec(this.routeBuilder, this.locatorBuilder);
private GatewayFilterSpec gatewayFilterBuilder() {
return new GatewayFilterSpec(this.routeBuilder, this.locatorBuilder);
}
}
public static class WebFilterSpec {
public static class GatewayFilterSpec {
private Route.Builder builder;
private LocatorBuilder locatorBuilder;
public WebFilterSpec(Route.Builder routeBuilder, LocatorBuilder locatorBuilder) {
public GatewayFilterSpec(Route.Builder routeBuilder, LocatorBuilder locatorBuilder) {
this.builder = routeBuilder;
this.locatorBuilder = locatorBuilder;
}
public WebFilterSpec webFilters(List<WebFilter> webFilters) {
this.addAll(webFilters);
public GatewayFilterSpec gatewayFilters(List<GatewayFilter> gatewayFilters) {
this.addAll(gatewayFilters);
return this;
}
public WebFilterSpec add(WebFilter webFilter) {
return this.filter(webFilter);
public GatewayFilterSpec add(GatewayFilter gatewayFilter) {
return this.filter(gatewayFilter);
}
public WebFilterSpec filter(WebFilter webFilter) {
return this.filter(webFilter, 0);
public GatewayFilterSpec filter(GatewayFilter gatewayFilter) {
return this.filter(gatewayFilter, 0);
}
public WebFilterSpec filter(WebFilter webFilter, int order) {
this.builder.add(new OrderedWebFilter(webFilter, order));
public GatewayFilterSpec filter(GatewayFilter gatewayFilter, int order) {
this.builder.add(new OrderedGatewayFilter(gatewayFilter, order));
return this;
}
public WebFilterSpec addAll(Collection<WebFilter> webFilters) {
this.builder.addAll(webFilters);
public GatewayFilterSpec addAll(Collection<GatewayFilter> gatewayFilters) {
this.builder.addAll(gatewayFilters);
return this;
}
public WebFilterSpec addResponseHeader(String headerName, String headerValue) {
return add(WebFilterFactories.addResponseHeader(headerName, headerValue));
public GatewayFilterSpec addResponseHeader(String headerName, String headerValue) {
return add(GatewayFilters.addResponseHeader(headerName, headerValue));
}
// TODO: build()?

View File

@@ -17,7 +17,7 @@
package org.springframework.cloud.gateway.support;
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
/**
@@ -34,7 +34,7 @@ public class NameUtils {
return clazz.getSimpleName().replace(RoutePredicateFactory.class.getSimpleName(), "");
}
public static String normalizeFilterName(Class<? extends WebFilterFactory> clazz) {
return clazz.getSimpleName().replace(WebFilterFactory.class.getSimpleName(), "");
public static String normalizeFilterName(Class<? extends GatewayFilterFactory> clazz) {
return clazz.getSimpleName().replace(GatewayFilterFactory.class.getSimpleName(), "");
}
}

View File

@@ -47,7 +47,7 @@ import static org.springframework.web.reactive.function.BodyExtractors.toMono;
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
@ActiveProfiles(profiles = "request-header-web-filter")
public class AddRequestHeaderWebFilterFactoryTests extends BaseWebClientTests {
public class AddRequestHeaderGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void addRequestHeaderFilterWorks() {

View File

@@ -41,7 +41,7 @@ import static org.springframework.web.reactive.function.BodyExtractors.toMono;
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
@ActiveProfiles(profiles = "request-parameter-web-filter")
public class AddRequestParameterWebFilterFactoryTests extends BaseWebClientTests {
public class AddRequestParameterGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void addRequestParameterFilterWorksBlankQuery() {

View File

@@ -40,7 +40,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class HystrixWebFilterFactoryTests extends BaseWebClientTests {
public class HystrixGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void hystrixFilterWorks() {

View File

@@ -40,7 +40,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class RedirectToWebFilterFactoryTests extends BaseWebClientTests {
public class RedirectToGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void redirectToFilterWorks() {

View File

@@ -32,7 +32,6 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersWebFilterFactory.DEFAULT_HEADERS_TO_REMOVE;
import static org.springframework.cloud.gateway.test.TestUtils.getMap;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
@@ -44,7 +43,7 @@ import reactor.test.StepVerifier;
//TODO: why does this break other tests if not in a profile?
@ActiveProfiles("removenonproxyheaders")
@DirtiesContext
public class RemoveNonProxyHeadersWebFilterFactoryTests extends BaseWebClientTests {
public class RemoveNonProxyHeadersGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void removeNonProxyHeadersFilterWorks() {

View File

@@ -40,7 +40,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class RemoveRequestHeaderWebFilterFactoryTests extends BaseWebClientTests {
public class RemoveRequestHeaderGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void removeRequestHeaderFilterWorks() {

View File

@@ -37,7 +37,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class RemoveResponseHeaderWebFilterFactoryTests extends BaseWebClientTests {
public class RemoveResponseHeaderGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void removeResponseHeaderFilterWorks() {

View File

@@ -15,18 +15,18 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerWebExchange;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilterChain;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory.BURST_CAPACITY_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory.KEY_RESOLVER_NAME_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory.REPLENISH_RATE_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.BURST_CAPACITY_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.KEY_RESOLVER_NAME_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.REPLENISH_RATE_KEY;
import static org.springframework.tuple.TupleBuilder.tuple;
import reactor.core.publisher.Mono;
@@ -38,16 +38,16 @@ import reactor.core.publisher.Mono;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class RequestRateLimiterWebFilterFactoryTests extends BaseWebClientTests {
public class RequestRateLimiterGatewayFilterFactoryTests extends BaseWebClientTests {
@Autowired
private RequestRateLimiterWebFilterFactory filterFactory;
private RequestRateLimiterGatewayFilterFactory filterFactory;
@MockBean
private RateLimiter rateLimiter;
@MockBean
private WebFilterChain filterChain;
private GatewayFilterChain filterChain;
@Test
public void allowedWorks() throws Exception {
@@ -71,7 +71,7 @@ public class RequestRateLimiterWebFilterFactoryTests extends BaseWebClientTests
MockServerHttpRequest request = MockServerHttpRequest.get("/").build();
MockServerWebExchange exchange = new MockServerWebExchange(request);
MockServerWebExchange exchange = MockServerWebExchange.from(request);
exchange.getResponse().setStatusCode(HttpStatus.OK);
when(this.filterChain.filter(exchange)).thenReturn(Mono.empty());

View File

@@ -38,7 +38,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class RewritePathWebFilterFactoryIntegrationTests extends BaseWebClientTests {
public class RewritePathGatewayFilterFactoryIntegrationTests extends BaseWebClientTests {
@Test
public void rewritePathFilterWorks() {

View File

@@ -22,27 +22,27 @@ import java.util.LinkedHashSet;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerWebExchange;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
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.filter.factory.RewritePathGatewayFilterFactory.REGEXP_KEY;
import static org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory.REPLACEMENT_KEY;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.tuple.TupleBuilder.tuple;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
*/
public class RewritePathWebFilterFactoryTests {
public class RewritePathGatewayFilterFactoryTests {
@Test
public void rewritePathFilterWorks() {
@@ -55,15 +55,15 @@ public class RewritePathWebFilterFactoryTests {
}
private void testRewriteFilter(String regex, String replacement, String actualPath, String expectedPath) {
WebFilter filter = new RewritePathWebFilterFactory().apply(tuple().of(REGEXP_KEY, regex, REPLACEMENT_KEY, replacement));
GatewayFilter filter = new RewritePathGatewayFilterFactory().apply(tuple().of(REGEXP_KEY, regex, REPLACEMENT_KEY, replacement));
MockServerHttpRequest request = MockServerHttpRequest
.get("http://localhost"+ actualPath)
.build();
ServerWebExchange exchange = new MockServerWebExchange(request);
ServerWebExchange exchange = MockServerWebExchange.from(request);
WebFilterChain filterChain = mock(WebFilterChain.class);
GatewayFilterChain filterChain = mock(GatewayFilterChain.class);
ArgumentCaptor<ServerWebExchange> captor = ArgumentCaptor.forClass(ServerWebExchange.class);
when(filterChain.filter(captor.capture())).thenReturn(Mono.empty());

View File

@@ -32,14 +32,14 @@ import org.springframework.web.reactive.function.client.ClientResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.CONTENT_SECURITY_POLICY_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.REFERRER_POLICY_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.STRICT_TRANSPORT_SECURITY_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.X_CONTENT_TYPE_OPTIONS_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.X_DOWNLOAD_OPTIONS_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.X_FRAME_OPTIONS_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactory.X_XSS_PROTECTION_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.CONTENT_SECURITY_POLICY_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.REFERRER_POLICY_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.STRICT_TRANSPORT_SECURITY_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.X_CONTENT_TYPE_OPTIONS_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.X_DOWNLOAD_OPTIONS_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.X_FRAME_OPTIONS_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER;
import static org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactory.X_XSS_PROTECTION_HEADER;
import static org.springframework.cloud.gateway.test.TestUtils.assertStatus;
import reactor.core.publisher.Mono;
@@ -48,7 +48,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class SecureHeadersWebFilterFactoryTests extends BaseWebClientTests {
public class SecureHeadersGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void secureHeadersFilterWorks() {

View File

@@ -38,7 +38,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class SetPathWebFilterFactoryIntegrationTests extends BaseWebClientTests {
public class SetPathGatewayFilterFactoryIntegrationTests extends BaseWebClientTests {
@Test
public void setPathFilterDefaultValuesWork() {

View File

@@ -26,18 +26,18 @@ import java.util.Map;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerWebExchange;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.util.pattern.PathPattern.PathMatchInfo;
import static org.assertj.core.api.Assertions.assertThat;
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.filter.factory.SetPathGatewayFilterFactory.TEMPLATE_KEY;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
import static org.springframework.tuple.TupleBuilder.tuple;
@@ -47,7 +47,7 @@ import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
*/
public class SetPathWebFilterFactoryTests {
public class SetPathGatewayFilterFactoryTests {
@Test
public void setPathFilterWorks() {
@@ -63,13 +63,13 @@ public class SetPathWebFilterFactoryTests {
}
private void testRewriteFilter(String template, String actualPath, String expectedPath, HashMap<String, String> variables) {
WebFilter filter = new SetPathWebFilterFactory().apply(tuple().of(TEMPLATE_KEY, template));
GatewayFilter filter = new SetPathGatewayFilterFactory().apply(tuple().of(TEMPLATE_KEY, template));
MockServerHttpRequest request = MockServerHttpRequest
.get("http://localhost"+ actualPath)
.build();
ServerWebExchange exchange = new MockServerWebExchange(request);
ServerWebExchange exchange = MockServerWebExchange.from(request);
try {
Constructor<PathMatchInfo> constructor = ReflectionUtils.accessibleConstructor(PathMatchInfo.class, Map.class, Map.class);
@@ -80,7 +80,7 @@ public class SetPathWebFilterFactoryTests {
ReflectionUtils.rethrowRuntimeException(e);
}
WebFilterChain filterChain = mock(WebFilterChain.class);
GatewayFilterChain filterChain = mock(GatewayFilterChain.class);
ArgumentCaptor<ServerWebExchange> captor = ArgumentCaptor.forClass(ServerWebExchange.class);
when(filterChain.filter(captor.capture())).thenReturn(Mono.empty());

View File

@@ -38,7 +38,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class SetResponseWebFilterFactoryTests extends BaseWebClientTests {
public class SetResponseGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void setResponseHeaderFilterWorks() {

View File

@@ -38,7 +38,7 @@ import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
public class SetStatusWebFilterFactoryTests extends BaseWebClientTests {
public class SetStatusGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void setStatusIntWorks() {

View File

@@ -14,7 +14,7 @@ import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.Routes;
import org.springframework.context.annotation.Bean;
@@ -32,9 +32,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory.BURST_CAPACITY_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterWebFilterFactory.REPLENISH_RATE_KEY;
import static org.springframework.cloud.gateway.filter.factory.WebFilterFactories.prefixPath;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.BURST_CAPACITY_KEY;
import static org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory.REPLENISH_RATE_KEY;
import static org.springframework.cloud.gateway.filter.factory.GatewayFilters.prefixPath;
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path;
import static org.springframework.tuple.TupleBuilder.tuple;
import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;
@@ -96,7 +96,7 @@ public class PrincipalNameKeyResolverIntegrationTests {
}
@Bean
public RouteLocator customRouteLocator(RequestRateLimiterWebFilterFactory rateLimiterFactory) {
public RouteLocator customRouteLocator(RequestRateLimiterGatewayFilterFactory rateLimiterFactory) {
return Routes.locator()
.route("protected-throttled")
.uri("http://localhost:"+port)

View File

@@ -22,7 +22,7 @@ import java.time.format.DateTimeFormatter;
import org.junit.Test;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerWebExchange;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
@@ -128,6 +128,6 @@ public class BetweenRoutePredicateFactoryTests {
static ServerWebExchange getExchange() {
MockServerHttpRequest request = MockServerHttpRequest.get("http://example.com").build();
return new MockServerWebExchange(request);
return MockServerWebExchange.from(request);
}
}

View File

@@ -20,6 +20,7 @@ package org.springframework.cloud.gateway.handler.predicate;
import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
@@ -58,17 +59,17 @@ public class RoutePredicatesTest {
private ServerWebExchange mockHostExchange(String host) {
MockServerHttpRequest mockRequest = MockServerHttpRequest.get("/")
.header("Host", host).build();
return mockRequest.toExchange();
return MockServerWebExchange.from(mockRequest);
}
private ServerWebExchange mockPathExchange(String path) {
MockServerHttpRequest mockRequest = MockServerHttpRequest.get(path).build();
return mockRequest.toExchange();
return MockServerWebExchange.from(mockRequest);
}
private ServerWebExchange mockMethodExchange(String method) {
MockServerHttpRequest mockRequest = MockServerHttpRequest
.method(HttpMethod.resolve(method), "/").build();
return mockRequest.toExchange();
return MockServerWebExchange.from(mockRequest);
}
}

View File

@@ -24,19 +24,19 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.junit.runners.model.Statement;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.HystrixWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RedirectToWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RemoveRequestHeaderWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactoryIntegrationTests;
import org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.SecureHeadersWebFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.SetPathWebFilterFactoryIntegrationTests;
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.filter.factory.AddRequestHeaderGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RemoveNonProxyHeadersGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RemoveRequestHeaderGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactoryIntegrationTests;
import org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.SetPathGatewayFilterFactoryIntegrationTests;
import org.springframework.cloud.gateway.filter.factory.SetPathGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.SetResponseGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.factory.SetStatusGatewayFilterFactoryTests;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiterTests;
import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactoryTests;
import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactoryTests;
@@ -61,19 +61,19 @@ import static org.junit.Assume.assumeThat;
RedisRateLimiterTests.class,
WebSocketIntegrationTests.class,
// route filter tests
AddRequestHeaderWebFilterFactoryTests.class,
AddRequestParameterWebFilterFactoryTests.class,
HystrixWebFilterFactoryTests.class,
RedirectToWebFilterFactoryTests.class,
RemoveNonProxyHeadersWebFilterFactoryTests.class,
RemoveRequestHeaderWebFilterFactoryTests.class,
RewritePathWebFilterFactoryIntegrationTests.class,
SecureHeadersWebFilterFactoryTests.class,
SetPathWebFilterFactoryIntegrationTests.class,
SetPathWebFilterFactoryTests.class,
SetResponseWebFilterFactoryTests.class,
SetStatusWebFilterFactoryTests.class,
RewritePathWebFilterFactoryTests.class,
AddRequestHeaderGatewayFilterFactoryTests.class,
AddRequestParameterGatewayFilterFactoryTests.class,
HystrixGatewayFilterFactoryTests.class,
RedirectToGatewayFilterFactoryTests.class,
RemoveNonProxyHeadersGatewayFilterFactoryTests.class,
RemoveRequestHeaderGatewayFilterFactoryTests.class,
RewritePathGatewayFilterFactoryIntegrationTests.class,
SecureHeadersGatewayFilterFactoryTests.class,
SetPathGatewayFilterFactoryIntegrationTests.class,
SetPathGatewayFilterFactoryTests.class,
SetResponseGatewayFilterFactoryTests.class,
SetStatusGatewayFilterFactoryTests.class,
RewritePathGatewayFilterFactoryTests.class,
// RoutePredicateFactory tests
AfterRoutePredicateFactoryTests.class,
BeforeRoutePredicateFactoryTests.class,

View File

@@ -1,10 +1,11 @@
package org.springframework.cloud.gateway.route
import org.junit.Test
import org.springframework.cloud.gateway.filter.factory.WebFilterFactories.addResponseHeader
import org.springframework.cloud.gateway.filter.factory.GatewayFilters.addResponseHeader
import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host
import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path
import org.springframework.mock.http.server.reactive.MockServerHttpRequest
import org.springframework.mock.web.server.MockServerWebExchange
import org.springframework.web.server.ServerWebExchange
import reactor.test.StepVerifier
import java.net.URI
@@ -33,22 +34,22 @@ class GatewayDslTests {
StepVerifier
.create(routeLocator.routes)
.expectNextMatches({ r ->
r.id == "test" && r.webFilters.size == 1 && r.uri == URI.create("http://httpbin.org:80")
r.id == "test" && r.filters.size == 1 && r.uri == URI.create("http://httpbin.org:80")
})
.expectNextMatches({ r ->
r.id == "test2" && r.webFilters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
r.id == "test2" && r.filters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
})
.expectComplete()
.verify()
val sampleExchange: ServerWebExchange = MockServerHttpRequest.get("/image/webp")
.header("Host", "test.abc.org").toExchange()
val sampleExchange: ServerWebExchange = MockServerWebExchange.from(MockServerHttpRequest.get("/image/webp")
.header("Host", "test.abc.org").build())
val filteredRoutes = routeLocator.routes.filter({ r -> r.predicate.test(sampleExchange) })
StepVerifier.create(filteredRoutes)
.expectNextMatches({ r ->
r.id == "test2" && r.webFilters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
r.id == "test2" && r.filters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
})
.expectComplete()
.verify()

View File

@@ -29,7 +29,7 @@ import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.cloud.gateway.filter.factory.WebFilterFactories.addResponseHeader;
import static org.springframework.cloud.gateway.filter.factory.GatewayFilters.addResponseHeader;
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host;
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path;
import static org.springframework.tuple.TupleBuilder.tuple;
@@ -42,7 +42,7 @@ import static org.springframework.tuple.TupleBuilder.tuple;
public class GatewaySampleApplication {
@Bean
public RouteLocator customRouteLocator(ThrottleWebFilterFactory throttle) {
public RouteLocator customRouteLocator(ThrottleGatewayFilterFactory throttle) {
return Routes.locator()
.route("test")
.uri("http://httpbin.org:80")
@@ -67,8 +67,8 @@ public class GatewaySampleApplication {
}
@Bean
public ThrottleWebFilterFactory throttleWebFilterFactory() {
return new ThrottleWebFilterFactory();
public ThrottleGatewayFilterFactory throttleWebFilterFactory() {
return new ThrottleGatewayFilterFactory();
}
@Bean

View File

@@ -21,10 +21,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.isomorphism.util.TokenBucket;
import org.isomorphism.util.TokenBuckets;
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.WebFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import java.util.concurrent.TimeUnit;
@@ -32,11 +32,11 @@ import java.util.concurrent.TimeUnit;
* Sample throttling filter.
* See https://github.com/bbeck/token-bucket
*/
public class ThrottleWebFilterFactory implements WebFilterFactory {
public class ThrottleGatewayFilterFactory implements GatewayFilterFactory {
private Log log = LogFactory.getLog(getClass());
@Override
public WebFilter apply(Tuple args) {
public GatewayFilter apply(Tuple args) {
int capacity = args.getInt("capacity");
int refillTokens = args.getInt("refillTokens");
int refillPeriod = args.getInt("refillPeriod");