Commit 2cdcd767 by Dave Syer

Move some of the routing logic into the route locator

We now support prefix stripping per service, e.g. zuul: routes: customers: path: /customers/** stripPrefix: true Will route /customers/101 -> /101 (on the customers service) See gh-77
parent 34f277b8
......@@ -551,7 +551,19 @@ The location of the backend can be specified as either a "serviceId"
Forwarding to the service is protected by a Hystrix circuit breaker so if a service is down the client will see an error, but once the circuit is open the proxy will not try to contact the service.
To add a prefix to the mapping, set `zuul.prefix` to a value, such as `/api`. To strip the proxy prefix from the request before the request is forwarded set `zuul.stripPrefix = true`.
To add a prefix to all mappings, set `zuul.prefix` to a value, such as `/api`. To strip the proxy prefix from the request before the request is forwarded set `zuul.stripPrefix = true`. You can also strip the non-wildcard prefix from individual routes, e.g.
.application.yml
[source,yaml]
----
zuul:
routes:
users:
path: /myusers/**
stripPrefix: true
----
In this example requests to "/myusers/101" will be forwarded to "/101" on the "users" service (the path is stripped up to the first wildcard character).
The `X-Forwarded-Host` header added to the forwarded requests by default. To turn it off set `zuul.addProxyHeaders = false`.
......
package org.springframework.cloud.netflix.zuul;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.netflix.zuul.ZuulProperties.ZuulRoute;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* @author Spencer Gibb
*/
@Slf4j
public class ProxyRouteLocator implements ApplicationListener<EnvironmentChangeEvent> {
public static final String DEFAULT_ROUTE = "/";
private DiscoveryClient discovery;
private ZuulProperties properties;
private PathMatcher pathMatcher = new AntPathMatcher();
private Field propertySourcesField;
private AtomicReference<Map<String, ZuulRoute>> routes = new AtomicReference<>();
private Map<String, String> staticRoutes = new LinkedHashMap<String, String>();
public ProxyRouteLocator(DiscoveryClient discovery, ZuulProperties properties) {
this.discovery = discovery;
this.properties = properties;
initField();
}
private void initField() {
propertySourcesField = ReflectionUtils.findField(CompositePropertySource.class,
"propertySources");
propertySourcesField.setAccessible(true);
}
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
for (String key : event.getKeys()) {
if (key.startsWith("zuul.routes")) {
resetRoutes();
return;
}
}
}
public void addRoute(String path, String location) {
staticRoutes.put(path, location);
resetRoutes();
}
public Collection<String> getRoutePaths() {
return getRoutes().keySet();
}
public Map<String, String> getRoutes() {
if (routes.get() == null) {
routes.set(locateRoutes());
}
Map<String, String> values = new LinkedHashMap<String, String>();
for (String key : routes.get().keySet()) {
String url = key;
values.put(url, routes.get().get(key).getLocation());
}
return values;
}
public ProxyRouteSpec getMatchingRoute(String path) {
String location = null;
String targetPath = null;
for (Entry<String, ZuulRoute> entry : routes.get().entrySet()) {
String pattern = entry.getKey();
if (pathMatcher.match(pattern, path)) {
ZuulRoute route = entry.getValue();
String prefix = properties.getPrefix();
location = route.getLocation();
targetPath = path;
if (path.startsWith(prefix) && properties.isStripPrefix()) {
targetPath = path.substring(prefix.length());
}
if (route.isStripPrefix()) {
int index = route.getPath().indexOf("*");
index = index > 0 ? index-1 : 0;
targetPath = path.substring(index);
}
}
}
return location==null ? null : new ProxyRouteSpec(targetPath, location);
}
// Package access so ZuulHandlerMapping can reset it's mappings
void resetRoutes() {
routes.set(locateRoutes());
}
protected LinkedHashMap<String, ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
addConfiguredRoutes(routesMap);
addStaticRoutes(routesMap);
// Add routes for discovery services by default
List<String> services = discovery.getServices();
for (String serviceId : services) {
// Ignore specifically ignored services and those that were manually
// configured
String key = "/" + serviceId + "/**";
if (!properties.getIgnoredServices().contains(serviceId)
&& !routesMap.containsKey(key)) {
routesMap.put(key, new ZuulRoute(key, serviceId));
}
}
if (routesMap.get(DEFAULT_ROUTE) != null) {
String defaultServiceId = routesMap.get(DEFAULT_ROUTE).getServiceId();
// Move the defaultServiceId to the end
routesMap.remove(DEFAULT_ROUTE);
routesMap.put(DEFAULT_ROUTE, new ZuulRoute(defaultServiceId));
}
LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();
for (Entry<String, ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
// Prepend with slash if not already present.
if (!path.startsWith("/")) {
path = "/" + path;
}
if (StringUtils.hasText(properties.getPrefix())) {
path = properties.getPrefix() + path;
if (!path.startsWith("/")) {
path = "/" + path;
}
}
values.put(path, entry.getValue());
}
return values;
}
protected void addStaticRoutes(LinkedHashMap<String, ZuulRoute> routes) {
for (Entry<String, String> entry : staticRoutes.entrySet()) {
routes.put(entry.getKey(), new ZuulRoute(entry.getKey(), entry.getValue()));
}
}
protected void addConfiguredRoutes(Map<String, ZuulRoute> routes) {
Map<String, ZuulRoute> routeEntries = properties.getRoutesWithDefaultServiceIds();
for (ZuulRoute entry : routeEntries.values()) {
String route = entry.getPath();
if (routes.containsKey(route)) {
log.warn("Overwriting route {}: already defined by {}", route,
routes.get(route));
}
routes.put(route, entry);
}
}
public String getTargetPath(String matchingRoute, String requestURI) {
String path = getRoutes().get(matchingRoute);
if (path==null) {
path = requestURI;
} else {
}
return path;
}
@Data
@AllArgsConstructor
public static class ProxyRouteSpec {
private String path;
private String location;
}
}
......@@ -40,8 +40,8 @@ public class ZuulConfiguration {
private ZuulProperties zuulProperties;
@Bean
public ZuulRouteLocator routes() {
return new ZuulRouteLocator(discovery, zuulProperties);
public ProxyRouteLocator routes() {
return new ProxyRouteLocator(discovery, zuulProperties);
}
@Bean
......@@ -51,7 +51,7 @@ public class ZuulConfiguration {
@Bean
public ZuulHandlerMapping zuulHandlerMapping() {
return new ZuulHandlerMapping(routes(), zuulController(), zuulProperties);
return new ZuulHandlerMapping(routes(), zuulController());
}
@Configuration
......
......@@ -11,7 +11,6 @@ import org.springframework.context.ApplicationListener;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
......@@ -27,24 +26,20 @@ import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
public class ZuulHandlerMapping extends AbstractUrlHandlerMapping implements
ApplicationListener<InstanceRegisteredEvent>, MvcEndpoint {
private ZuulRouteLocator routeLocator;
private ProxyRouteLocator routeLocator;
private ZuulController zuul;
private ZuulProperties properties;
@Autowired
public ZuulHandlerMapping(ZuulRouteLocator routeLocator, ZuulController zuul,
ZuulProperties properties) {
public ZuulHandlerMapping(ProxyRouteLocator routeLocator, ZuulController zuul) {
this.routeLocator = routeLocator;
this.zuul = zuul;
this.properties = properties;
setOrder(-200);
}
@Override
public void onApplicationEvent(InstanceRegisteredEvent event) {
registerHandlers(routeLocator.getRoutes().keySet());
registerHandlers(routeLocator.getRoutePaths());
}
protected void registerHandlers(Collection<String> routes) {
......@@ -53,18 +48,6 @@ public class ZuulHandlerMapping extends AbstractUrlHandlerMapping implements
}
else {
for (String url : routes) {
// Prepend with slash if not already present.
if (!url.startsWith("/")) {
url = "/" + url;
}
if (StringUtils.hasText(properties.getPrefix())) {
url = properties.getPrefix() + url;
if (!url.startsWith("/")) {
url = "/" + url;
}
}
registerHandler(url, zuul);
}
}
......@@ -75,7 +58,7 @@ public class ZuulHandlerMapping extends AbstractUrlHandlerMapping implements
@ManagedOperation
public Map<String, String> reset() {
routeLocator.resetRoutes();
registerHandlers(routeLocator.getRoutes().keySet());
registerHandlers(routeLocator.getRoutePaths());
return getRoutes();
}
......
......@@ -43,7 +43,7 @@ public class ZuulProperties {
private String path;
private String serviceId;
private String url;
private boolean stripPath = false;
private boolean stripPrefix = false;
public ZuulRoute(String text) {
String location = null;
......
package org.springframework.cloud.netflix.zuul;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.netflix.zuul.ZuulProperties.ZuulRoute;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.util.ReflectionUtils;
/**
* @author Spencer Gibb
*/
@Slf4j
public class ZuulRouteLocator implements ApplicationListener<EnvironmentChangeEvent> {
public static final String DEFAULT_ROUTE = "/";
private DiscoveryClient discovery;
private ZuulProperties properties;
private Field propertySourcesField;
private AtomicReference<LinkedHashMap<String, String>> routes = new AtomicReference<>();
public ZuulRouteLocator(DiscoveryClient discovery, ZuulProperties properties) {
this.discovery = discovery;
this.properties = properties;
initField();
}
private void initField() {
propertySourcesField = ReflectionUtils.findField(CompositePropertySource.class,
"propertySources");
propertySourcesField.setAccessible(true);
}
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
for (String key : event.getKeys()) {
if (key.startsWith("zuul.route")) {
resetRoutes();
return;
}
}
}
public Collection<String> getRoutePaths() {
return getRoutes().keySet();
}
public Map<String, String> getRoutes() {
if (routes.get() == null) {
resetRoutes();
}
return routes.get();
}
//access so ZuulHandlerMapping actuator can reset it's mappings
/*package*/ void resetRoutes() {
LinkedHashMap<String, String> newValue = locateRoutes();
routes.set(newValue);
}
protected LinkedHashMap<String, String> locateRoutes() {
LinkedHashMap<String, String> routesMap = new LinkedHashMap<>();
addConfiguredRoutes(routesMap);
String defaultServiceId = routesMap.get(DEFAULT_ROUTE);
// Add routes for discovery services by default
List<String> services = discovery.getServices();
for (String serviceId : services) {
// Ignore specifically ignored services and those that were manually configured
String key = "/" + serviceId + "/**";
if (!properties.getIgnoredServices().contains(serviceId) && !routesMap.containsKey(key)) {
routesMap.put(key, serviceId);
}
}
if (defaultServiceId != null) {
// move the defaultServiceId to the end
routesMap.remove(DEFAULT_ROUTE);
routesMap.put(DEFAULT_ROUTE, defaultServiceId);
}
return routesMap;
}
protected void addConfiguredRoutes(Map<String, String> routes) {
Map<String, ZuulRoute> routeEntries = properties.getRoutesWithDefaultServiceIds();
for (ZuulRoute entry : routeEntries.values()) {
String location = entry.getLocation();
String route = entry.getPath();
if (routes.containsKey(route)) {
log.warn("Overwriting route {}: already defined by {}", route,
routes.get(route));
}
routes.put(route, location);
}
}
}
package org.springframework.cloud.netflix.zuul.filters.pre;
import static com.google.common.collect.Iterables.tryFind;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.ZuulRouteLocator;
import org.springframework.cloud.netflix.zuul.ProxyRouteLocator;
import org.springframework.cloud.netflix.zuul.ProxyRouteLocator.ProxyRouteSpec;
import org.springframework.cloud.netflix.zuul.ZuulProperties;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
public class PreDecorationFilter extends ZuulFilter {
private static Logger LOG = LoggerFactory.getLogger(PreDecorationFilter.class);
private ZuulRouteLocator routeLocator;
private ProxyRouteLocator routeLocator;
private ZuulProperties properties;
private PathMatcher pathMatcher = new AntPathMatcher();
public PreDecorationFilter(ZuulRouteLocator routeLocator, ZuulProperties properties) {
public PreDecorationFilter(ProxyRouteLocator routeLocator, ZuulProperties properties) {
this.routeLocator = routeLocator;
this.properties = properties;
}
......@@ -55,44 +45,27 @@ public class PreDecorationFilter extends ZuulFilter {
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
String requestURI = ctx.getRequest().getRequestURI();
final String requestURI = ctx.getRequest().getRequestURI();
String proxyMapping = properties.getPrefix();
ProxyRouteSpec route = routeLocator.getMatchingRoute(requestURI);
final String uriPart;
if (StringUtils.hasText(proxyMapping) && properties.isStripPrefix()
&& requestURI.startsWith(proxyMapping)) {
// TODO: better strategy?
uriPart = requestURI.substring(proxyMapping.length());
}
else {
uriPart = requestURI;
}
ctx.put("requestURI", uriPart);
Map<String, String> routesMap = routeLocator.getRoutes();
if (route!=null) {
Optional<String> route = tryFind(routesMap.keySet(), new Predicate<String>() {
@Override
public boolean apply(@Nullable String path) {
return pathMatcher.match(path, uriPart);
}
});
String location = route.getLocation();
if (route.isPresent()) {
String target = routesMap.get(route.get());
if (location != null) {
if (target != null) {
ctx.put("requestURI", route.getPath());
if (target.startsWith("http:") || target.startsWith("https:")) {
ctx.setRouteHost(getUrl(target));
ctx.addOriginResponseHeader("X-Zuul-Service", target);
if (location.startsWith("http:") || location.startsWith("https:")) {
ctx.setRouteHost(getUrl(location));
ctx.addOriginResponseHeader("X-Zuul-Service", location);
}
else {
// set serviceId for use in filters.route.RibbonRequest
ctx.set("serviceId", target);
ctx.set("serviceId", location);
ctx.setRouteHost(null);
ctx.addOriginResponseHeader("X-Zuul-ServiceId", target);
ctx.addOriginResponseHeader("X-Zuul-ServiceId", location);
}
if (properties.isAddProxyHeaders()) {
......
package org.springframework.cloud.netflix.zuul;
package org.springframework.cloud.netflix.zuul.filters.route;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
......
......@@ -19,7 +19,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessor;
import org.springframework.cloud.netflix.zuul.RibbonCommand;
import org.springframework.cloud.netflix.zuul.SpringFilter;
import org.springframework.util.StringUtils;
......
......@@ -13,6 +13,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.zuul.ProxyRouteLocator.ProxyRouteSpec;
import org.springframework.cloud.netflix.zuul.ZuulProperties.ZuulRoute;
import org.springframework.core.env.ConfigurableEnvironment;
......@@ -22,7 +23,7 @@ import com.google.common.collect.Lists;
* @author Spencer Gibb
* @author Dave Syer
*/
public class ZuulRouteLocatorTests {
public class ProxyRouteLocatorTests {
public static final String IGNOREDSERVICE = "ignoredservice";
public static final String ASERVICE = "aservice";
......@@ -34,16 +35,61 @@ public class ZuulRouteLocatorTests {
@Mock
DiscoveryClient discovery;
private ZuulProperties properties = new ZuulProperties();
@Before
public void init() {
initMocks(this);
}
@Test
public void testGetMatchingPath() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1");
assertEquals("foo", route.getLocation());
}
@Test
public void testGetMatchingPathWithPrefix() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
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 testGetMatchingPathWithPrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
this.properties.setStripPrefix(true);
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 testGetMatchingPathWithRoutePrefixStripping() throws Exception {
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
ZuulRoute zuulRoute = new ZuulRoute("/foo/**");
zuulRoute.setStripPrefix(true);
this.properties.getRoutes().put("foo", zuulRoute);
routeLocator.getRoutes(); // force refresh
ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1");
assertEquals("foo", route.getLocation());
assertEquals("/1", route.getPath());
}
@Test
public void testGetRoutes() {
ZuulProperties properties = new ZuulProperties();
ZuulRouteLocator routeLocator = new ZuulRouteLocator(this.discovery, properties);
properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**"));
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**"));
Map<String, String> routesMap = routeLocator.getRoutes();
......@@ -54,24 +100,18 @@ public class ZuulRouteLocatorTests {
@Test
public void testGetRoutesWithMapping() {
ZuulProperties properties = new ZuulProperties();
ZuulRouteLocator routeLocator = new ZuulRouteLocator(this.discovery, properties);
properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", ASERVICE));
// Prefix doesn't have any impact on the routes (it's used in the filter)
properties.setPrefix("/foo");
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", ASERVICE));
this.properties.setPrefix("/foo");
Map<String, String> routesMap = routeLocator.getRoutes();
assertNotNull("routesMap was null", routesMap);
assertFalse("routesMap was empty", routesMap.isEmpty());
assertMapping(routesMap, ASERVICE);
assertMapping(routesMap, ASERVICE, "foo/" + ASERVICE);
}
@Test
public void testGetPhysicalRoutes() {
ZuulProperties properties = new ZuulProperties();
ZuulRouteLocator routeLocator = new ZuulRouteLocator(this.discovery, properties);
properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", "http://" + ASERVICE));
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", "http://" + ASERVICE));
Map<String, String> routesMap = routeLocator.getRoutes();
......@@ -82,9 +122,8 @@ public class ZuulRouteLocatorTests {
@Test
public void testIgnoreRoutes() {
ZuulProperties properties = new ZuulProperties();
ZuulRouteLocator routeLocator = new ZuulRouteLocator(this.discovery, properties);
properties.setIgnoredServices(Lists.newArrayList(IGNOREDSERVICE));
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
this.properties.setIgnoredServices(Lists.newArrayList(IGNOREDSERVICE));
when(discovery.getServices()).thenReturn(
Lists.newArrayList(IGNOREDSERVICE));
......@@ -96,8 +135,7 @@ public class ZuulRouteLocatorTests {
@Test
public void testAutoRoutes() {
ZuulProperties properties = new ZuulProperties();
ZuulRouteLocator routeLocator = new ZuulRouteLocator(this.discovery, properties);
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
when(discovery.getServices()).thenReturn(
Lists.newArrayList(MYSERVICE));
......@@ -111,9 +149,8 @@ public class ZuulRouteLocatorTests {
@Test
public void testAutoRoutesCanBeOverridden() {
ZuulProperties properties = new ZuulProperties();
properties.getRoutes().put(MYSERVICE, new ZuulRoute("/"+MYSERVICE + "/**", "http://example.com/" + MYSERVICE));
ZuulRouteLocator routeLocator = new ZuulRouteLocator(this.discovery, properties);
this.properties.getRoutes().put(MYSERVICE, new ZuulRoute("/"+MYSERVICE + "/**", "http://example.com/" + MYSERVICE));
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
when(discovery.getServices()).thenReturn(
Lists.newArrayList(MYSERVICE));
......
......@@ -28,13 +28,13 @@ public class SampleZuulProxyApplicationTests {
private int port;
@Autowired
private ZuulRouteLocator routes;
private ProxyRouteLocator routes;
@Autowired
private ZuulHandlerMapping mapping;
@Test
public void bindRouteUsingPropertyEditor() {
public void bindRouteUsingPhysicalRoute() {
assertEquals("http://localhost:7777/local", routes.getRoutes().get("/test/**"));
}
......@@ -45,8 +45,8 @@ public class SampleZuulProxyApplicationTests {
@Test
public void deleteOnSelfViaSimpleHostRoutingFilter() {
routes.getRoutes().put("/self/**", "http://localhost:" + port + "/local");
mapping.registerHandlers(routes.getRoutes().keySet());
routes.addRoute("/self/**", "http://localhost:" + port + "/local");
mapping.reset();
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + port + "/self/1", HttpMethod.DELETE,
new HttpEntity<Void>((Void) null), String.class);
......
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