Add support for random port with https as well
This commit is contained in:
@@ -38,4 +38,6 @@ public @interface AutoConfigureWireMock {
|
||||
|
||||
int port() default 8080;
|
||||
|
||||
int httpsPort() default -1;
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
|
||||
import org.springframework.boot.context.embedded.Ssl;
|
||||
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
|
||||
@@ -57,7 +58,9 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
|
||||
import com.github.tomakehurst.wiremock.common.HttpsSettings;
|
||||
@@ -126,17 +129,19 @@ class SpringBootHttpServer
|
||||
|
||||
@Override
|
||||
public int port() {
|
||||
if (options.httpsSettings().enabled()) {
|
||||
return options.portNumber();
|
||||
}
|
||||
EmbeddedWebApplicationContext embedded = (EmbeddedWebApplicationContext) context;
|
||||
return embedded.getEmbeddedServletContainer().getPort();
|
||||
return container().port();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int httpsPort() {
|
||||
// TODO HTTPS on random port
|
||||
return this.options.httpsSettings().port();
|
||||
return container().httpsPort();
|
||||
}
|
||||
|
||||
private ContainerProperties container() {
|
||||
if (this.context != null) {
|
||||
return context.getBean(ContainerProperties.class);
|
||||
}
|
||||
return new ContainerProperties(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,7 +212,7 @@ class SpringBootHttpServer
|
||||
UndertowContainerConfiguration.class, ServerPropertiesAutoConfiguration.class,
|
||||
BeanPostProcessorsRegistrar.class, ConfigurationPropertiesAutoConfiguration.class,
|
||||
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
PropertyPlaceholderAutoConfiguration.class, ContainerProperties.class })
|
||||
class WiremockServerConfiguration {
|
||||
|
||||
@Autowired
|
||||
@@ -255,6 +260,51 @@ class WiremockServerConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
class ContainerProperties {
|
||||
|
||||
private Options options;
|
||||
|
||||
private Integer localPort;
|
||||
|
||||
private Integer localHttpsPort;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
public ContainerProperties(Options options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public int port() {
|
||||
if (options.httpsSettings().enabled()) {
|
||||
return options.portNumber();
|
||||
}
|
||||
if (this.localPort != null) {
|
||||
return this.localPort;
|
||||
}
|
||||
EmbeddedWebApplicationContext embedded = (EmbeddedWebApplicationContext) context;
|
||||
return embedded.getEmbeddedServletContainer().getPort();
|
||||
}
|
||||
|
||||
public int httpsPort() {
|
||||
if (this.localHttpsPort != null) {
|
||||
return this.localHttpsPort;
|
||||
}
|
||||
return this.options.httpsSettings().port();
|
||||
}
|
||||
|
||||
public void setLocalPort(int localPort) {
|
||||
this.localPort = localPort;
|
||||
}
|
||||
|
||||
public void setLocalHttpsPort(int localHttpsPort) {
|
||||
this.localHttpsPort = localHttpsPort;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ContainerConfiguration {
|
||||
|
||||
@Configuration
|
||||
@@ -264,6 +314,11 @@ class ContainerConfiguration {
|
||||
@Autowired
|
||||
private Options options;
|
||||
|
||||
@Autowired
|
||||
private ContainerProperties container;
|
||||
|
||||
private Connector connector;
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerFactory servletContainer() {
|
||||
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
|
||||
@@ -273,10 +328,20 @@ class ContainerConfiguration {
|
||||
return tomcat;
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void serverUp(EmbeddedServletContainerInitializedEvent event) {
|
||||
if (connector != null) {
|
||||
container.setLocalPort(connector.getLocalPort());
|
||||
container
|
||||
.setLocalHttpsPort(event.getEmbeddedServletContainer().getPort());
|
||||
}
|
||||
}
|
||||
|
||||
private Connector createStandardConnector() {
|
||||
Connector connector = new Connector(
|
||||
"org.apache.coyote.http11.Http11NioProtocol");
|
||||
connector.setPort(this.options.portNumber());
|
||||
this.connector = connector;
|
||||
return connector;
|
||||
}
|
||||
|
||||
@@ -286,9 +351,15 @@ class ContainerConfiguration {
|
||||
@ConditionalOnMissingBean(EmbeddedServletContainerFactory.class)
|
||||
@ConditionalOnClass({ UndertowEmbeddedServletContainerFactory.class, Builder.class })
|
||||
static class UndertowContainerConfiguration {
|
||||
|
||||
@Autowired
|
||||
private Options options;
|
||||
|
||||
@Autowired
|
||||
private ContainerProperties container;
|
||||
|
||||
private Integer port;
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerFactory servletContainer() {
|
||||
UndertowEmbeddedServletContainerFactory undertow = new UndertowEmbeddedServletContainerFactory();
|
||||
@@ -297,11 +368,23 @@ class ContainerConfiguration {
|
||||
@Override
|
||||
public void customize(Builder builder) {
|
||||
builder.addHttpListener(options.portNumber(), "localhost");
|
||||
UndertowContainerConfiguration.this.port = options.portNumber();
|
||||
}
|
||||
});
|
||||
}
|
||||
return undertow;
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void serverUp(EmbeddedServletContainerInitializedEvent event) {
|
||||
if (port != null) {
|
||||
// TODO: make it dynamic as well
|
||||
container.setLocalPort(port);
|
||||
container
|
||||
.setLocalHttpsPort(event.getEmbeddedServletContainer().getPort());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -309,9 +392,15 @@ class ContainerConfiguration {
|
||||
@ConditionalOnClass({ JettyEmbeddedServletContainerFactory.class,
|
||||
ServerConnector.class })
|
||||
static class JettyContainerConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ContainerProperties container;
|
||||
|
||||
@Autowired
|
||||
private Options options;
|
||||
|
||||
private ServerConnector connector;
|
||||
|
||||
@Bean
|
||||
public EmbeddedServletContainerFactory servletContainer() {
|
||||
final JettyEmbeddedServletContainerFactory jetty = new JettyEmbeddedServletContainerFactory();
|
||||
@@ -338,8 +427,18 @@ class ContainerConfiguration {
|
||||
.getHttpConfiguration().setSendServerVersion(false);
|
||||
}
|
||||
}
|
||||
this.connector = connector;
|
||||
return connector;
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void serverUp(EmbeddedServletContainerInitializedEvent event) {
|
||||
if (connector != null) {
|
||||
container.setLocalPort(connector.getLocalPort());
|
||||
container
|
||||
.setLocalHttpsPort(event.getEmbeddedServletContainer().getPort());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,17 @@ public class WireMockApplicationListener implements ApplicationListener<Applicat
|
||||
}
|
||||
Map<String, Object> source = ((MapPropertySource) propertySources
|
||||
.get("wiremock")).getSource();
|
||||
source.put("wiremock.server.port", SocketUtils.findAvailableTcpPort(10000, 15000));
|
||||
source.put("wiremock.server.port", SocketUtils.findAvailableTcpPort(10000, 12500));
|
||||
}
|
||||
if (environment.getProperty("wiremock.server.https-port", Integer.class, 0) == 0) {
|
||||
MutablePropertySources propertySources = environment.getPropertySources();
|
||||
if (!propertySources.contains("wiremock")) {
|
||||
propertySources.addFirst(
|
||||
new MapPropertySource("wiremock", new HashMap<String, Object>()));
|
||||
}
|
||||
Map<String, Object> source = ((MapPropertySource) propertySources
|
||||
.get("wiremock")).getSource();
|
||||
source.put("wiremock.server.https-port", SocketUtils.findAvailableTcpPort(12500, 15000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,30 +43,37 @@ public class WireMockConfiguration implements SmartLifecycle, ImportAware {
|
||||
|
||||
@Autowired(required = false)
|
||||
private Options options;
|
||||
|
||||
|
||||
@Value("${wiremock.server.port:8080}")
|
||||
private int port = 8080;
|
||||
|
||||
@Value("${wiremock.server.https-port:-1}")
|
||||
private int httpsPort = -1;
|
||||
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata metadata) {
|
||||
int port = AnnotationAttributes
|
||||
.fromMap(metadata
|
||||
.getAnnotationAttributes(AutoConfigureWireMock.class.getName()))
|
||||
.getNumber("port").intValue();
|
||||
if (port>0) {
|
||||
AnnotationAttributes map = AnnotationAttributes.fromMap(
|
||||
metadata.getAnnotationAttributes(AutoConfigureWireMock.class.getName()));
|
||||
int port = map.getNumber("port").intValue();
|
||||
if (port > 0) {
|
||||
this.port = port;
|
||||
}
|
||||
int httpsPort = map.getNumber("httpsPort").intValue();
|
||||
if (httpsPort > 0) {
|
||||
this.httpsPort = httpsPort;
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (options == null) {
|
||||
com.github.tomakehurst.wiremock.core.WireMockConfiguration factory = com.github.tomakehurst.wiremock.core.WireMockConfiguration
|
||||
.wireMockConfig()
|
||||
.httpServerFactory(new SpringBootHttpServerFactory());
|
||||
com.github.tomakehurst.wiremock.core.WireMockConfiguration factory = WireMockSpring.options();
|
||||
if (port != 8080) {
|
||||
factory.port(port);
|
||||
}
|
||||
if (httpsPort != -1) {
|
||||
factory.httpsPort(httpsPort);
|
||||
}
|
||||
this.options = factory;
|
||||
}
|
||||
server = new WireMockServer(options);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.springframework.cloud.contract.wiremock;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = WiremockTestsApplication.class, properties = "app.baseUrl=https://localhost:${wiremock.server.https-port}", webEnvironment = WebEnvironment.NONE)
|
||||
@DirtiesContext
|
||||
@AutoConfigureWireMock(httpsPort = 9999)
|
||||
public class AutoConfigureWireMockHttpsPortApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private Service service;
|
||||
|
||||
@Test
|
||||
public void contextLoads() throws Exception {
|
||||
stubFor(get(urlEqualTo("/resource")).willReturn(aResponse()
|
||||
.withHeader("Content-Type", "text/plain").withBody("Hello World!")));
|
||||
assertThat(this.service.go()).isEqualTo("Hello World!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.springframework.cloud.contract.wiremock;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes=WiremockTestsApplication.class, properties="app.baseUrl=https://localhost:${wiremock.server.https-port}", webEnvironment=WebEnvironment.NONE)
|
||||
@DirtiesContext
|
||||
@AutoConfigureWireMock(port=0, httpsPort=0)
|
||||
public class AutoConfigureWireMockRandomPortHttpsApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private Service service;
|
||||
|
||||
@Test
|
||||
public void contextLoads() throws Exception {
|
||||
stubFor(get(urlEqualTo("/resource"))
|
||||
.willReturn(aResponse().withHeader("Content-Type", "text/plain").withBody("Hello World!")));
|
||||
assertThat(this.service.go()).isEqualTo("Hello World!");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user