Skip to content

Commit

Permalink
Backward compatibility with Spring Cloud
Browse files Browse the repository at this point in the history
  • Loading branch information
jmnarloch committed Feb 1, 2016
1 parent 9e74691 commit 5456091
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package io.jmnarloch.spring.cloud.zuul.matcher;

import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;

import java.util.Map;

Expand All @@ -31,12 +31,13 @@ public interface RouteMatcher {
*
* @param routes the routes map
*/
void setRoutes(Map<String, ProxyRouteLocator.ProxyRouteSpec> routes);
void setRoutes(Map<String, ZuulProperties.ZuulRoute> routes);

/**
* Retrieves the route spec for given path.
* Retrieves the route specification for given path.
*
* @param path the route path
* @return the matching route spec
* @return the matching route spec, or null if no routes matches the path
*/
ProxyRouteLocator.ProxyRouteSpec getMatchingRoute(String path);
ZuulProperties.ZuulRoute getMatchingRoute(String path);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package io.jmnarloch.spring.cloud.zuul.matcher;

import io.jmnarloch.spring.cloud.zuul.trie.Trie;
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.util.Assert;

import java.util.Map;
Expand All @@ -42,8 +42,8 @@ public class TrieRouteMatcher implements RouteMatcher {
/**
* Holds the reference to the Trie instance.
*/
private final AtomicReference<Trie<ProxyRouteSpecEntry>> trie =
new AtomicReference<Trie<ProxyRouteSpecEntry>>();
private final AtomicReference<Trie<ZuulRouteEntry>> trie =
new AtomicReference<Trie<ZuulRouteEntry>>();

/**
* Creates new instance of {@link TrieRouteMatcher} with specific supplier.
Expand All @@ -59,13 +59,13 @@ public TrieRouteMatcher(TrieSupplier trieSupplier) {
* {@inheritDoc}
*/
@Override
public void setRoutes(Map<String, ProxyRouteLocator.ProxyRouteSpec> routes) {
public void setRoutes(Map<String, ZuulProperties.ZuulRoute> routes) {

final Trie<ProxyRouteSpecEntry> trie = createTrie();
for (Map.Entry<String, ProxyRouteLocator.ProxyRouteSpec> route : routes.entrySet()) {
final Trie<ZuulRouteEntry> trie = createTrie();
for (Map.Entry<String, ZuulProperties.ZuulRoute> route : routes.entrySet()) {
trie.put(
path(route.getKey()),
new ProxyRouteSpecEntry(route.getKey(), route.getValue(), isWildcard(route.getKey()))
new ZuulRouteEntry(route.getKey(), route.getValue(), isWildcard(route.getKey()))
);
}
this.trie.lazySet(trie);
Expand All @@ -75,13 +75,13 @@ public void setRoutes(Map<String, ProxyRouteLocator.ProxyRouteSpec> routes) {
* {@inheritDoc}
*/
@Override
public ProxyRouteLocator.ProxyRouteSpec getMatchingRoute(String path) {
final ProxyRouteSpecEntry matching = trie.get().prefix(path);
public ZuulProperties.ZuulRoute getMatchingRoute(String path) {
final ZuulRouteEntry matching = trie.get().prefix(path);
if (matching == null
|| !matching.isWildcard() && !matchesExact(path, matching.getPath())) {
return null;
} else {
return matching.getProxyRouteSpec();
return matching.getRoute();
}
}

Expand Down Expand Up @@ -124,7 +124,7 @@ private boolean isWildcard(String path) {
*
* @return the trie instance
*/
private Trie<ProxyRouteSpecEntry> createTrie() {
private Trie<ZuulRouteEntry> createTrie() {
return trieSupplier.createTrie();
}

Expand All @@ -133,7 +133,7 @@ private Trie<ProxyRouteSpecEntry> createTrie() {
*
* @author Jakub Narloch
*/
private static class ProxyRouteSpecEntry {
private static class ZuulRouteEntry {

/**
* The route path.
Expand All @@ -143,23 +143,23 @@ private static class ProxyRouteSpecEntry {
/**
* The route spec.
*/
private final ProxyRouteLocator.ProxyRouteSpec proxyRouteSpec;
private final ZuulProperties.ZuulRoute route;

/**
* Whether the route is a wildcard.
*/
private final boolean wildcard;

/**
* Creates new instance of {@link ProxyRouteSpecEntry}
* Creates new instance of {@link ZuulRouteEntry}
*
* @param path the route path
* @param proxyRouteSpec the route spec
* @param route the zuul route
* @param wildcard whether the route is wildcard
*/
public ProxyRouteSpecEntry(String path, ProxyRouteLocator.ProxyRouteSpec proxyRouteSpec, boolean wildcard) {
public ZuulRouteEntry(String path, ZuulProperties.ZuulRoute route, boolean wildcard) {
this.path = path;
this.proxyRouteSpec = proxyRouteSpec;
this.route = route;
this.wildcard = wildcard;
}

Expand All @@ -177,8 +177,8 @@ public String getPath() {
*
* @return the route spec
*/
public ProxyRouteLocator.ProxyRouteSpec getProxyRouteSpec() {
return proxyRouteSpec;
public ZuulProperties.ZuulRoute getRoute() {
return route;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* A simple implementation of {@link ProxyRouteLocator} that delegates to the {@link RouteMatcher} for retrieving the
* best matching route for specified request path.
Expand Down Expand Up @@ -68,30 +65,21 @@ public MatcherProxyRouteLocator(String servletPath, DiscoveryClient discovery, Z
*/
@Override
public ProxyRouteSpec getMatchingRoute(String path) {
return routeMatcher.getMatchingRoute(path);

if (StringUtils.hasText(this.servletPath) && !this.servletPath.equals("/")
&& path.startsWith(this.servletPath)) {
path = path.substring(this.servletPath.length());
}

return toProxyRouteSpec(path, routeMatcher.getMatchingRoute(path));
}

/**
* {@inheritDoc}
*/
@Override
public void resetRoutes() {
routeMatcher.setRoutes(toProxyRouteSpec(locateRoutes()));
}

/**
* Creates a map of {@link org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator.ProxyRouteSpec} out of
* {@link org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute}.
*
* @param routes the map of routes
* @return the corresponding map of route specs
*/
private Map<String, ProxyRouteSpec> toProxyRouteSpec(Map<String, ZuulProperties.ZuulRoute> routes) {
final Map<String, ProxyRouteSpec> routeSpecs = new LinkedHashMap<String, ProxyRouteSpec>();
for (Map.Entry<String, ZuulProperties.ZuulRoute> route : routes.entrySet()) {
routeSpecs.put(route.getKey(), toProxyRouteSpec(route.getValue()));
}
return routeSpecs;
routeMatcher.setRoutes(locateRoutes());
}

/**
Expand All @@ -101,28 +89,31 @@ private Map<String, ProxyRouteSpec> toProxyRouteSpec(Map<String, ZuulProperties.
* @param route the zuul route
* @return the route spec
*/
private ProxyRouteSpec toProxyRouteSpec(ZuulProperties.ZuulRoute route) {
private ProxyRouteSpec toProxyRouteSpec(final String path, final ZuulProperties.ZuulRoute route) {
if(route == null) {
return null;
}

String path = getRequestPath(route);
String targetPath = getRequestPath(path);
String prefix = properties.getPrefix();
final Boolean retryable = isRetryable(route);

if (properties.isStripPrefix() && path.startsWith(prefix)) {
path = path.substring(prefix.length());
if (properties.isStripPrefix() && targetPath.startsWith(prefix)) {
targetPath = path.substring(prefix.length());
}

if (route.isStripPrefix()) {
int index = route.getPath().indexOf("*") - 1;
if (index > 0) {
String routePrefix = route.getPath().substring(0, index);
path = path.replaceFirst(routePrefix, "");
targetPath = targetPath.replaceFirst(routePrefix, "");
prefix = prefix + routePrefix;
}
}

return new ProxyRouteSpec(
route.getId(),
path,
targetPath,
route.getLocation(),
prefix,
retryable
Expand All @@ -145,11 +136,10 @@ private Boolean isRetryable(ZuulProperties.ZuulRoute route) {
/**
* Retrieves the route path, stripped from the servlet path.
*
* @param route the route path
* @param path the route path
* @return the route request path
*/
private String getRequestPath(ZuulProperties.ZuulRoute route) {
final String path = route.getPath();
private String getRequestPath(String path) {
if (StringUtils.hasText(this.servletPath) && !this.servletPath.equals("/")
&& path.startsWith(this.servletPath)) {
return path.substring(this.servletPath.length());
Expand Down
8 changes: 6 additions & 2 deletions src/test/java/io/jmnarloch/spring/cloud/zuul/Demo.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
* Demonstrates the usage of this component.
Expand All @@ -53,11 +54,14 @@ public void shouldMatchRoute() {
final String path = "/uaa/authorize";

// when
final ProxyRouteLocator.ProxyRouteSpec route = proxyRouteLocator.getMatchingRoute(path);
final ProxyRouteLocator.ProxyRouteSpec route = proxyRouteLocator.getMatchingRoute(path);

// then
assertNotNull(route);
assertEquals("/uaa/**", route.getPath());
assertEquals("oauth2", route.getId());
assertEquals("/uaa/authorize", route.getPath());
assertEquals("oauth2-service", route.getLocation());
assertTrue(route.getPrefix().isEmpty());
}

@EnableZuulProxyMatcher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.jmnarloch.spring.cloud.zuul.trie.Tries;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;

import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -54,7 +54,7 @@ public void shouldNotMatchWildcardRoute() {
final String path = "/accounts/";

// when
final ProxyRouteLocator.ProxyRouteSpec result = instance.getMatchingRoute(path);
final ZuulProperties.ZuulRoute result = instance.getMatchingRoute(path);

// then
assertNull(result);
Expand All @@ -66,7 +66,7 @@ public void shouldMatchWildcardRoute() {
final String path = "/account/details";

// when
final ProxyRouteLocator.ProxyRouteSpec result = instance.getMatchingRoute(path);
final ZuulProperties.ZuulRoute result = instance.getMatchingRoute(path);

// then
assertNotNull(result);
Expand All @@ -78,7 +78,7 @@ public void shouldNotMatchExactRouteWithSuffix() {
final String path = "/uaa/authorize";

// when
final ProxyRouteLocator.ProxyRouteSpec result = instance.getMatchingRoute(path);
final ZuulProperties.ZuulRoute result = instance.getMatchingRoute(path);

// then
assertNull(result);
Expand All @@ -90,7 +90,7 @@ public void shouldMatchExactRoute() {
final String path = "/uaa/";

// when
final ProxyRouteLocator.ProxyRouteSpec result = instance.getMatchingRoute(path);
final ZuulProperties.ZuulRoute result = instance.getMatchingRoute(path);

// then
assertNotNull(result);
Expand All @@ -102,18 +102,18 @@ public void shouldNotMatchExactRoute() {
final String path = "/uaa";

// when
final ProxyRouteLocator.ProxyRouteSpec result = instance.getMatchingRoute(path);
final ZuulProperties.ZuulRoute result = instance.getMatchingRoute(path);

// then
assertNull(result);
}

protected Map<String, ProxyRouteLocator.ProxyRouteSpec> getRoutes() {
protected Map<String, ZuulProperties.ZuulRoute> getRoutes() {

final Map<String, ProxyRouteLocator.ProxyRouteSpec> routes =
new HashMap<String, ProxyRouteLocator.ProxyRouteSpec>();
routes.put("/uaa/", new ProxyRouteLocator.ProxyRouteSpec("uaa", "/uaa", "/uaa", "", null));
routes.put("/account/**", new ProxyRouteLocator.ProxyRouteSpec("account", "/account", "/account", "", null));
final Map<String, ZuulProperties.ZuulRoute> routes =
new HashMap<String, ZuulProperties.ZuulRoute>();
routes.put("/uaa/", new ZuulProperties.ZuulRoute("uaa", "/uaa", "uaa", "/uaa", false, null));
routes.put("/account/**", new ZuulProperties.ZuulRoute("account", "/account", "account", "/account", false, null));
return routes;
}
}

0 comments on commit 5456091

Please sign in to comment.