Default filters now get route specific events.

Filters like Retry with a POST body require an event to be sent from the
filter factory to the caching filter higher up the filter chain. Default
filters were created with a static id and therefor didn't receive the
event. This updates default filters to use the route id.

Fixes gh-1918
Fixes gh-2150
This commit is contained in:
Felipe Adorno
2021-02-18 21:35:46 -03:00
committed by spencergibb
parent 70c50744fb
commit fedb6fce77
3 changed files with 38 additions and 7 deletions

View File

@@ -168,12 +168,10 @@ public class RetryGatewayFilterFactory
@Override
public String toString() {
return filterToStringCreator(RetryGatewayFilterFactory.this)
.append("retries", retryConfig.getRetries())
.append("series", retryConfig.getSeries())
.append("statuses", retryConfig.getStatuses())
.append("methods", retryConfig.getMethods())
.append("exceptions", retryConfig.getExceptions()).toString();
return filterToStringCreator(RetryGatewayFilterFactory.this).append("retries", retryConfig.getRetries())
.append("series", retryConfig.getSeries()).append("statuses", retryConfig.getStatuses())
.append("methods", retryConfig.getMethods()).append("exceptions", retryConfig.getExceptions())
.toString();
}
};
}

View File

@@ -225,7 +225,7 @@ public class RouteDefinitionRouteLocator
// TODO: support option to apply defaults after route specific filters?
if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
filters.addAll(loadGatewayFilters(DEFAULT_FILTERS,
filters.addAll(loadGatewayFilters(routeDefinition.getId(),
new ArrayList<>(this.gatewayProperties.getDefaultFilters())));
}

View File

@@ -33,6 +33,7 @@ import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFac
import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RemoveResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactory;
import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
@@ -118,6 +119,38 @@ public class RouteDefinitionRouteLocatorTests {
}).expectComplete().verify();
}
@Test
public void contextLoadsAndApplyRouteIdToRetryFilter() {
List<RoutePredicateFactory> predicates = Arrays.asList(new HostRoutePredicateFactory());
List<GatewayFilterFactory> gatewayFilterFactories = Arrays.asList(new RetryGatewayFilterFactory(),
new AddResponseHeaderGatewayFilterFactory());
GatewayProperties gatewayProperties = new GatewayProperties();
gatewayProperties.setDefaultFilters(Arrays.asList(new FilterDefinition("Retry")));
gatewayProperties.setRoutes(Arrays.asList(new RouteDefinition() {
{
setId("foo");
setUri(URI.create("https://foo.example.com"));
setPredicates(Arrays.asList(new PredicateDefinition("Host=*.example.com")));
setFilters(Arrays.asList(new FilterDefinition("AddResponseHeader=X-Response-Foo, Bar")));
}
}));
PropertiesRouteDefinitionLocator routeDefinitionLocator = new PropertiesRouteDefinitionLocator(
gatewayProperties);
@SuppressWarnings("deprecation")
RouteDefinitionRouteLocator routeDefinitionRouteLocator = new RouteDefinitionRouteLocator(
new CompositeRouteDefinitionLocator(Flux.just(routeDefinitionLocator)), predicates,
gatewayFilterFactories, gatewayProperties, new ConfigurationService(null, () -> null, () -> null));
StepVerifier.create(routeDefinitionRouteLocator.getRoutes()).assertNext(route -> {
List<GatewayFilter> filters = route.getFilters();
assertThat(filters).hasSize(2);
assertThat(filters.get(0).toString()).contains("routeId = 'foo'");
assertThat(getFilterClassName(filters.get(0))).contains("Retry");
assertThat(getFilterClassName(filters.get(1))).contains("AddResponseHeader");
}).expectComplete().verify();
}
private List<RouteDefinition> containsInvalidRoutes() {
RouteDefinition foo = new RouteDefinition();
foo.setId("foo");