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

Commit 45d44aa

Browse files
Johannes StelzerJohannes Stelzer
authored andcommitted
Rework default management-url computation.
This change not only allows you to use `context-path` and `contextPath` but also respects automatic port assignment when using `server.port=0` or `managment.port=0`. Also corrects the value if server.port != mangement.port and server.context-path and management.server-path is set. fixes #57
1 parent 2732510 commit 45d44aa

3 files changed

Lines changed: 193 additions & 2 deletions

File tree

spring-boot-admin-starter-client/src/main/java/de/codecentric/boot/admin/config/AdminClientProperties.java

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,71 @@
1515
*/
1616
package de.codecentric.boot.admin.config;
1717

18+
import java.net.InetAddress;
19+
import java.net.UnknownHostException;
20+
21+
import org.springframework.beans.factory.annotation.Autowired;
1822
import org.springframework.beans.factory.annotation.Value;
23+
import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties;
24+
import org.springframework.boot.autoconfigure.web.ServerProperties;
25+
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
1926
import org.springframework.boot.context.properties.ConfigurationProperties;
27+
import org.springframework.context.ApplicationListener;
28+
import org.springframework.util.StringUtils;
2029

2130
@ConfigurationProperties(prefix = "spring.boot.admin.client", ignoreUnknownFields = false)
22-
public class AdminClientProperties {
31+
public class AdminClientProperties implements ApplicationListener<EmbeddedServletContainerInitializedEvent>{
2332

24-
@Value("http://#{T(java.net.InetAddress).localHost.canonicalHostName}:${management.port:${server.port:8080}}${server.context-path:/}${management.context-path:/}")
2533
private String url;
2634

2735
@Value("${spring.application.name:spring-boot-application}")
2836
private String name;
2937

38+
@Autowired
39+
private ManagementServerProperties management;
40+
41+
@Autowired
42+
private ServerProperties server;
43+
44+
private int serverPort = -1;
45+
46+
private int managementPort = -1;
47+
48+
49+
@Override
50+
public void onApplicationEvent(
51+
EmbeddedServletContainerInitializedEvent event) {
52+
if ("management".equals(event.getApplicationContext().getNamespace())) {
53+
managementPort = event.getEmbeddedServletContainer().getPort();
54+
} else {
55+
serverPort = event.getEmbeddedServletContainer().getPort();
56+
}
57+
}
58+
3059
/**
3160
* @return Client-management-URL to register with. Can be overriden in case the
3261
* reachable URL is different (e.g. Docker). Must be unique in registry.
3362
*/
3463
public String getUrl() {
64+
if (url == null) {
65+
if (managementPort != -1) {
66+
url = "http://"
67+
+ (getHostname() + ':' + managementPort + toPathFragment(management
68+
.getContextPath()))
69+
.replaceAll("//+", "/");
70+
} else if (serverPort != -1){
71+
url = "http://"
72+
+ (getHostname()
73+
+ ':'
74+
+ serverPort
75+
+ toPathFragment(server.getContextPath()) + toPathFragment(management
76+
.getContextPath())).replaceAll("//+", "/");
77+
} else {
78+
throw new IllegalStateException(
79+
"EmbeddedServletContainer has not been initialized yet!");
80+
}
81+
}
82+
3583
return url;
3684
}
3785

@@ -49,4 +97,22 @@ public String getName() {
4997
public void setName(String name) {
5098
this.name = name;
5199
}
100+
101+
private String getHostname() {
102+
try {
103+
return InetAddress.getLocalHost().getCanonicalHostName();
104+
}
105+
catch (UnknownHostException ex) {
106+
throw new IllegalStateException("Couldn't get hostname", ex);
107+
}
108+
}
109+
110+
private String toPathFragment(String fragment) {
111+
if (StringUtils.isEmpty(fragment)) {
112+
return "";
113+
}
114+
else {
115+
return "/" + fragment;
116+
}
117+
}
52118
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package de.codecentric.boot.admin.config;
2+
3+
import static org.hamcrest.Matchers.is;
4+
import static org.junit.Assert.assertThat;
5+
import static org.mockito.Mockito.mock;
6+
import static org.mockito.Mockito.when;
7+
8+
import java.net.InetAddress;
9+
import java.net.UnknownHostException;
10+
11+
import org.junit.After;
12+
import org.junit.Test;
13+
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
14+
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
15+
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
16+
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
17+
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
18+
import org.springframework.boot.test.EnvironmentTestUtils;
19+
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
20+
21+
public class AdminClientPropertiesTest {
22+
23+
private AnnotationConfigWebApplicationContext context;
24+
25+
@After
26+
public void close() {
27+
if (this.context != null) {
28+
this.context.close();
29+
}
30+
}
31+
32+
@Test
33+
public void test_mgmtPortPath() {
34+
load("spring.boot.admin.url:http://localhost:8081",
35+
"management.contextPath=/admin");
36+
AdminClientProperties clientProperties = context
37+
.getBean(AdminClientProperties.class);
38+
39+
publishEvent(8080, null);
40+
publishEvent(8081, "management");
41+
42+
assertThat(clientProperties.getUrl(), is("http://" + getHostname()
43+
+ ":8081/admin"));
44+
}
45+
46+
@Test
47+
public void test_mgmtPort() {
48+
load("spring.boot.admin.url:http://localhost:8081");
49+
AdminClientProperties clientProperties = context
50+
.getBean(AdminClientProperties.class);
51+
52+
publishEvent(8080, null);
53+
publishEvent(8081, "management");
54+
55+
assertThat(clientProperties.getUrl(), is("http://" + getHostname() + ":8081"));
56+
}
57+
58+
@Test
59+
public void test_contextPath_mgmtPath() {
60+
load("spring.boot.admin.url:http://localhost:8081", "server.context-path=app",
61+
"management.context-path=/admin");
62+
AdminClientProperties clientProperties = context
63+
.getBean(AdminClientProperties.class);
64+
65+
publishEvent(8080, null);
66+
67+
assertThat(clientProperties.getUrl(), is("http://" + getHostname()
68+
+ ":8080/app/admin"));
69+
}
70+
71+
72+
@Test
73+
public void test_contextPath() {
74+
load("spring.boot.admin.url:http://localhost:8081", "server.context-path=app");
75+
AdminClientProperties clientProperties = context
76+
.getBean(AdminClientProperties.class);
77+
78+
publishEvent(8080, null);
79+
80+
assertThat(clientProperties.getUrl(), is("http://" + getHostname() + ":8080/app"));
81+
}
82+
83+
84+
@Test
85+
public void test_default() {
86+
load("spring.boot.admin.url:http://localhost:8081");
87+
AdminClientProperties clientProperties = context
88+
.getBean(AdminClientProperties.class);
89+
90+
publishEvent(8080, null);
91+
92+
assertThat(clientProperties.getUrl(), is("http://" + getHostname() + ":8080"));
93+
}
94+
95+
private String getHostname() {
96+
try {
97+
return InetAddress.getLocalHost().getCanonicalHostName();
98+
}
99+
catch (UnknownHostException e) {
100+
throw new RuntimeException(e);
101+
}
102+
}
103+
104+
private void publishEvent(int port, String namespace) {
105+
EmbeddedServletContainer eventSource = mock(EmbeddedServletContainer.class);
106+
when(eventSource.getPort()).thenReturn(port);
107+
EmbeddedWebApplicationContext eventContext = mock(EmbeddedWebApplicationContext.class);
108+
when(eventContext.getNamespace()).thenReturn(namespace);
109+
context.publishEvent(new EmbeddedServletContainerInitializedEvent(eventContext,
110+
eventSource));
111+
}
112+
113+
private void load(String... environment) {
114+
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
115+
applicationContext.register(ServerPropertiesAutoConfiguration.class);
116+
applicationContext.register(ManagementServerPropertiesAutoConfiguration.class);
117+
applicationContext.register(SpringBootAdminClientAutoConfiguration.class);
118+
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
119+
applicationContext.refresh();
120+
this.context = applicationContext;
121+
}
122+
123+
}

spring-boot-admin-starter-client/src/test/java/de/codecentric/boot/admin/config/SpringBootAdminClientAutoConfigurationTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import org.junit.After;
66
import org.junit.Test;
7+
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
78
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
89
import org.springframework.boot.test.EnvironmentTestUtils;
910
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
@@ -53,6 +54,7 @@ public void active_logfile_supressed() {
5354
private void load(String... environment) {
5455
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
5556
applicationContext.register(ServerPropertiesAutoConfiguration.class);
57+
applicationContext.register(ManagementServerPropertiesAutoConfiguration.class);
5658
applicationContext.register(SpringBootAdminClientAutoConfiguration.class);
5759
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
5860
applicationContext.refresh();

0 commit comments

Comments
 (0)