【问题标题】:Get Spring Boot management port at runtime when management.port=0management.port=0时在运行时获取Spring Boot管理端口
【发布时间】:2016-08-02 16:59:24
【问题描述】:

我正在寻找有关在集成测试中将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}"
}

【问题讨论】:

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


    【解决方案1】:

    需要通过@SpringBootTest 的属性字段将管理端口设置为0,然后在测试中使用@LocalServerPort 和/或@LocalManagementPort 注释来获取端口。

    例子:

    来自 Spring Boot 2.0.0:
    properties = {"management.server.port=0"}

    @ExtendWith(SpringExtension.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
            "management.server.port=0" })
    public class HealthCheckIT {
    
        @Autowired
        private WebTestClient webTestClient;
    
        @LocalManagementPort
        int managementPort;
    
        @Test
        public void testManagementPort() {
            webTestClient
                    .get().uri("http://localhost:" + managementPort + "/actuator/health")
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                    .accept(MediaType.APPLICATION_JSON)
                    .exchange()
                    .expectStatus().isOk();
        }
    }
    

    对于旧版本:[1.4.0 - 1.5.x]:
    properties = {"management.port=0"}

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
        "management.port=0", "management.context-path=/admin" })
    public class SampleTest {
    
        @LocalServerPort
        int port;
    
        @LocalManagementPort
        int managementPort;
    

    【讨论】:

    • 这需要import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
    • 在 Spring Boot 2.0.0 上,属性 management.port 更改为 management.server.port
    【解决方案2】:

    我就是这样做的,直接从我的测试类中复制(我使用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"));
        }
    
    
    
    }
    

    【讨论】:

    • 谢谢@dave-bower,看到您的解决方案提示了我正确的方向。
    • 我的问题是,我使用的是 Spock-Framework 和 Spock-Spring,在使用 @Value 注释时,此属性无法解决。可能是因为我正在使用@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MyApplication.class) 初始化我的测试。我将编辑我的问题并在那里为我的 Spock-Testing Environment 添加解决方案。
    【解决方案3】:

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

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

    它也需要这个注解

    @AutoConfigureWebTestClient

    【讨论】:

      猜你喜欢
      • 2018-08-09
      • 2015-07-30
      • 2015-09-17
      • 2019-03-20
      • 2019-04-17
      • 2021-03-27
      • 1970-01-01
      • 2020-06-29
      • 2019-03-19
      相关资源
      最近更新 更多