Commit ea5585e3 by Tom Cawley Committed by Spencer Gibb

Dynamic filtering on Zuul SimpleRouteLocator.getRoutes()

* Introduce getRoutesMap() so subclasses can have read/write access to configured/discovered routes.
parent ace95a33
......@@ -23,7 +23,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
......@@ -65,12 +64,9 @@ public class SimpleRouteLocator implements RouteLocator, Ordered {
@Override
public List<Route> getRoutes() {
if (this.routes.get() == null) {
this.routes.set(locateRoutes());
}
List<Route> values = new ArrayList<>();
for (String url : this.routes.get().keySet()) {
ZuulRoute route = this.routes.get().get(url);
for (Entry<String, ZuulRoute> entry : getRoutesMap().entrySet()) {
ZuulRoute route = entry.getValue();
String path = route.getPath();
values.add(getRoute(route, path));
}
......@@ -89,14 +85,20 @@ public class SimpleRouteLocator implements RouteLocator, Ordered {
}
protected Map<String, ZuulRoute> getRoutesMap() {
if (this.routes.get() == null) {
this.routes.set(locateRoutes());
}
return this.routes.get();
}
protected Route getSimpleMatchingRoute(final String path) {
if (log.isDebugEnabled()) {
log.debug("Finding route for path: " + path);
}
if (this.routes.get() == null) {
this.routes.set(locateRoutes());
}
// This is called for the initialization done in getRoutesMap()
getRoutesMap();
if (log.isDebugEnabled()) {
log.debug("servletPath=" + this.dispatcherServletPath);
......@@ -116,7 +118,7 @@ public class SimpleRouteLocator implements RouteLocator, Ordered {
protected ZuulRoute getZuulRoute(String adjustedPath) {
if (!matchesIgnoredPatterns(adjustedPath)) {
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
for (Entry<String, ZuulRoute> entry : getRoutesMap().entrySet()) {
String pattern = entry.getKey();
log.debug("Matching pattern:" + pattern);
if (this.pathMatcher.match(pattern, adjustedPath)) {
......
/*
* Copyright 2013-2014 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.netflix.zuul.filters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
/**
* @author Tom Cawley
*/
public class SimpleRouteLocatorTests {
private ZuulProperties zuul = new ZuulProperties();
public SimpleRouteLocatorTests() {
}
@Test
public void test_getRoutesDefaultRouteAcceptor() {
RouteLocator locator = new SimpleRouteLocator("/", this.zuul);
this.zuul.getRoutes().clear();
this.zuul.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo"));
assertThat(locator.getRoutes(), hasItem(createRoute("foo", "/**", "/foo")));
}
@Test
public void test_getRoutesFilterRouteAcceptor() {
RouteLocator locator = new FilteringRouteLocator("/", this.zuul);
this.zuul.getRoutes().clear();
this.zuul.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo"));
this.zuul.getRoutes().put("bar", new ZuulRoute("/bar/**", "bar"));
final List<Route> routes = locator.getRoutes();
assertThat(routes, hasItem(createRoute("bar", "/**", "/bar")));
assertThat(routes, hasSize(1));
}
@Test
public void test_getMatchingRouteFilterRouteAcceptor() {
RouteLocator locator = new FilteringRouteLocator("/", this.zuul);
this.zuul.getRoutes().clear();
this.zuul.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo"));
this.zuul.getRoutes().put("bar", new ZuulRoute("/bar/**", "bar"));
assertThat(locator.getMatchingRoute("/foo/1"), nullValue());
assertThat(locator.getMatchingRoute("/bar/1"), is(createRoute("bar", "/1", "/bar")));
}
private Route createRoute(String id, String path, String prefix) {
return new Route(id, path, id, prefix, false, null);
}
private static class FilteringRouteLocator extends SimpleRouteLocator {
public FilteringRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
}
@Override
public List<Route> getRoutes() {
List<Route> values = new ArrayList<>();
for (Entry<String, ZuulRoute> entry : getRoutesMap().entrySet()) {
ZuulRoute route = entry.getValue();
if (acceptRoute(route)) {
String path = route.getPath();
values.add(getRoute(route, path));
}
}
return values;
}
private boolean acceptRoute(ZuulRoute route) {
return route != null && !(route.getId().equals("foo"));
}
protected Route getRoute(ZuulRoute route, String path) {
if (acceptRoute(route)) {
return super.getRoute(route, path);
}
return null;
}
// For testing, expose as public so we can call getRoutesMap() directly.
@Override
public Map<String, ZuulRoute> getRoutesMap() {
return super.getRoutesMap();
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment