2016-04-12 8 views
2

Ich bin auf der Suche nach Beratung, wie der Port, der dem eingebetteten Tomcat zugewiesen wurde, der den Endpunkt des Aktuators bei der Einstellung management.port Eigenschaft zu 0 in Integrationstests zugeordnet ist .Erhalten Sie Spring Boot-Management-Port zur Laufzeit, wenn Management.port = 0

Im mit Spring-Boot 1.3.2 mit folgenden application.yml Konfiguration:

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

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

... 

meine Integrationstests werden dann mit @WebIntegrationTest kommentiert, über die Ports Einstellung gezeigt 0

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

und die folgend Bei der Durchführung vollständiger Integrationstests sollte die Dienstprogrammklasse verwendet werden, um auf die Anwendungskonfiguration zuzugreifen:

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

Ich weiß bereits, dass der Standard-Port mit der local.server.port erhalten werden kann und es scheint etwas Entsprechendes für den Management-Endpunkt mit dem Namen local.management.port zu geben. Aber das scheint eine andere Bedeutung zu haben.

Edit: Die offizielle Dokumentation erwähnt nicht einen Weg, dies zu tun: (http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-discover-the-http-port-at-runtime)

Gibt es derzeit jede undokumentierte Weise eine Hand auf diesem Management-Port zu bekommen?


Lösung Edit:

Als ich meine Feder-Boot-Anwendung zum Testen des Spock-Framework und Spock-Spring verwenden, muß ich die Anwendung initialisieren mit:

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

Irgendwie scheint Spock-Spring oder die Testinitialisierung die Auswertung der @Value Annotation so zu beeinflussen, dass @Value("${local.management.port}") in

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

Mit Ihrer Lösung wusste, dass ich die Eigenschaft existiert, so dass ich einfach die Feder Environment direkt die Eigenschaft-Wert bei Testlaufzeit abzurufen:

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

Antwort

4

Dies ist, wie ich es getan habe, gerade kopiert von meiner Testklasse (ich benutze RestAssured für Behauptungen):

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")); 
    } 



} 
+0

Vielen Dank @ dave-bower, Ihre Lösung zu sehen, hat mich in die richtige Richtung angedeutet. – mawi

+0

Mein Problem war, dass ich das Spock-Framework und Spock-Spring benutze, wo diese Eigenschaft nicht aufgelöst wird, wenn man die @ Value Annotation benutzt. Wahrscheinlich, weil ich meine Tests mit '@ContextConfiguration initialisieren (loader = SpringApplicationContextLoader.class, classes = MyApplication.class)'. Ich werde meine Frage bearbeiten und dort die Lösung für meine Spock-Testing-Umgebung hinzufügen. – mawi

+0

Froh, dass es geholfen hat! –

4

ab Frühling Stiefel 1.4.0 es ein einfacher Weg ist:

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

dies benötigt importieren org.springframework.boot.test.context.SpringBootTest.WebEnvironment; –