I'm looking for advice on how to get the port that was assigned to the embedded tomcat that is serving the actuator endpoint when setting management.port
property to 0
in integration tests.
Im using Spring Boot 1.3.2 with the following application.yml
configuration:
server.port: 8080
server.contextPath: /my-app-context-path
management.port: 8081
management.context-path: /manage
...
my integration tests are then annotated with @WebIntegrationTest
, setting the ports shown above to 0
@WebIntegrationTest({ "server.port=0", "management.port=0" })
and the following utility class should be used to get access to the application configuration when doing full integration tests:
@Component
@Profile("testing")
class TestserverInfo {
@Value( '${server.contextPath:}' )
private String contextPath;
@Autowired
private EmbeddedWebApplicationContext server;
@Autowired
private ManagementServerProperties managementServerProperties
public String getBasePath() {
final int serverPort = server.embeddedServletContainer.port
return "http://localhost:${serverPort}${contextPath}"
}
public String getManagementPath() {
// The following wont work here:
// server.embeddedServletContainer.port -> regular server port
// management.port -> is zero just as server.port as i want random ports
final int managementPort = // how can i get this one ?
final String managementPath = managementServerProperties.getContextPath()
return "http://localhost:${managementPort}${managementPath}"
}
}
I allready know the standard port can be get by using the local.server.port
and there seems to be some equivalent for the management endpoint named local.management.port
. But that one seems to have a different meaning.
Edit: The official documentation doesn't mention a way to do this: (http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-discover-the-http-port-at-runtime)
Is there currently any undocumented way to get a hand on that management port?
Solution Edit:
As I am using the Spock-Framework and Spock-Spring for testing my spring-boot application, i have to initialize the application using:
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MyApplication.class)
Somehow Spock-Spring or the test-initialization seems to affect the evaluation of the @Value
Annotation so that @Value("${local.management.port}")
resulted in
java.lang.IllegalArgumentException: Could not resolve placeholder 'local.management.port' in string value "${local.management.port}"
With your solution i knew the property existed, so I simply use the spring Environment
directly to retrieve the property-value at test runtime:
@Autowired
ManagementServerProperties managementServerProperties
@Autowired
Environment environment
public String getManagementPath() {
final int managementPort = environment.getProperty('local.management.port', Integer.class)
final String managementPath = managementServerProperties.getContextPath()
return "http://localhost:${managementPort}${managementPath}"
}
This is how I've done it, copied straight from my test class (I use RestAssured for assertions):
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static com.jayway.restassured.RestAssured.get;
import static org.hamcrest.CoreMatchers.equalTo;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
@WebIntegrationTest(randomPort = true, value = {"management.port=0", "management.context-path=/admin"})
@DirtiesContext
public class ActuatorEndpointTest {
@Value("${local.management.port}")
private int localManagementPort;
@Test
public void actuatorHealthEndpointIsAvailable() throws Exception {
String healthUrl = "http://localhost:" + localManagementPort + "/admin/health";
get(healthUrl)
.then()
.assertThat().body("status", equalTo("UP"));
}
}
As of Spring Boot 1.4.0 there is an easier way:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"management.port=0", "management.context-path=/admin" })
@DirtiesContext
public class SampleTest {
@LocalServerPort
int port;
@LocalManagementPort
int managementPort;
来源:https://stackoverflow.com/questions/36567207/get-spring-boot-management-port-at-runtime-when-management-port-0