当 management.port=0 时在运行时获取 Spring 引导管理端口
Get Spring Boot management port at runtime when management.port=0
我正在寻找有关如何在将 management.port
属性 设置为 [=19] 时获取分配给为执行器端点服务的嵌入式 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" })
和以下实用程序 class 应该用于在进行完整集成测试时访问应用程序配置:
@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}"
}
我就是这样做的,直接从我的测试中复制 class(我使用 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"));
}
}
需要通过 @SpringBootTest
的属性字段将管理端口设置为 0,然后在测试中使用 @LocalServerPort
and/or @LocalManagementPort
注释获取端口.
示例:
来自 Spring 启动 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;
这是对@magiccrafter 回答的更新,需要以下内容才能正常工作
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
它也需要这个注解
@AutoConfigureWebTestClient
我正在寻找有关如何在将 management.port
属性 设置为 [=19] 时获取分配给为执行器端点服务的嵌入式 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" })
和以下实用程序 class 应该用于在进行完整集成测试时访问应用程序配置:
@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}"
}
我就是这样做的,直接从我的测试中复制 class(我使用 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"));
}
}
需要通过 @SpringBootTest
的属性字段将管理端口设置为 0,然后在测试中使用 @LocalServerPort
and/or @LocalManagementPort
注释获取端口.
示例:
来自 Spring 启动 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;
这是对@magiccrafter 回答的更新,需要以下内容才能正常工作
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
它也需要这个注解
@AutoConfigureWebTestClient