Browse Source

Merge pull request #464 from andreasevers/zuul-ignored-patterns

* zuul-ignored-patterns:
  If more fine-grained ignoring is needed, you can specify specific patterns to ignore. These patterns are being evaluated at the end of the route location process, which means prefixes should be included in the pattern to warrant a match. Ignored patterns span all services and supersede any other route specification.
pull/6/head
Spencer Gibb 9 years ago
parent
commit
cb732763b5
  1. 17
      docs/src/main/asciidoc/spring-cloud-netflix.adoc
  2. 55
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRouteLocator.java
  3. 2
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java
  4. 150
      spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRouteLocatorTests.java

17
docs/src/main/asciidoc/spring-cloud-netflix.adoc

@ -900,6 +900,23 @@ An application with the `@EnableZuulProxy` could act as a standalone @@ -900,6 +900,23 @@ An application with the `@EnableZuulProxy` could act as a standalone
server if you set a default route ("/"), for example `zuul.route.home:
/` would route all traffic (i.e. "/**") to the "home" service.
If more fine-grained ignoring is needed, you can specify specific patterns to ignore.
These patterns are being evaluated at the end of the route location process, which
means prefixes should be included in the pattern to warrant a match. Ignored patterns
span all services and supersede any other route specification.
.application.yml
[source,yaml]
----
zuul:
ignoredPatterns: */admin/**
routes:
users: /myusers/**
----
This means that all calls such as "/myusers/101" will be forwarded to "/101" on the "users" service.
But calls including "/admin/" will not resolve.
=== Uploading Files through Zuul
If you `@EnableZuulProxy` you can use the proxy paths to

55
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRouteLocator.java

@ -108,35 +108,48 @@ public class ProxyRouteLocator implements RouteLocator { @@ -108,35 +108,48 @@ public class ProxyRouteLocator implements RouteLocator {
}
log.debug("path=" + path);
Boolean retryable = this.properties.getRetryable();
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
String pattern = entry.getKey();
log.debug("Matching pattern:" + pattern);
if (this.pathMatcher.match(pattern, path)) {
ZuulRoute route = entry.getValue();
id = route.getId();
location = route.getLocation();
targetPath = path;
if (path.startsWith(prefix) && this.properties.isStripPrefix()) {
targetPath = path.substring(prefix.length());
}
if (route.isStripPrefix()) {
int index = route.getPath().indexOf("*") - 1;
if (index > 0) {
String routePrefix = route.getPath().substring(0, index);
targetPath = targetPath.replaceFirst(routePrefix, "");
prefix = prefix + routePrefix;
if (!matchesIgnoredPatterns(path)) {
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
String pattern = entry.getKey();
log.debug("Matching pattern:" + pattern);
if (this.pathMatcher.match(pattern, path)) {
ZuulRoute route = entry.getValue();
id = route.getId();
location = route.getLocation();
targetPath = path;
if (path.startsWith(prefix) && this.properties.isStripPrefix()) {
targetPath = path.substring(prefix.length());
}
if (route.isStripPrefix()) {
int index = route.getPath().indexOf("*") - 1;
if (index > 0) {
String routePrefix = route.getPath().substring(0, index);
targetPath = targetPath.replaceFirst(routePrefix, "");
prefix = prefix + routePrefix;
}
}
if (route.getRetryable() != null) {
retryable = route.getRetryable();
}
break;
}
if (route.getRetryable() != null) {
retryable = route.getRetryable();
}
break;
}
}
return (location == null ? null : new ProxyRouteSpec(id, targetPath, location,
prefix, retryable));
}
protected boolean matchesIgnoredPatterns(String path) {
for (String pattern : this.properties.getIgnoredPatterns()) {
log.debug("Matching ignored pattern:" + pattern);
if (this.pathMatcher.match(pattern, path)) {
log.debug("Path " + path + " matches ignored pattern " + pattern);
return true;
}
}
return false;
}
public void resetRoutes() {
this.routes.set(locateRoutes());
}

2
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java

@ -51,6 +51,8 @@ public class ZuulProperties { @@ -51,6 +51,8 @@ public class ZuulProperties {
private List<String> ignoredServices = new ArrayList<String>();
private List<String> ignoredPatterns = new ArrayList<String>();
private String servletPath = "/zuul";
@PostConstruct

150
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRouteLocatorTests.java

@ -44,6 +44,8 @@ public class ProxyRouteLocatorTests { @@ -44,6 +44,8 @@ public class ProxyRouteLocatorTests {
public static final String IGNOREDSERVICE = "ignoredservice";
public static final String IGNOREDPATTERN = "/foo/**";
public static final String ASERVICE = "aservice";
public static final String MYSERVICE = "myservice";
@ -151,7 +153,155 @@ public class ProxyRouteLocatorTests { @@ -151,7 +153,155 @@ public class ProxyRouteLocatorTests {
assertEquals("foo", route.getLocation());
assertEquals("/1", route.getPath());
}
@Test
public void testGetMatchingPathWithoutMatchingIgnoredPattern() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**"));
this.properties.init();
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/bar/1");
assertEquals("bar", route.getLocation());
assertEquals("bar", route.getId());
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPattern() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
this.properties.init();
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1");
assertNull("routes did not ignore " + IGNOREDPATTERN, route);
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPatternWithPrefix() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
this.properties.setPrefix("/proxy");
this.properties.init();
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertEquals("foo", route.getLocation());
assertEquals("/1", route.getPath());
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPatternWithServletPath() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/app", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
this.properties.init();
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/app/foo/1");
assertNull("routes did not ignore " + IGNOREDPATTERN, route);
}
@Test
public void testGetMatchingPathWithoutMatchingIgnoredPatternWithNoPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo",
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
this.properties.setStripPrefix(false);
this.properties.setPrefix("/proxy");
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertEquals("foo", route.getLocation());
assertEquals("/proxy/foo/1", route.getPath());
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPatternWithNoPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList("/proxy" + IGNOREDPATTERN));
this.properties.getRoutes().put("foo",
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
this.properties.setStripPrefix(false);
this.properties.setPrefix("/proxy");
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertNull("routes did not ignore " + "/proxy" + IGNOREDPATTERN, route);
}
@Test
public void testGetMatchingPathWithoutMatchingIgnoredPatternWithLocalPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo"));
this.properties.setStripPrefix(false);
this.properties.setPrefix("/proxy");
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertEquals("foo", route.getLocation());
assertEquals("/proxy/1", route.getPath());
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPatternWithLocalPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList("/proxy" + IGNOREDPATTERN));
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo"));
this.properties.setStripPrefix(false);
this.properties.setPrefix("/proxy");
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertNull("routes did not ignore " + "/proxy" + IGNOREDPATTERN, route);
}
@Test
public void testGetMatchingPathWithoutMatchingIgnoredPatternWithGlobalPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo",
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
this.properties.setPrefix("/proxy");
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertEquals("foo", route.getLocation());
assertEquals("/foo/1", route.getPath());
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPatternWithGlobalPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
this.properties.setIgnoredPatterns(Collections.singletonList("/proxy" + IGNOREDPATTERN));
this.properties.getRoutes().put("foo",
new ZuulRoute("foo", "/foo/**", "foo", null, false, null));
this.properties.setPrefix("/proxy");
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
assertNull("routes did not ignore " + "/proxy" + IGNOREDPATTERN, route);
}
@Test
public void testGetMatchingPathWithMatchingIgnoredPatternWithRoutePrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,
this.properties);
ZuulRoute zuulRoute = new ZuulRoute("/foo/**");
zuulRoute.setStripPrefix(true);
this.properties.setIgnoredPatterns(Collections.singletonList(IGNOREDPATTERN));
this.properties.getRoutes().put("foo", zuulRoute);
this.properties.init();
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1");
assertNull("routes did not ignore " + IGNOREDPATTERN, route);
}
@Test
public void testGetRoutes() {
ProxyRouteLocator routeLocator = new ProxyRouteLocator("/", this.discovery,

Loading…
Cancel
Save