diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java index 29639c52..273f7eab 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java @@ -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 getRoutes() { - if (this.routes.get() == null) { - this.routes.set(locateRoutes()); - } List values = new ArrayList<>(); - for (String url : this.routes.get().keySet()) { - ZuulRoute route = this.routes.get().get(url); + for (Entry 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 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 entry : this.routes.get().entrySet()) { + for (Entry entry : getRoutesMap().entrySet()) { String pattern = entry.getKey(); log.debug("Matching pattern:" + pattern); if (this.pathMatcher.match(pattern, adjustedPath)) { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java new file mode 100644 index 00000000..0ba3d486 --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java @@ -0,0 +1,112 @@ +/* + * 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 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 getRoutes() { + List values = new ArrayList<>(); + + for (Entry 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 getRoutesMap() { + return super.getRoutesMap(); + } + } +} \ No newline at end of file