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?
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}"
}
You can get this information via Environment for the port and the host you can obtain by using InternetAddress . Getting the port this way will only work, if a) the port is actually configured explicitly, and b) it is not set to 0 (meaning the servlet container will choose a random port on startup).
We can change the port of the Spring Boot in the following ways: By Adding the configuration in the application properties of the Spring Boot project. By Implementing the WebServerFactoryCustomizer interface in the component class. Changing the configuration of VM options.
Management port needs to be set to 0 via the @SpringBootTest
's properties field and then to get the port in the tests use @LocalServerPort
and/or @LocalManagementPort
annotations.
Examples:
From 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();
}
}
For older versions: [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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With