当management.port = 0时,在运行时获取Spring Boot管理端口

时间:2016-04-12 08:07:37

标签: spring spring-boot spock spring-boot-actuator

我正在寻找有关在集成测试中将management.port属性设置为0时如何获取分配给为执行器端点提供服务的嵌入式tomcat的端口的建议。

我使用Spring Boot 1.3.2并使用以下application.yml配置:

server.port: 8080
server.contextPath: /my-app-context-path

management.port: 8081
management.context-path: /manage

...

然后使用@WebIntegrationTest对我的集成测试进行注释,将上面显示的端口设置为0

@WebIntegrationTest({ "server.port=0", "management.port=0" })

并且在执行完整集成测试时,应使用以下实用程序类来访问应用程序配置:

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

我已经知道使用local.server.port可以获得标准端口,并且似乎有一些名为local.management.port的管理端点的等效端口。但那个似乎有不同的含义。

编辑: 官方文档没有提到这样做的方法:(http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-discover-the-http-port-at-runtime

目前是否有任何未记录的方式来管理该管理端口?


解决方案编辑:

当我使用Spock-Framework和Spock-Spring测试我的spring-boot应用程序时,我必须使用以下命令初始化应用程序:

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MyApplication.class)

不知何故,Spock-Spring或测试初始化​​似乎会影响@Value注释的评估,以便@Value("${local.management.port}")导致

java.lang.IllegalArgumentException: Could not resolve placeholder 'local.management.port' in string value "${local.management.port}"

使用您的解决方案我知道该属性存在,所以我只是直接使用spring Environment来检索测试运行时的属性值:

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

3 个答案:

答案 0 :(得分:6)

从Spring Boot 1.4.0开始,有一种更简单的方法:

@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;

答案 1 :(得分:5)

我就是这样做的,直接从我的测试类中复制(我使用RestAssured进行断言):

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 :(得分:0)

这是@magiccrafter 答案的更新,需要以下内容才能正常工作

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <scope>test</scope>
</dependency>

它也需要这个注解

@AutoConfigureWebTestClient