Get Spring Boot management port at runtime when management.port=0

不羁岁月 提交于 2019-11-30 18:13:08

问题


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}"
}

回答1:


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"));
    }



}



回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!