diff --git a/pom.xml b/pom.xml index 95a2442e98..0546ec670b 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 5.12.1 2.17.0 - 1.4.1.BUILD-SNAPSHOT + 1.4.2.RELEASE 2.17 1.2.2.BUILD-SNAPSHOT 1.0.4.BUILD-SNAPSHOT diff --git a/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceContextPathTests.java b/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceContextPathTests.java new file mode 100644 index 0000000000..9da4395392 --- /dev/null +++ b/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceContextPathTests.java @@ -0,0 +1,57 @@ +package com.example.loan; + +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.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.example.loan.model.Client; +import com.example.loan.model.LoanApplication; +import com.example.loan.model.LoanApplicationResult; +import com.example.loan.model.LoanApplicationStatus; + +import static org.assertj.core.api.Assertions.assertThat; + +// tag::autoconfigure_stubrunner[] +@RunWith(SpringRunner.class) +@SpringBootTest(properties="server.context-path=/app") +@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"}, workOffline = true) +@DirtiesContext +public class LoanApplicationServiceContextPathTests { +// end::autoconfigure_stubrunner[] + + @Autowired + private LoanApplicationService service; + + @Test + public void shouldSuccessfullyApplyForLoan() { + // given: + LoanApplication application = new LoanApplication(new Client("1234567890"), + 123.123); + // when: + LoanApplicationResult loanApplication = service.loanApplication(application); + // then: + assertThat(loanApplication.getLoanApplicationStatus()) + .isEqualTo(LoanApplicationStatus.LOAN_APPLIED); + assertThat(loanApplication.getRejectionReason()).isNull(); + } + + // tag::client_tdd[] + @Test + public void shouldBeRejectedDueToAbnormalLoanAmount() { + // given: + LoanApplication application = new LoanApplication(new Client("1234567890"), + 99999); + // when: + LoanApplicationResult loanApplication = service.loanApplication(application); + // then: + assertThat(loanApplication.getLoanApplicationStatus()) + .isEqualTo(LoanApplicationStatus.LOAN_APPLICATION_REJECTED); + assertThat(loanApplication.getRejectionReason()).isEqualTo("Amount too high"); + } + // end::client_tdd[] + +} diff --git a/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java b/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java index b9e3b437cb..07360760b7 100644 --- a/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java +++ b/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java @@ -4,7 +4,9 @@ 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.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import com.example.loan.model.Client; @@ -16,8 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat; // tag::autoconfigure_stubrunner[] @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(webEnvironment=WebEnvironment.NONE) @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"}, workOffline = true) +@DirtiesContext public class LoanApplicationServiceTests { // end::autoconfigure_stubrunner[] diff --git a/samples/wiremock-tomcat/src/test/java/com/example/WiremockImportContextPathApplicationTests.java b/samples/wiremock-tomcat/src/test/java/com/example/WiremockImportContextPathApplicationTests.java new file mode 100644 index 0000000000..dadb1b61f4 --- /dev/null +++ b/samples/wiremock-tomcat/src/test/java/com/example/WiremockImportContextPathApplicationTests.java @@ -0,0 +1,35 @@ +package com.example; + +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.cloud.contract.wiremock.AutoConfigureWireMock; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = { "app.baseUrl=http://localhost:8080", + "server.context-path=/app" }, webEnvironment = WebEnvironment.NONE) +@DirtiesContext +@AutoConfigureWireMock +public class WiremockImportContextPathApplicationTests { + + @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!"); + } + +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java index 7244306570..7ca041bfe1 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java @@ -48,8 +48,7 @@ class StubRunnerExecutor implements StubFinder { private final MessageVerifier contractVerifierMessaging; private StubServer stubServer; - public StubRunnerExecutor(AvailablePortScanner portScanner, - MessageVerifier contractVerifierMessaging) { + public StubRunnerExecutor(AvailablePortScanner portScanner, MessageVerifier contractVerifierMessaging) { this.portScanner = portScanner; this.contractVerifierMessaging = contractVerifierMessaging; } @@ -58,11 +57,12 @@ class StubRunnerExecutor implements StubFinder { this(portScanner, new NoOpStubMessages()); } - public RunningStubs runStubs(StubRunnerOptions stubRunnerOptions, - StubRepository repository, StubConfiguration stubConfiguration) { + public RunningStubs runStubs(StubRunnerOptions stubRunnerOptions, StubRepository repository, + StubConfiguration stubConfiguration) { if (this.stubServer != null) { if (log.isDebugEnabled()) { - log.debug("Returning cached version of stubs [" + stubConfiguration.toColonSeparatedDependencyNotation() + "]"); + log.debug("Returning cached version of stubs [" + stubConfiguration.toColonSeparatedDependencyNotation() + + "]"); } return runningStubs(); } @@ -73,8 +73,8 @@ class StubRunnerExecutor implements StubFinder { } private RunningStubs runningStubs() { - return new RunningStubs(Collections - .singletonMap(this.stubServer.getStubConfiguration(), this.stubServer.getPort())); + return new RunningStubs( + Collections.singletonMap(this.stubServer.getStubConfiguration(), this.stubServer.getPort())); } public void shutdown() { @@ -87,8 +87,7 @@ class StubRunnerExecutor implements StubFinder { public URL findStubUrl(String groupId, String artifactId) { URL url = null; if (groupId == null) { - url = findStubUrl( - this.stubServer.stubConfiguration.artifactId.equals(artifactId)); + url = findStubUrl(this.stubServer.stubConfiguration.artifactId.equals(artifactId)); } if (url == null) { url = findStubUrl(this.stubServer.stubConfiguration.artifactId.equals(artifactId) @@ -104,12 +103,16 @@ class StubRunnerExecutor implements StubFinder { public URL findStubUrl(String ivyNotation) { String[] splitString = ivyNotation.split(":", -1); if (splitString.length > 4) { - throw new IllegalArgumentException("[" + ivyNotation + "] is an invalid notation. Pass [groupId]:artifactId[:version][:classifier]."); - } else if (splitString.length == 1) { + throw new IllegalArgumentException( + "[" + ivyNotation + "] is an invalid notation. Pass [groupId]:artifactId[:version][:classifier]."); + } + else if (splitString.length == 1) { return findStubUrl(null, splitString[0]); - } else if (splitString.length == 2) { + } + else if (splitString.length == 2) { return findStubUrl(splitString[0], splitString[1]); - } else if (splitString.length == 3) { + } + else if (splitString.length == 3) { return findStubUrl(groupIdArtifactVersionMatches(splitString)); } return findStubUrl(groupIdArtifactVersionMatches(splitString) && classifierMatches(splitString)); @@ -131,21 +134,18 @@ class StubRunnerExecutor implements StubFinder { @Override public RunningStubs findAllRunningStubs() { - return new RunningStubs(Collections.singletonMap(this.stubServer.stubConfiguration, - this.stubServer.getPort())); + return new RunningStubs(Collections.singletonMap(this.stubServer.stubConfiguration, this.stubServer.getPort())); } @Override public Map> getContracts() { - return Collections.singletonMap(this.stubServer.stubConfiguration, - this.stubServer.getContracts()); + return Collections.singletonMap(this.stubServer.stubConfiguration, this.stubServer.getContracts()); } @Override public boolean trigger(String ivyNotationAsString, String labelName) { Collection matchingContracts = new ArrayList<>(); - for (Entry> it : getContracts() - .entrySet()) { + for (Entry> it : getContracts().entrySet()) { if (it.getKey().groupIdAndArtifactMatches(ivyNotationAsString)) { matchingContracts.addAll(it.getValue()); } @@ -193,8 +193,7 @@ class StubRunnerExecutor implements StubFinder { @Override public Map> labels() { Map> labels = new LinkedHashMap<>(); - for (Entry> it : getContracts() - .entrySet()) { + for (Entry> it : getContracts().entrySet()) { Collection values = new ArrayList<>(); for (Contract contract : it.getValue()) { if (contract.getLabel() != null) { @@ -214,47 +213,42 @@ class StubRunnerExecutor implements StubFinder { DslProperty body = outputMessage.getBody(); Headers headers = outputMessage.getHeaders(); this.contractVerifierMessaging.send( - JsonOutput.toJson(BodyExtractor.extractClientValueFromBody( - body == null ? null : body.getClientValue())), - headers == null ? null : headers.asStubSideMap(), - outputMessage.getSentTo().getClientValue()); + JsonOutput + .toJson(BodyExtractor.extractClientValueFromBody(body == null ? null : body.getClientValue())), + headers == null ? null : headers.asStubSideMap(), outputMessage.getSentTo().getClientValue()); } private URL returnStubUrlIfMatches(boolean condition) { return condition ? this.stubServer.getStubUrl() : null; } - private void startStubServers(final StubRunnerOptions stubRunnerOptions, - final StubConfiguration stubConfiguration, StubRepository repository) { - final List mappings = repository - .getProjectDescriptors(); + private void startStubServers(final StubRunnerOptions stubRunnerOptions, final StubConfiguration stubConfiguration, + StubRepository repository) { + final List mappings = repository.getProjectDescriptors(); final Collection contracts = repository.contracts; Integer port = stubRunnerOptions.port(stubConfiguration); if (!contracts.isEmpty() && !hasRequest(contracts)) { if (log.isDebugEnabled()) { log.debug("There are no HTTP related contracts. Won't start any servers"); } - this.stubServer = new StubServer(stubRunnerOptions, stubConfiguration, mappings, contracts, new NoOpHttpServerStub()); + this.stubServer = new StubServer(stubConfiguration, mappings, contracts, new NoOpHttpServerStub()); return; } if (contracts.isEmpty()) { - log.warn( - "There are no contracts in the published JAR. This is an unusual situation " - + "that's why will start the server - maybe you know what you're doing..."); + log.warn("There are no contracts in the published JAR. This is an unusual situation " + + "that's why will start the server - maybe you know what you're doing..."); } if (port != null && port >= 0) { - this.stubServer = new StubServer(stubRunnerOptions, stubConfiguration, mappings, contracts, - new WireMockHttpServerStub(port)); - } else { - this.stubServer = this.portScanner - .tryToExecuteWithFreePort(new PortCallback() { - @Override - public StubServer call(int availablePort) { - return new StubServer(stubRunnerOptions, stubConfiguration, - mappings, contracts, - new WireMockHttpServerStub(availablePort)); - } - }); + this.stubServer = new StubServer(stubConfiguration, mappings, contracts, new WireMockHttpServerStub(port)); + } + else { + this.stubServer = this.portScanner.tryToExecuteWithFreePort(new PortCallback() { + @Override + public StubServer call(int availablePort) { + return new StubServer(stubConfiguration, mappings, contracts, + new WireMockHttpServerStub(availablePort)); + } + }); } this.stubServer = this.stubServer.start(); } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java index 7aac4762e8..4f1e740112 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java @@ -19,7 +19,6 @@ package org.springframework.cloud.contract.stubrunner; import java.util.Collection; import java.util.Map; - /** * Technical options related to running StubRunner * @@ -61,14 +60,8 @@ public class StubRunnerOptions { */ final Map stubIdsToPortMapping; - /** - * Context Path of the server - */ - final String contextPath; - - public StubRunnerOptions(Integer minPortValue, Integer maxPortValue, - String stubRepositoryRoot, boolean workOffline, String stubsClassifier, - Collection dependencies, + public StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline, + String stubsClassifier, Collection dependencies, Map stubIdsToPortMapping) { this.minPortValue = minPortValue; this.maxPortValue = maxPortValue; @@ -77,27 +70,24 @@ public class StubRunnerOptions { this.stubsClassifier = stubsClassifier; this.dependencies = dependencies; this.stubIdsToPortMapping = stubIdsToPortMapping; - this.contextPath = ""; } - public StubRunnerOptions(Integer minPortValue, Integer maxPortValue, - String stubRepositoryRoot, boolean workOffline, String stubsClassifier, - Collection dependencies, + /** + * @deprecated there is no context path any longer + */ + @Deprecated + public StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline, + String stubsClassifier, Collection dependencies, Map stubIdsToPortMapping, String contextPath) { - this.minPortValue = minPortValue; - this.maxPortValue = maxPortValue; - this.stubRepositoryRoot = stubRepositoryRoot; - this.workOffline = workOffline; - this.stubsClassifier = stubsClassifier; - this.dependencies = dependencies; - this.stubIdsToPortMapping = stubIdsToPortMapping; - this.contextPath = contextPath; + this(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier, dependencies, + stubIdsToPortMapping); } public Integer port(StubConfiguration stubConfiguration) { - if (this.stubIdsToPortMapping!=null) { + if (this.stubIdsToPortMapping != null) { return this.stubIdsToPortMapping.get(stubConfiguration); - } else { + } + else { return null; } } @@ -120,11 +110,10 @@ public class StubRunnerOptions { @Override public String toString() { - return "StubRunnerOptions [minPortValue=" + this.minPortValue + ", maxPortValue=" - + this.maxPortValue + ", stubRepositoryRoot=" + this.stubRepositoryRoot - + ", workOffline=" + this.workOffline + ", stubsClassifier=" + this.stubsClassifier - + ", dependencies=" + this.dependencies + ", stubIdsToPortMapping=" - + this.stubIdsToPortMapping + "]"; + return "StubRunnerOptions [minPortValue=" + this.minPortValue + ", maxPortValue=" + this.maxPortValue + + ", stubRepositoryRoot=" + this.stubRepositoryRoot + ", workOffline=" + this.workOffline + + ", stubsClassifier=" + this.stubsClassifier + ", dependencies=" + this.dependencies + + ", stubIdsToPortMapping=" + this.stubIdsToPortMapping + "]"; } } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java index 515be3fd5a..39e67e8f5a 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java @@ -37,7 +37,6 @@ public class StubRunnerOptionsBuilder { private String stubRepositoryRoot; private boolean workOffline = false; private String stubsClassifier = "stubs"; - private String contextPath = ""; public StubRunnerOptionsBuilder() { } @@ -96,8 +95,11 @@ public class StubRunnerOptionsBuilder { return this; } + /** + * @deprecated there is no context path for the stub server + */ + @Deprecated public StubRunnerOptionsBuilder withContextPath(String contextPath) { - this.contextPath = contextPath; return this; } @@ -107,14 +109,12 @@ public class StubRunnerOptionsBuilder { this.stubRepositoryRoot = options.stubRepositoryRoot; this.workOffline = options.workOffline; this.stubsClassifier = options.stubsClassifier; - this.contextPath = options.contextPath; return this; } public StubRunnerOptions build() { return new StubRunnerOptions(this.minPortValue, this.maxPortValue, this.stubRepositoryRoot, - this.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping, - this.contextPath); + this.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping); } private Collection buildDependencies() { diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubServer.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubServer.java index fd489f6b3c..6fb15069da 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubServer.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubServer.java @@ -23,23 +23,20 @@ import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.contract.spec.Contract; -import org.springframework.util.StringUtils; import com.github.tomakehurst.wiremock.client.WireMock; class StubServer { - + private static final Logger log = LoggerFactory.getLogger(StubServer.class); - + private final HttpServerStub httpServerStub; final StubConfiguration stubConfiguration; final Collection mappings; final Collection contracts; - private final StubRunnerOptions stubRunnerOptions; - StubServer(StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration, - Collection mappings, Collection contracts, HttpServerStub httpServerStub) { - this.stubRunnerOptions = stubRunnerOptions; + StubServer(StubConfiguration stubConfiguration, Collection mappings, + Collection contracts, HttpServerStub httpServerStub) { this.stubConfiguration = stubConfiguration; this.mappings = mappings; this.httpServerStub = httpServerStub; @@ -48,8 +45,8 @@ class StubServer { public StubServer start() { this.httpServerStub.start(); - log.info("Started stub server for project [" + this.stubConfiguration.toColonSeparatedDependencyNotation() + - "] on port " + this.httpServerStub.port()); + log.info("Started stub server for project [" + this.stubConfiguration.toColonSeparatedDependencyNotation() + + "] on port " + this.httpServerStub.port()); registerStubMappings(); return this; } @@ -63,31 +60,21 @@ class StubServer { return this.httpServerStub.port(); } if (log.isDebugEnabled()) { - log.debug("The HTTP Server stub is not running... That means that the " + - "artifact is running a messaging module. Returning back -1 value of the port."); + log.debug("The HTTP Server stub is not running... That means that the " + + "artifact is running a messaging module. Returning back -1 value of the port."); } return -1; } public URL getStubUrl() { try { - return new URL("http://localhost:" + getPort() + prependSlashIfNecessary(this.stubRunnerOptions.contextPath)); + return new URL("http://localhost:" + getPort()); } catch (MalformedURLException e) { throw new IllegalStateException("Cannot parse URL", e); } } - private String prependSlashIfNecessary(String contextPath) { - if (!StringUtils.hasText(contextPath)) { - return ""; - } - if (contextPath.startsWith("/")) { - return contextPath; - } - return "/" + contextPath; - } - public StubConfiguration getStubConfiguration() { return this.stubConfiguration; } @@ -97,7 +84,7 @@ class StubServer { } private void registerStubMappings() { - WireMock wireMock = new WireMock("localhost", this.httpServerStub.port(), prependSlashIfNecessary(this.stubRunnerOptions.contextPath)); + WireMock wireMock = new WireMock("localhost", this.httpServerStub.port(), ""); registerDefaultHealthChecks(wireMock); registerStubs(this.mappings, wireMock); } @@ -108,14 +95,15 @@ class StubServer { } private void registerStubs(Collection sortedMappings, WireMock wireMock) { - for (WiremockMappingDescriptor mappingDescriptor : sortedMappings) { + for (WiremockMappingDescriptor mappingDescriptor : sortedMappings) { try { wireMock.register(mappingDescriptor.getMapping()); if (log.isDebugEnabled()) { log.debug("Registered stub mappings from [" + mappingDescriptor.descriptor + "]"); } - } catch (Exception e) { - log.warn("Failed to register the stub mapping ["+ mappingDescriptor + "]", e); + } + catch (Exception e) { + log.warn("Failed to register the stub mapping [" + mappingDescriptor + "]", e); } } } @@ -123,8 +111,9 @@ class StubServer { private void registerHealthCheck(WireMock wireMock, String url) { registerHealthCheck(wireMock, url, "OK"); } - + private void registerHealthCheck(WireMock wireMock, String url, String body) { - wireMock.register(WireMock.get(WireMock.urlEqualTo(url)).willReturn(WireMock.aResponse().withBody(body).withStatus(200))); + wireMock.register( + WireMock.get(WireMock.urlEqualTo(url)).willReturn(WireMock.aResponse().withBody(body).withStatus(200))); } } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java index f9c777e6ec..7553c25917 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java @@ -20,7 +20,6 @@ import java.io.IOException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.contract.stubrunner.AetherStubDownloader; import org.springframework.cloud.contract.stubrunner.BatchStubRunner; @@ -49,8 +48,6 @@ public class StubRunnerConfiguration { private StubDownloader stubDownloader; @Autowired private StubRunnerProperties props; - @Autowired(required = false) - private ServerProperties serverProperties; /** * Bean that initializes stub runners, runs them and on shutdown closes them. Upon its @@ -66,7 +63,6 @@ public class StubRunnerConfiguration { .withWorkOffline(this.props.isWorkOffline()) .withStubsClassifier(this.props.getClassifier()) .withStubs(this.props.getIds()) - .withContextPath(contextPath()) .build(); BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, this.stubDownloader != null ? this.stubDownloader @@ -82,11 +78,4 @@ public class StubRunnerConfiguration { return stubRepositoryRoot != null ? stubRepositoryRoot.getURI().toString() : ""; } - private String contextPath() { - if (this.serverProperties == null) { - return ""; - } - return this.serverProperties.getContextPath(); - } - } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java index 7f195bb5d1..27ab22716f 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java @@ -60,6 +60,11 @@ public class StubRunnerProperties { */ private String classifier = "stubs"; + /** + * The context path that the stub server will run under. + */ + private String contextPath = ""; + public int getMinPort() { return this.minPort; } @@ -108,6 +113,14 @@ public class StubRunnerProperties { this.classifier = classifier; } + public String getContextPath() { + return this.contextPath; + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + @Override public String toString() { return "StubRunnerProperties{" + "minPort=" + this.minPort + ", maxPort=" + this.maxPort + ", workOffline=" + this.workOffline + ", repositoryRoot=" + this.repositoryRoot diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy index a7bd585c31..bee5ab6820 100644 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy @@ -28,7 +28,7 @@ class StubServerSpec extends Specification { def 'should register stub mappings upon server start'() { given: List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() - StubServer pingStubServer = new StubServer(new TestStubRunnerOptions(), stubConfiguration, mappingDescriptors, [], + StubServer pingStubServer = new StubServer(stubConfiguration, mappingDescriptors, [], new WireMockHttpServerStub(STUB_SERVER_PORT)) when: pingStubServer.start() @@ -40,7 +40,7 @@ class StubServerSpec extends Specification { def 'should provide stub server URL'() { given: List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() - StubServer pingStubServer = new StubServer(new TestStubRunnerOptions(), stubConfiguration, mappingDescriptors, [], + StubServer pingStubServer = new StubServer(stubConfiguration, mappingDescriptors, [], new WireMockHttpServerStub(STUB_SERVER_PORT)) when: pingStubServer.start() diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/TestStubRunnerOptions.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/TestStubRunnerOptions.groovy deleted file mode 100644 index 19c287d977..0000000000 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/TestStubRunnerOptions.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package org.springframework.cloud.contract.stubrunner - -import groovy.transform.PackageScope - -/** - * @author Marcin Grzejszczak - */ -@PackageScope class TestStubRunnerOptions extends StubRunnerOptions { - public TestStubRunnerOptions() { - super(1, 2, "", false, "", new ArrayList(), - new HashMap()); - } -} diff --git a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/SpringBootHttpServerFactory.java b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/SpringBootHttpServerFactory.java index 9f30793c13..fad716dd8b 100644 --- a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/SpringBootHttpServerFactory.java +++ b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/SpringBootHttpServerFactory.java @@ -37,8 +37,9 @@ import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfigura import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration.BeanPostProcessorsRegistrar; import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; 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.ConfigurableEmbeddedServletContainer; +import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; @@ -170,8 +171,8 @@ class SpringBootHttpServer @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof ServerProperties) { - ServerProperties server = (ServerProperties) bean; + if (bean instanceof WiremockServerProperties) { + WiremockServerProperties server = (WiremockServerProperties) bean; server.setPort(getPort()); setupHttps(server, SpringBootHttpServer.this.options.httpsSettings()); // TODO: other options @@ -179,7 +180,7 @@ class SpringBootHttpServer return bean; } - private void setupHttps(ServerProperties server, HttpsSettings httpsSettings) { + private void setupHttps(WiremockServerProperties server, HttpsSettings httpsSettings) { if (httpsSettings.port() < 0 || !httpsSettings.enabled()) { return; } @@ -207,9 +208,44 @@ class SpringBootHttpServer } +class WiremockServerProperties implements EmbeddedServletContainerCustomizer { + + private ServerProperties delegate = new ServerProperties(); + + public Integer getPort() { + return this.delegate.getPort(); + } + + public void setPort(Integer port) { + this.delegate.setPort(port); + } + + public Ssl getSsl() { + return this.delegate.getSsl(); + } + + public void setSsl(Ssl ssl) { + this.delegate.setSsl(ssl); + } + + @Override + public void customize(ConfigurableEmbeddedServletContainer container) { + this.delegate.customize(container); + } +} + +@Configuration +class ServerPropertiesConfiguration { + @Bean + public WiremockServerProperties serverProperties() { + // Needs to be something that doesn't bind to "server.*" + return new WiremockServerProperties(); + } +} + @Configuration @Import({ TomcatContainerConfiguration.class, JettyContainerConfiguration.class, - UndertowContainerConfiguration.class, ServerPropertiesAutoConfiguration.class, + UndertowContainerConfiguration.class, ServerPropertiesConfiguration.class, BeanPostProcessorsRegistrar.class, ConfigurationPropertiesAutoConfiguration.class, JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, ContainerProperties.class }) diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java b/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java index 0b18697eff..0fae64d3da 100644 --- a/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java @@ -5,8 +5,10 @@ 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.cloud.contract.stubrunner.StubFinder; import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import com.example.loan.model.Client; @@ -18,9 +20,10 @@ import static org.assertj.core.api.Assertions.assertThat; // tag::autoconfigure_stubrunner[] @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(webEnvironment=WebEnvironment.NONE) @AutoConfigureStubRunner(repositoryRoot = "classpath:m2repo/repository/", ids = { "org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer" }) +@DirtiesContext public class LoanApplicationServiceTests { // end::autoconfigure_stubrunner[]