Skip to content
This repository was archived by the owner on Jun 29, 2018. It is now read-only.

Commit 8a6cdfa

Browse files
committed
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
1 parent 184528c commit 8a6cdfa

10 files changed

Lines changed: 323 additions & 95 deletions

File tree

pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<main.basedir>${basedir}</main.basedir>
2020
<passphrase>${gpg.passphrase}</passphrase>
2121
<spring-boot.version>1.3.0.RC1</spring-boot.version>
22-
<spring-cloud.version>Angel.SR3</spring-cloud.version>
22+
<spring-cloud.version>Brixton.M2</spring-cloud.version>
2323
<build-plugin.jacoco.version>0.7.5.201505241946</build-plugin.jacoco.version>
2424
<build-plugin.coveralls.version>4.0.0</build-plugin.coveralls.version>
2525
<build-plugin.gpg.version>1.6</build-plugin.gpg.version>
@@ -46,6 +46,10 @@
4646
<url>https://github.com/codecentric/spring-boot-admin</url>
4747
</scm>
4848
<developers>
49+
<developer>
50+
<name>Johannes Edmeier</name>
51+
<email>johannes.edmeier@gmail.com</email>
52+
</developer>
4953
<developer>
5054
<name>Thomas Bosch</name>
5155
<email>thomas.bosch@codecentric.de</email>

spring-boot-admin-samples/spring-boot-admin-sample-discovery/src/main/resources/application.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ spring:
1111
eureka:
1212
instance:
1313
leaseRenewalIntervalInSeconds: 5
14-
metadataMap:
15-
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
1614
client:
1715
serviceUrl:
1816
defaultZone: http://localhost:8761/eureka/

spring-boot-admin-server/pom.xml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@
2525
<groupId>com.fasterxml.jackson.core</groupId>
2626
<artifactId>jackson-databind</artifactId>
2727
</dependency>
28-
<dependency>
29-
<groupId>org.springframework.boot</groupId>
30-
<artifactId>spring-boot-configuration-processor</artifactId>
31-
<optional>true</optional>
32-
</dependency>
3328
<!-- Use Zuul WITHOUT Hystrix/Ribbon/Config Client -->
3429
<dependency>
3530
<groupId>com.netflix.zuul</groupId>
@@ -58,13 +53,12 @@
5853
<groupId>com.hazelcast</groupId>
5954
<artifactId>hazelcast</artifactId>
6055
<optional>true</optional>
61-
<!-- https://github.com/spring-projects/spring-boot/issues/3418 -->
62-
<exclusions>
63-
<exclusion>
64-
<groupId>org.freemarker</groupId>
65-
<artifactId>freemarker</artifactId>
66-
</exclusion>
67-
</exclusions>
56+
</dependency>
57+
<!-- Optional Configuration Processor for metadata -->
58+
<dependency>
59+
<groupId>org.springframework.boot</groupId>
60+
<artifactId>spring-boot-configuration-processor</artifactId>
61+
<optional>true</optional>
6862
</dependency>
6963
<!-- Test -->
7064
<dependency>

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/config/RevereseZuulProxyConfiguration.java

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,14 @@
1818
import java.util.Map;
1919

2020
import org.springframework.beans.factory.annotation.Autowired;
21-
import org.springframework.boot.actuate.endpoint.Endpoint;
2221
import org.springframework.boot.actuate.trace.TraceRepository;
23-
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2422
import org.springframework.boot.autoconfigure.web.ServerProperties;
25-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
26-
import org.springframework.cloud.netflix.zuul.RoutesEndpoint;
2723
import org.springframework.cloud.netflix.zuul.ZuulFilterInitializer;
2824
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
29-
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
30-
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
3125
import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter;
3226
import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter;
3327
import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter;
3428
import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter;
35-
import org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter;
3629
import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter;
3730
import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter;
3831
import org.springframework.cloud.netflix.zuul.web.ZuulController;
@@ -47,17 +40,14 @@
4740
import de.codecentric.boot.admin.event.RoutesOutdatedEvent;
4841
import de.codecentric.boot.admin.registry.ApplicationRegistry;
4942
import de.codecentric.boot.admin.zuul.ApplicationRouteLocator;
43+
import de.codecentric.boot.admin.zuul.PreDecorationFilter;
5044

5145
@Configuration
52-
@EnableConfigurationProperties(ZuulProperties.class)
5346
public class RevereseZuulProxyConfiguration {
5447

5548
@Autowired(required = false)
5649
private TraceRepository traces;
5750

58-
@Autowired
59-
private ZuulProperties zuulProperties;
60-
6151
@Autowired
6252
private ServerProperties server;
6353

@@ -67,12 +57,12 @@ public class RevereseZuulProxyConfiguration {
6757
@Bean
6858
public ApplicationRouteLocator routeLocator() {
6959
return new ApplicationRouteLocator(this.server.getServletPrefix(), registry,
70-
this.zuulProperties, RegistryController.PATH);
60+
RegistryController.PATH);
7161
}
7262

7363
@Bean
7464
public PreDecorationFilter preDecorationFilter() {
75-
return new PreDecorationFilter(routeLocator(), this.zuulProperties.isAddProxyHeaders());
65+
return new PreDecorationFilter(routeLocator(), true);
7666
}
7767

7868
@Bean
@@ -125,15 +115,13 @@ public SendErrorFilter sendErrorFilter() {
125115

126116
@Configuration
127117
protected static class ZuulFilterConfiguration {
128-
129118
@Autowired
130119
private Map<String, ZuulFilter> filters;
131120

132121
@Bean
133122
public ZuulFilterInitializer zuulFilterInitializer() {
134123
return new ZuulFilterInitializer(this.filters);
135124
}
136-
137125
}
138126

139127
@EventListener
@@ -142,18 +130,4 @@ public void onRoutesOutdatedEvent(RoutesOutdatedEvent event) {
142130
zuulHandlerMapping().registerHandlers();
143131
}
144132

145-
@Configuration
146-
@ConditionalOnClass(Endpoint.class)
147-
protected static class RoutesEndpointConfiguration {
148-
149-
@Autowired
150-
private ProxyRouteLocator routeLocator;
151-
152-
@Bean
153-
public RoutesEndpoint zuulEndpoint() {
154-
return new RoutesEndpoint(this.routeLocator);
155-
}
156-
157-
}
158-
159133
}

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/controller/RegistryController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public ResponseEntity<Application> register(@RequestBody Application app) {
6969
@RequestMapping(method = RequestMethod.GET)
7070
public Collection<Application> applications(
7171
@RequestParam(value = "name", required = false) String name) {
72-
LOGGER.debug("Deliver registered applications with name= {}", name);
72+
LOGGER.debug("Deliver registered applications with name={}", name);
7373
if (name == null || name.isEmpty()) {
7474
return registry.getApplications();
7575
} else {

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/zuul/ApplicationRouteLocator.java

Lines changed: 101 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@
1515
*/
1616
package de.codecentric.boot.admin.zuul;
1717

18+
import java.util.Collection;
19+
import java.util.Collections;
1820
import java.util.LinkedHashMap;
21+
import java.util.Map;
22+
import java.util.Map.Entry;
23+
import java.util.concurrent.atomic.AtomicReference;
1924

20-
import org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator;
21-
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
2228
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
29+
import org.springframework.util.AntPathMatcher;
30+
import org.springframework.util.PathMatcher;
2331
import org.springframework.util.StringUtils;
2432

2533
import de.codecentric.boot.admin.model.Application;
@@ -30,31 +38,29 @@
3038
*
3139
* @author Johannes Stelzer
3240
*/
33-
public class ApplicationRouteLocator extends ProxyRouteLocator {
34-
41+
public class ApplicationRouteLocator implements RouteLocator {
42+
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRouteLocator.class);
43+
private AtomicReference<Map<String, ZuulRoute>> routes = new AtomicReference<>();
3544
private ApplicationRegistry registry;
3645
private String prefix;
46+
private PathMatcher pathMatcher = new AntPathMatcher();
47+
private String servletPath;
3748

3849
public ApplicationRouteLocator(String servletPath, ApplicationRegistry registry,
39-
ZuulProperties properties, String prefix) {
40-
super(servletPath, null, properties);
50+
String prefix) {
51+
this.servletPath = servletPath;
4152
this.registry = registry;
4253
this.prefix = prefix;
4354
}
4455

45-
@Override
46-
protected LinkedHashMap<String, ZuulRoute> locateRoutes() {
47-
LinkedHashMap<String, ZuulRoute> locateRoutes = super.locateRoutes();
48-
49-
if (registry != null) {
50-
for (Application application : registry.getApplications()) {
51-
addRoute(locateRoutes, prefix + "/" + application.getId() + "/health/**",
52-
application.getHealthUrl());
53-
54-
if (!StringUtils.isEmpty(application.getManagementUrl())) {
55-
addRoute(locateRoutes, prefix + "/" + application.getId() + "/*/**",
56-
application.getManagementUrl());
57-
}
56+
private LinkedHashMap<String, ZuulRoute> locateRoutes() {
57+
LinkedHashMap<String, ZuulRoute> locateRoutes = new LinkedHashMap<String, ZuulRoute>();
58+
for (Application application : registry.getApplications()) {
59+
addRoute(locateRoutes, prefix + "/" + application.getId() + "/health/**",
60+
application.getHealthUrl());
61+
if (!StringUtils.isEmpty(application.getManagementUrl())) {
62+
addRoute(locateRoutes, prefix + "/" + application.getId() + "/*/**",
63+
application.getManagementUrl());
5864
}
5965
}
6066

@@ -65,4 +71,80 @@ private void addRoute(LinkedHashMap<String, ZuulRoute> locateRoutes, String path
6571
locateRoutes.put(path, new ZuulRoute(path, url));
6672
}
6773

74+
public ProxyRouteSpec getMatchingRoute(String path) {
75+
LOGGER.info("Finding route for path: {}; servletPath={}", path, this.servletPath);
76+
if (StringUtils.hasText(this.servletPath) && !this.servletPath.equals("/")
77+
&& path.startsWith(this.servletPath)) {
78+
path = path.substring(this.servletPath.length());
79+
}
80+
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
81+
String pattern = entry.getKey();
82+
LOGGER.debug("Matching pattern: {}", pattern);
83+
if (this.pathMatcher.match(pattern, path)) {
84+
ZuulRoute route = entry.getValue();
85+
int index = route.getPath().indexOf("*") - 1;
86+
String routePrefix = route.getPath().substring(0, index);
87+
String targetPath = path.replaceFirst(routePrefix, "");
88+
return new ProxyRouteSpec(route.getId(), targetPath, route.getLocation(),
89+
routePrefix);
90+
}
91+
}
92+
return null;
93+
}
94+
95+
@Override
96+
public Collection<String> getRoutePaths() {
97+
return getRoutes().keySet();
98+
}
99+
100+
public void resetRoutes() {
101+
this.routes.set(locateRoutes());
102+
}
103+
104+
public Map<String, String> getRoutes() {
105+
if (this.routes.get() == null) {
106+
this.routes.set(locateRoutes());
107+
}
108+
Map<String, String> values = new LinkedHashMap<>();
109+
for (String key : this.routes.get().keySet()) {
110+
String url = key;
111+
values.put(url, this.routes.get().get(key).getLocation());
112+
}
113+
return values;
114+
}
115+
116+
@Override
117+
public Collection<String> getIgnoredPaths() {
118+
return Collections.emptyList();
119+
}
120+
121+
public static class ProxyRouteSpec {
122+
private final String id;
123+
private final String path;
124+
private final String location;
125+
private final String prefix;
126+
127+
public ProxyRouteSpec(String id, String path, String location, String prefix) {
128+
this.id = id;
129+
this.path = path;
130+
this.location = location;
131+
this.prefix = prefix;
132+
}
133+
134+
public String getId() {
135+
return id;
136+
}
137+
138+
public String getPath() {
139+
return path;
140+
}
141+
142+
public String getLocation() {
143+
return location;
144+
}
145+
146+
public String getPrefix() {
147+
return prefix;
148+
}
149+
}
68150
}

0 commit comments

Comments
 (0)