Add support for default filters.
fixes gh-23
This commit is contained in:
@@ -84,9 +84,9 @@ public class GatewayAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters,
|
||||
public FilteringWebHandler filteringWebHandler(GatewayProperties properties, List<GlobalFilter> globalFilters,
|
||||
Map<String, RouteFilter> routeFilters) {
|
||||
return new FilteringWebHandler(globalFilters, routeFilters);
|
||||
return new FilteringWebHandler(properties, globalFilters, routeFilters);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.gateway.api.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.api.Route;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@@ -16,12 +17,17 @@ import javax.validation.constraints.NotNull;
|
||||
public class GatewayProperties {
|
||||
|
||||
/**
|
||||
* Map of route names to properties.
|
||||
* List of Routes
|
||||
*/
|
||||
@NotNull
|
||||
@Valid
|
||||
private List<Route> routes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* List of filter definitions that are applied to every route.
|
||||
*/
|
||||
private List<FilterDefinition> defaultFilters = new ArrayList<>();
|
||||
|
||||
public List<Route> getRoutes() {
|
||||
return routes;
|
||||
}
|
||||
@@ -30,4 +36,11 @@ public class GatewayProperties {
|
||||
this.routes = routes;
|
||||
}
|
||||
|
||||
public List<FilterDefinition> getDefaultFilters() {
|
||||
return defaultFilters;
|
||||
}
|
||||
|
||||
public void setDefaultFilters(List<FilterDefinition> defaultFilters) {
|
||||
this.defaultFilters = defaultFilters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.gateway.api.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.api.Route;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.filter.route.RouteFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
@@ -55,19 +57,21 @@ import reactor.core.publisher.Mono;
|
||||
public class FilteringWebHandler extends WebHandlerDecorator {
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final GatewayProperties gatewayProperties;
|
||||
private final List<GlobalFilter> globalFilters;
|
||||
private final Map<String, RouteFilter> routeFilters = new HashMap<>();
|
||||
|
||||
private final Map<String, List<WebFilter>> combinedFiltersForRoute = new HashMap<>();
|
||||
|
||||
public FilteringWebHandler(List<GlobalFilter> globalFilters,
|
||||
public FilteringWebHandler(GatewayProperties gatewayProperties, List<GlobalFilter> globalFilters,
|
||||
Map<String, RouteFilter> routeFilters) {
|
||||
this(new EmptyWebHandler(), globalFilters, routeFilters);
|
||||
this(new EmptyWebHandler(), gatewayProperties, globalFilters, routeFilters);
|
||||
}
|
||||
|
||||
public FilteringWebHandler(WebHandler targetHandler, List<GlobalFilter> globalFilters,
|
||||
public FilteringWebHandler(WebHandler targetHandler, GatewayProperties gatewayProperties, List<GlobalFilter> globalFilters,
|
||||
Map<String, RouteFilter> routeFilters) {
|
||||
super(targetHandler);
|
||||
this.gatewayProperties = gatewayProperties;
|
||||
this.globalFilters = initList(globalFilters);
|
||||
routeFilters.forEach((name, def) -> this.routeFilters.put(normalizeName(name), def));
|
||||
}
|
||||
@@ -107,8 +111,14 @@ public class FilteringWebHandler extends WebHandlerDecorator {
|
||||
//TODO: probably a java 8 stream way of doing this
|
||||
combinedFilters = new ArrayList<>(loadFilters(this.globalFilters));
|
||||
|
||||
//TODO: support option to apply defaults after route specific filters?
|
||||
if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
|
||||
combinedFilters.addAll(loadWebFilters("defaultFilters",
|
||||
this.gatewayProperties.getDefaultFilters()));
|
||||
}
|
||||
|
||||
if (route.isPresent() && !route.get().getFilters().isEmpty()) {
|
||||
combinedFilters.addAll(loadRouteFilters(route.get()));
|
||||
combinedFilters.addAll(loadWebFilters(route.get().getId(), route.get().getFilters()));
|
||||
}
|
||||
|
||||
AnnotationAwareOrderComparator.sort(combinedFilters);
|
||||
@@ -129,8 +139,8 @@ public class FilteringWebHandler extends WebHandlerDecorator {
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<WebFilter> loadRouteFilters(Route route) {
|
||||
List<WebFilter> filters = route.getFilters().stream()
|
||||
private List<WebFilter> loadWebFilters(String id, List<FilterDefinition> filterDefinitions) {
|
||||
List<WebFilter> filters = filterDefinitions.stream()
|
||||
.map(definition -> {
|
||||
RouteFilter filter = this.routeFilters.get(definition.getName());
|
||||
if (filter == null) {
|
||||
@@ -143,7 +153,7 @@ public class FilteringWebHandler extends WebHandlerDecorator {
|
||||
} else {
|
||||
args = Collections.emptyList();
|
||||
}
|
||||
logger.debug("Route " + route.getId() + " applying filter " + args + " to " + definition.getName());
|
||||
logger.debug("Route " + id + " applying filter " + args + " to " + definition.getName());
|
||||
}
|
||||
return filter.apply(definition.getArgs());
|
||||
})
|
||||
|
||||
@@ -9,11 +9,13 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.gateway.api.Route;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.filter.route.SecureHeadersProperties;
|
||||
import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping;
|
||||
@@ -73,6 +75,9 @@ public class GatewayIntegrationTests {
|
||||
private WebClient webClient;
|
||||
private String baseUri;
|
||||
|
||||
@Autowired
|
||||
private GatewayProperties properties;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
//TODO: how to set new ReactorClientHttpConnector()
|
||||
@@ -187,6 +192,27 @@ public class GatewayIntegrationTests {
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultFiltersWorks() {
|
||||
assertThat(this.properties.getDefaultFilters()).isNotEmpty();
|
||||
|
||||
Mono<ClientResponse> result = webClient.get()
|
||||
.uri("/headers")
|
||||
.header("Host", "www.addresponseheader.org")
|
||||
.exchange();
|
||||
|
||||
StepVerifier.create(result)
|
||||
.consumeNextWith(
|
||||
response -> {
|
||||
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
|
||||
assertThat(httpHeaders.getFirst("X-Response-Default-Foo"))
|
||||
.isEqualTo("Default-Bar");
|
||||
assertThat(httpHeaders.get("X-Response-Default-Foo")).hasSize(1);
|
||||
})
|
||||
.expectComplete()
|
||||
.verify(DURATION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hostRouteWorks() {
|
||||
Mono<ClientResponse> result = webClient.get()
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
default-filters:
|
||||
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
|
||||
|
||||
routes:
|
||||
# =====================================
|
||||
- host_example_to_httpbin=http://httpbin.org:80, Host=**.example.org
|
||||
|
||||
Reference in New Issue
Block a user