Commit 8a6cdfa9 by Johannes Edmeier

Update to Spring Cloud Brixton

Deriving from Spring Clouds ProxyRouteLocator has become too difficult. It would have required to either set fixed ZuulProperties or providing a DiscoveryClient. So we are shipping our own lean version of it. Since the PreDecorationFilter is tightly coupled to the ProxyRouteLocator we also have to use our own stripped down version. closes #123
parent 184528cf
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<main.basedir>${basedir}</main.basedir> <main.basedir>${basedir}</main.basedir>
<passphrase>${gpg.passphrase}</passphrase> <passphrase>${gpg.passphrase}</passphrase>
<spring-boot.version>1.3.0.RC1</spring-boot.version> <spring-boot.version>1.3.0.RC1</spring-boot.version>
<spring-cloud.version>Angel.SR3</spring-cloud.version> <spring-cloud.version>Brixton.M2</spring-cloud.version>
<build-plugin.jacoco.version>0.7.5.201505241946</build-plugin.jacoco.version> <build-plugin.jacoco.version>0.7.5.201505241946</build-plugin.jacoco.version>
<build-plugin.coveralls.version>4.0.0</build-plugin.coveralls.version> <build-plugin.coveralls.version>4.0.0</build-plugin.coveralls.version>
<build-plugin.gpg.version>1.6</build-plugin.gpg.version> <build-plugin.gpg.version>1.6</build-plugin.gpg.version>
...@@ -47,6 +47,10 @@ ...@@ -47,6 +47,10 @@
</scm> </scm>
<developers> <developers>
<developer> <developer>
<name>Johannes Edmeier</name>
<email>johannes.edmeier@gmail.com</email>
</developer>
<developer>
<name>Thomas Bosch</name> <name>Thomas Bosch</name>
<email>thomas.bosch@codecentric.de</email> <email>thomas.bosch@codecentric.de</email>
<organization>codecentric AG</organization> <organization>codecentric AG</organization>
......
...@@ -11,8 +11,6 @@ spring: ...@@ -11,8 +11,6 @@ spring:
eureka: eureka:
instance: instance:
leaseRenewalIntervalInSeconds: 5 leaseRenewalIntervalInSeconds: 5
metadataMap:
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
client: client:
serviceUrl: serviceUrl:
defaultZone: http://localhost:8761/eureka/ defaultZone: http://localhost:8761/eureka/
\ No newline at end of file
...@@ -25,11 +25,6 @@ ...@@ -25,11 +25,6 @@
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Use Zuul WITHOUT Hystrix/Ribbon/Config Client --> <!-- Use Zuul WITHOUT Hystrix/Ribbon/Config Client -->
<dependency> <dependency>
<groupId>com.netflix.zuul</groupId> <groupId>com.netflix.zuul</groupId>
...@@ -58,13 +53,12 @@ ...@@ -58,13 +53,12 @@
<groupId>com.hazelcast</groupId> <groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId> <artifactId>hazelcast</artifactId>
<optional>true</optional> <optional>true</optional>
<!-- https://github.com/spring-projects/spring-boot/issues/3418 --> </dependency>
<exclusions> <!-- Optional Configuration Processor for metadata -->
<exclusion> <dependency>
<groupId>org.freemarker</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>freemarker</artifactId> <artifactId>spring-boot-configuration-processor</artifactId>
</exclusion> <optional>true</optional>
</exclusions>
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
......
...@@ -18,21 +18,14 @@ package de.codecentric.boot.admin.config; ...@@ -18,21 +18,14 @@ package de.codecentric.boot.admin.config;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.trace.TraceRepository; import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.RoutesEndpoint;
import org.springframework.cloud.netflix.zuul.ZuulFilterInitializer; import org.springframework.cloud.netflix.zuul.ZuulFilterInitializer;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter; import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter;
import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter; import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter;
import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter; import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter;
import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter; import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter;
import org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter;
import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter; import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter;
import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter;
import org.springframework.cloud.netflix.zuul.web.ZuulController; import org.springframework.cloud.netflix.zuul.web.ZuulController;
...@@ -47,18 +40,15 @@ import de.codecentric.boot.admin.controller.RegistryController; ...@@ -47,18 +40,15 @@ import de.codecentric.boot.admin.controller.RegistryController;
import de.codecentric.boot.admin.event.RoutesOutdatedEvent; import de.codecentric.boot.admin.event.RoutesOutdatedEvent;
import de.codecentric.boot.admin.registry.ApplicationRegistry; import de.codecentric.boot.admin.registry.ApplicationRegistry;
import de.codecentric.boot.admin.zuul.ApplicationRouteLocator; import de.codecentric.boot.admin.zuul.ApplicationRouteLocator;
import de.codecentric.boot.admin.zuul.PreDecorationFilter;
@Configuration @Configuration
@EnableConfigurationProperties(ZuulProperties.class)
public class RevereseZuulProxyConfiguration { public class RevereseZuulProxyConfiguration {
@Autowired(required = false) @Autowired(required = false)
private TraceRepository traces; private TraceRepository traces;
@Autowired @Autowired
private ZuulProperties zuulProperties;
@Autowired
private ServerProperties server; private ServerProperties server;
@Autowired @Autowired
...@@ -67,12 +57,12 @@ public class RevereseZuulProxyConfiguration { ...@@ -67,12 +57,12 @@ public class RevereseZuulProxyConfiguration {
@Bean @Bean
public ApplicationRouteLocator routeLocator() { public ApplicationRouteLocator routeLocator() {
return new ApplicationRouteLocator(this.server.getServletPrefix(), registry, return new ApplicationRouteLocator(this.server.getServletPrefix(), registry,
this.zuulProperties, RegistryController.PATH); RegistryController.PATH);
} }
@Bean @Bean
public PreDecorationFilter preDecorationFilter() { public PreDecorationFilter preDecorationFilter() {
return new PreDecorationFilter(routeLocator(), this.zuulProperties.isAddProxyHeaders()); return new PreDecorationFilter(routeLocator(), true);
} }
@Bean @Bean
...@@ -125,7 +115,6 @@ public class RevereseZuulProxyConfiguration { ...@@ -125,7 +115,6 @@ public class RevereseZuulProxyConfiguration {
@Configuration @Configuration
protected static class ZuulFilterConfiguration { protected static class ZuulFilterConfiguration {
@Autowired @Autowired
private Map<String, ZuulFilter> filters; private Map<String, ZuulFilter> filters;
...@@ -133,7 +122,6 @@ public class RevereseZuulProxyConfiguration { ...@@ -133,7 +122,6 @@ public class RevereseZuulProxyConfiguration {
public ZuulFilterInitializer zuulFilterInitializer() { public ZuulFilterInitializer zuulFilterInitializer() {
return new ZuulFilterInitializer(this.filters); return new ZuulFilterInitializer(this.filters);
} }
} }
@EventListener @EventListener
...@@ -142,18 +130,4 @@ public class RevereseZuulProxyConfiguration { ...@@ -142,18 +130,4 @@ public class RevereseZuulProxyConfiguration {
zuulHandlerMapping().registerHandlers(); zuulHandlerMapping().registerHandlers();
} }
@Configuration
@ConditionalOnClass(Endpoint.class)
protected static class RoutesEndpointConfiguration {
@Autowired
private ProxyRouteLocator routeLocator;
@Bean
public RoutesEndpoint zuulEndpoint() {
return new RoutesEndpoint(this.routeLocator);
}
}
} }
...@@ -69,7 +69,7 @@ public class RegistryController { ...@@ -69,7 +69,7 @@ public class RegistryController {
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.GET)
public Collection<Application> applications( public Collection<Application> applications(
@RequestParam(value = "name", required = false) String name) { @RequestParam(value = "name", required = false) String name) {
LOGGER.debug("Deliver registered applications with name= {}", name); LOGGER.debug("Deliver registered applications with name={}", name);
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
return registry.getApplications(); return registry.getApplications();
} else { } else {
......
...@@ -15,11 +15,19 @@ ...@@ -15,11 +15,19 @@
*/ */
package de.codecentric.boot.admin.zuul; package de.codecentric.boot.admin.zuul;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator; import org.slf4j.Logger;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import de.codecentric.boot.admin.model.Application; import de.codecentric.boot.admin.model.Application;
...@@ -30,31 +38,29 @@ import de.codecentric.boot.admin.registry.ApplicationRegistry; ...@@ -30,31 +38,29 @@ import de.codecentric.boot.admin.registry.ApplicationRegistry;
* *
* @author Johannes Stelzer * @author Johannes Stelzer
*/ */
public class ApplicationRouteLocator extends ProxyRouteLocator { public class ApplicationRouteLocator implements RouteLocator {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRouteLocator.class);
private AtomicReference<Map<String, ZuulRoute>> routes = new AtomicReference<>();
private ApplicationRegistry registry; private ApplicationRegistry registry;
private String prefix; private String prefix;
private PathMatcher pathMatcher = new AntPathMatcher();
private String servletPath;
public ApplicationRouteLocator(String servletPath, ApplicationRegistry registry, public ApplicationRouteLocator(String servletPath, ApplicationRegistry registry,
ZuulProperties properties, String prefix) { String prefix) {
super(servletPath, null, properties); this.servletPath = servletPath;
this.registry = registry; this.registry = registry;
this.prefix = prefix; this.prefix = prefix;
} }
@Override private LinkedHashMap<String, ZuulRoute> locateRoutes() {
protected LinkedHashMap<String, ZuulRoute> locateRoutes() { LinkedHashMap<String, ZuulRoute> locateRoutes = new LinkedHashMap<String, ZuulRoute>();
LinkedHashMap<String, ZuulRoute> locateRoutes = super.locateRoutes(); for (Application application : registry.getApplications()) {
addRoute(locateRoutes, prefix + "/" + application.getId() + "/health/**",
if (registry != null) { application.getHealthUrl());
for (Application application : registry.getApplications()) { if (!StringUtils.isEmpty(application.getManagementUrl())) {
addRoute(locateRoutes, prefix + "/" + application.getId() + "/health/**", addRoute(locateRoutes, prefix + "/" + application.getId() + "/*/**",
application.getHealthUrl()); application.getManagementUrl());
if (!StringUtils.isEmpty(application.getManagementUrl())) {
addRoute(locateRoutes, prefix + "/" + application.getId() + "/*/**",
application.getManagementUrl());
}
} }
} }
...@@ -65,4 +71,80 @@ public class ApplicationRouteLocator extends ProxyRouteLocator { ...@@ -65,4 +71,80 @@ public class ApplicationRouteLocator extends ProxyRouteLocator {
locateRoutes.put(path, new ZuulRoute(path, url)); locateRoutes.put(path, new ZuulRoute(path, url));
} }
public ProxyRouteSpec getMatchingRoute(String path) {
LOGGER.info("Finding route for path: {}; servletPath={}", path, this.servletPath);
if (StringUtils.hasText(this.servletPath) && !this.servletPath.equals("/")
&& path.startsWith(this.servletPath)) {
path = path.substring(this.servletPath.length());
}
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
String pattern = entry.getKey();
LOGGER.debug("Matching pattern: {}", pattern);
if (this.pathMatcher.match(pattern, path)) {
ZuulRoute route = entry.getValue();
int index = route.getPath().indexOf("*") - 1;
String routePrefix = route.getPath().substring(0, index);
String targetPath = path.replaceFirst(routePrefix, "");
return new ProxyRouteSpec(route.getId(), targetPath, route.getLocation(),
routePrefix);
}
}
return null;
}
@Override
public Collection<String> getRoutePaths() {
return getRoutes().keySet();
}
public void resetRoutes() {
this.routes.set(locateRoutes());
}
public Map<String, String> getRoutes() {
if (this.routes.get() == null) {
this.routes.set(locateRoutes());
}
Map<String, String> values = new LinkedHashMap<>();
for (String key : this.routes.get().keySet()) {
String url = key;
values.put(url, this.routes.get().get(key).getLocation());
}
return values;
}
@Override
public Collection<String> getIgnoredPaths() {
return Collections.emptyList();
}
public static class ProxyRouteSpec {
private final String id;
private final String path;
private final String location;
private final String prefix;
public ProxyRouteSpec(String id, String path, String location, String prefix) {
this.id = id;
this.path = path;
this.location = location;
this.prefix = prefix;
}
public String getId() {
return id;
}
public String getPath() {
return path;
}
public String getLocation() {
return location;
}
public String getPrefix() {
return prefix;
}
}
} }
/*
* Copyright 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 de.codecentric.boot.admin.zuul;
import java.net.MalformedURLException;
import java.net.URL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UrlPathHelper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulHeaders;
import com.netflix.zuul.context.RequestContext;
import de.codecentric.boot.admin.zuul.ApplicationRouteLocator.ProxyRouteSpec;
/**
* @author Johannes Edmeier
*/
public class PreDecorationFilter extends ZuulFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(PreDecorationFilter.class);
private ApplicationRouteLocator routeLocator;
private boolean addProxyHeaders;
private UrlPathHelper urlPathHelper = new UrlPathHelper();
public PreDecorationFilter(ApplicationRouteLocator routeLocator, boolean addProxyHeaders) {
this.routeLocator = routeLocator;
this.addProxyHeaders = addProxyHeaders;
}
@Override
public int filterOrder() {
return 5;
}
@Override
public String filterType() {
return "pre";
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
final String requestURI = this.urlPathHelper.getPathWithinApplication(ctx.getRequest());
ProxyRouteSpec route = this.routeLocator.getMatchingRoute(requestURI);
if (route != null) {
ctx.put("requestURI", route.getPath());
ctx.put("proxy", route.getId());
ctx.setRouteHost(getUrl(route.getLocation()));
ctx.addOriginResponseHeader("X-Zuul-Service", route.getLocation());
if (this.addProxyHeaders) {
ctx.addZuulRequestHeader("X-Forwarded-Host", ctx.getRequest().getServerName() + ":"
+ String.valueOf(ctx.getRequest().getServerPort()));
ctx.addZuulRequestHeader(ZuulHeaders.X_FORWARDED_PROTO,
ctx.getRequest().getScheme());
if (StringUtils.hasText(route.getPrefix())) {
ctx.addZuulRequestHeader("X-Forwarded-Prefix", route.getPrefix());
}
}
} else {
LOGGER.warn("No route found for uri: " + requestURI);
ctx.set("forward.to", requestURI);
}
return null;
}
private URL getUrl(String target) {
try {
return new URL(target);
} catch (MalformedURLException ex) {
throw new IllegalStateException("Target URL is malformed", ex);
}
}
}
...@@ -52,8 +52,8 @@ public class AdminApplicationTest { ...@@ -52,8 +52,8 @@ public class AdminApplicationTest {
@Test @Test
public void testGetApplications() { public void testGetApplications() {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
ResponseEntity<List> entity = new TestRestTemplate().getForEntity("http://localhost:" ResponseEntity<List> entity = new TestRestTemplate()
+ port + "/api/applications", List.class); .getForEntity("http://localhost:" + port + "/api/applications", List.class);
assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals(HttpStatus.OK, entity.getStatusCode());
} }
...@@ -68,13 +68,19 @@ public class AdminApplicationTest { ...@@ -68,13 +68,19 @@ public class AdminApplicationTest {
application, Application.class); application, Application.class);
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
ResponseEntity<Map> info = new TestRestTemplate().getForEntity(apiBaseUrl + "/" ResponseEntity<Map> app = new TestRestTemplate()
+ entity.getBody().getId() + "/info", Map.class); .getForEntity(apiBaseUrl + "/" + entity.getBody().getId(), Map.class);
assertEquals(HttpStatus.OK, app.getStatusCode());
assertEquals("TestApp", app.getBody().get("name"));
@SuppressWarnings("rawtypes")
ResponseEntity<Map> info = new TestRestTemplate()
.getForEntity(apiBaseUrl + "/" + entity.getBody().getId() + "/info", Map.class);
assertEquals(HttpStatus.OK, info.getStatusCode()); assertEquals(HttpStatus.OK, info.getStatusCode());
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
ResponseEntity<Map> health = new TestRestTemplate().getForEntity(apiBaseUrl + "/" ResponseEntity<Map> health = new TestRestTemplate()
+ entity.getBody().getId() + "/health", Map.class); .getForEntity(apiBaseUrl + "/" + entity.getBody().getId() + "/health", Map.class);
assertEquals(HttpStatus.OK, health.getStatusCode()); assertEquals(HttpStatus.OK, health.getStatusCode());
} }
......
...@@ -15,21 +15,20 @@ ...@@ -15,21 +15,20 @@
*/ */
package de.codecentric.boot.admin.zuul; package de.codecentric.boot.admin.zuul;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.hasItems;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.util.Collections;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import de.codecentric.boot.admin.model.Application; import de.codecentric.boot.admin.model.Application;
import de.codecentric.boot.admin.registry.ApplicationRegistry; import de.codecentric.boot.admin.registry.ApplicationRegistry;
import de.codecentric.boot.admin.zuul.ApplicationRouteLocator.ProxyRouteSpec;
public class ApplicationRouteLocatorTest { public class ApplicationRouteLocatorTest {
...@@ -39,34 +38,32 @@ public class ApplicationRouteLocatorTest { ...@@ -39,34 +38,32 @@ public class ApplicationRouteLocatorTest {
@Before @Before
public void setup() { public void setup() {
registry = mock(ApplicationRegistry.class); registry = mock(ApplicationRegistry.class);
locator = new ApplicationRouteLocator("/", registry, new ZuulProperties(), locator = new ApplicationRouteLocator("/", registry, "/api/applications");
"/api/applications");
} }
@Test @Test
public void locateRoutes_healthOnly() { public void locateRoutes_healthOnly() {
when(registry.getApplications()).thenReturn( when(registry.getApplications()).thenReturn(singletonList(Application.create("app1")
Collections.singletonList(Application.create("app1") .withHealthUrl("http://localhost/health").withId("1234").build()));
.withHealthUrl("http://localhost/health").withId("1234").build()));
locator.resetRoutes(); locator.resetRoutes();
assertEquals(1, locator.getRoutes().size()); assertEquals(1, locator.getRoutes().size());
assertEquals(Collections.singleton("/api/applications/1234/health/**"), assertEquals(singleton("/api/applications/1234/health/**"), locator.getRoutePaths());
locator.getRoutePaths());
assertEquals("http://localhost/health", assertEquals("http://localhost/health",
locator.getRoutes().get("/api/applications/1234/health/**")); locator.getRoutes().get("/api/applications/1234/health/**"));
assertEquals(new ProxyRouteLocator.ProxyRouteSpec("api/applications/1234/health", "", ProxyRouteSpec route = locator.getMatchingRoute("/api/applications/1234/health");
"http://localhost/health", "/api/applications/1234/health", null), assertEquals("api/applications/1234/health", route.getId());
locator.getMatchingRoute("/api/applications/1234/health")); assertEquals("", route.getPath());
assertEquals("http://localhost/health", route.getLocation());
assertEquals("/api/applications/1234/health", route.getPrefix());
} }
@Test @Test
public void locateRoutes() { public void locateRoutes() {
when(registry.getApplications()).thenReturn( when(registry.getApplications()).thenReturn(
Collections.singletonList(Application.create("app1") singletonList(Application.create("app1").withHealthUrl("http://localhost/health")
.withHealthUrl("http://localhost/health")
.withManagementUrl("http://localhost").withId("1234").build())); .withManagementUrl("http://localhost").withId("1234").build()));
locator.resetRoutes(); locator.resetRoutes();
...@@ -78,14 +75,16 @@ public class ApplicationRouteLocatorTest { ...@@ -78,14 +75,16 @@ public class ApplicationRouteLocatorTest {
assertEquals("http://localhost/health", assertEquals("http://localhost/health",
locator.getRoutes().get("/api/applications/1234/health/**")); locator.getRoutes().get("/api/applications/1234/health/**"));
assertEquals(new ProxyRouteLocator.ProxyRouteSpec("api/applications/1234/health", "", ProxyRouteSpec route = locator.getMatchingRoute("/api/applications/1234/health");
"http://localhost/health", "/api/applications/1234/health", null), assertEquals("api/applications/1234/health", route.getId());
locator.getMatchingRoute("/api/applications/1234/health")); assertEquals("", route.getPath());
assertEquals("http://localhost/health", route.getLocation());
assertEquals("http://localhost", locator.getRoutes().get("/api/applications/1234/*/**")); assertEquals("/api/applications/1234/health", route.getPrefix());
assertEquals(new ProxyRouteLocator.ProxyRouteSpec("api/applications/1234", "/*/**",
"http://localhost", "/api/applications/1234", null), route = locator.getMatchingRoute("/api/applications/1234/notify");
locator.getMatchingRoute("/api/applications/1234/*/**")); assertEquals("api/applications/1234", route.getId());
assertEquals("/notify", route.getPath());
assertEquals("http://localhost", route.getLocation());
assertEquals("/api/applications/1234", route.getPrefix());
} }
} }
/*
* Copyright 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 de.codecentric.boot.admin.zuul;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import com.netflix.zuul.context.RequestContext;
import de.codecentric.boot.admin.model.Application;
import de.codecentric.boot.admin.registry.ApplicationRegistry;
import de.codecentric.boot.admin.registry.HashingApplicationUrlIdGenerator;
import de.codecentric.boot.admin.registry.store.ApplicationStore;
import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
public class PreDecorationFilterTest {
private PreDecorationFilter filter;
private ApplicationRouteLocator routeLocator;
private MockHttpServletRequest request = new MockHttpServletRequest();
private ApplicationRegistry registry;
private ApplicationStore store;
@Before
public void init() {
store = new SimpleApplicationStore();
store.save(Application.create("test").withId("-id-").withHealthUrl("http://test/health")
.withManagementUrl("http://mgmt").build());
registry = new ApplicationRegistry(store, new HashingApplicationUrlIdGenerator());
routeLocator = new ApplicationRouteLocator("/", registry, "/proxied");
routeLocator.resetRoutes();
filter = new PreDecorationFilter(routeLocator, true);
RequestContext ctx = RequestContext.getCurrentContext();
ctx.clear();
ctx.setRequest(request);
}
@Test
public void basicProperties() throws Exception {
assertEquals(5, this.filter.filterOrder());
assertEquals(true, this.filter.shouldFilter());
assertEquals("pre", this.filter.filterType());
}
@Test
public void prefixRouteAddsHeader() throws Exception {
request.setRequestURI("/proxied/-id-/foo");
filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("/foo", ctx.get("requestURI"));
assertEquals("http://mgmt", ctx.getRouteHost().toString());
assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
assertEquals("/proxied/-id-", ctx.getZuulRequestHeaders().get("x-forwarded-prefix"));
}
}
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