Получить порт управления Spring Boot во время выполнения, когда management.port=0

Я ищу совета о том, как получить порт, который был назначен встроенному коту, который обслуживает конечную точку привода, при установке свойства management.port на 0 в интеграционных тестах.

Я использую 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 для тестирования моего приложения с весенней загрузкой, мне нужно инициализировать приложение, используя:

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

С вашим решением я знал, что свойство существует, поэтому я просто использую пружину 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}"
}

person mawi    schedule 12.04.2016    source источник


Ответы (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"));
    }



}
person Dave Bower    schedule 12.04.2016
comment
Спасибо @dave-bower, ваше решение подсказало мне правильное направление. - person mawi; 12.04.2016
comment
Моя проблема заключалась в том, что я использую Spock-Framework и Spock-Spring, где это свойство не разрешается при использовании аннотации @Value. Вероятно, потому что я инициализирую свои тесты, используя @ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MyApplication.class). Я отредактирую свой вопрос и добавлю туда решение для своей среды тестирования Spock. - person mawi; 12.04.2016

Порт управления должен быть установлен на 0 через поле свойств @SpringBootTest, а затем, чтобы получить порт в тестах, используйте аннотации @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;
person magiccrafter    schedule 22.12.2016
comment
для этого необходимо импортировать org.springframework.boot.test.context.SpringBootTest.WebEnvironment; - person Jeremy Kahan; 06.07.2017
comment
В Spring Boot 2.0.0 свойство management.port было изменено на management.server.port. - person Heitor Ganzeli; 16.04.2018