Use RefreshRoutesEvent to trigger code to clear route caches

This commit is contained in:
Spencer Gibb
2017-02-17 17:55:48 -07:00
parent db3c0d1211
commit e6faa31c48
4 changed files with 48 additions and 9 deletions

View File

@@ -14,8 +14,10 @@ import org.springframework.cloud.gateway.api.RouteWriter;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.route.RouteFilter;
import org.springframework.cloud.gateway.handler.FilteringWebHandler;
import org.springframework.cloud.gateway.support.CachingRouteLocator;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.cloud.gateway.support.RefreshRoutesEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.core.Ordered;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
@@ -26,7 +28,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
@@ -36,7 +37,7 @@ import reactor.core.publisher.Mono;
//@ConfigurationProperties(prefix = "endpoints.gateway")
@RestController
@RequestMapping("/admin/gateway")
public class GatewayEndpoint {/*extends AbstractEndpoint<Map<String, Object>> {*/
public class GatewayEndpoint implements ApplicationEventPublisherAware {/*extends AbstractEndpoint<Map<String, Object>> {*/
private static final Log log = LogFactory.getLog(GatewayEndpoint.class);
@@ -45,6 +46,7 @@ public class GatewayEndpoint {/*extends AbstractEndpoint<Map<String, Object>> {*
private List<RouteFilter> routeFilters;
private FilteringWebHandler filteringWebHandler;
private RouteWriter routeWriter;
private ApplicationEventPublisher publisher;
public GatewayEndpoint(RouteLocator routeLocator, List<GlobalFilter> globalFilters,
List<RouteFilter> routeFilters, FilteringWebHandler filteringWebHandler,
@@ -57,17 +59,20 @@ public class GatewayEndpoint {/*extends AbstractEndpoint<Map<String, Object>> {*
this.routeWriter = routeWriter;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
/*@Override
public Map<String, Object> invoke() {
}*/
//TODO: this should really be a listener that responds to a RefreshEvent
@PostMapping("/refresh")
public Flux<Route> refresh() {
if (this.routeLocator instanceof CachingRouteLocator) {
return ((CachingRouteLocator)this.routeLocator).refresh();
}
return Flux.empty();
public Mono<Void> refresh() {
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return Mono.empty();
}
@GetMapping("/globalfilters")

View File

@@ -24,6 +24,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
@@ -33,6 +35,8 @@ 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.cloud.gateway.support.RefreshRoutesEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.web.server.ServerWebExchange;
@@ -61,7 +65,7 @@ public class FilteringWebHandler extends WebHandlerDecorator {
private final List<GlobalFilter> globalFilters;
private final Map<String, RouteFilter> routeFilters = new HashMap<>();
private final Map<String, List<WebFilter>> combinedFiltersForRoute = new HashMap<>();
private final ConcurrentMap<String, List<WebFilter>> combinedFiltersForRoute = new ConcurrentHashMap<>();
public FilteringWebHandler(GatewayProperties gatewayProperties, List<GlobalFilter> globalFilters,
Map<String, RouteFilter> routeFilters) {
@@ -91,6 +95,12 @@ public class FilteringWebHandler extends WebHandlerDecorator {
return this.globalFilters;
}
@EventListener(RefreshRoutesEvent.class)
/* for testing */ void handleRefresh() {
this.combinedFiltersForRoute.clear();
}
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
Optional<Route> route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);

View File

@@ -5,6 +5,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.springframework.cloud.gateway.api.Route;
import org.springframework.cloud.gateway.api.RouteLocator;
import org.springframework.context.event.EventListener;
import reactor.core.publisher.Flux;
/**
@@ -37,4 +38,9 @@ public class CachingRouteLocator implements RouteLocator {
private List<Route> collectRoutes() {
return this.delegate.getRoutes().collectList().block();
}
@EventListener(RefreshRoutesEvent.class)
/* for testing */ void handleRefresh() {
refresh();
}
}

View File

@@ -0,0 +1,18 @@
package org.springframework.cloud.gateway.support;
import org.springframework.context.ApplicationEvent;
/**
* @author Spencer Gibb
*/
public class RefreshRoutesEvent extends ApplicationEvent {
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public RefreshRoutesEvent(Object source) {
super(source);
}
}