From b17238ff4e433556eabd0768e3fb8deb2f948c6d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 11 Oct 2016 11:27:10 +0200 Subject: [PATCH] Fixing missing context-path usage without this change when the user adds context-path it gets ignored and WireMock fails to register stubs with this change we update the WireMock instance to include the context path fixes #99 --- README.adoc | 4 +- .../main/asciidoc/verifier/introduction.adoc | 4 +- docs/src/main/asciidoc/verifier/rest.adoc | 2 +- .../stubrunner/StubRunnerExecutor.java | 8 +- .../stubrunner/StubRunnerOptions.java | 32 +++++--- .../stubrunner/StubRunnerOptionsBuilder.java | 10 ++- .../cloud/contract/stubrunner/StubServer.java | 21 +++++- .../spring/StubRunnerConfiguration.java | 14 +++- .../contract/stubrunner/StubServerSpec.groovy | 4 +- .../stubrunner/TestStubRunnerOptions.groovy | 13 ++++ tests/pom.xml | 1 + .../pom.xml | 45 +++++++++++ .../java/com/example/loan/Application.java | 13 ++++ .../example/loan/LoanApplicationService.java | 70 ++++++++++++++++++ .../java/com/example/loan/model/Client.java | 21 ++++++ .../example/loan/model/FraudCheckStatus.java | 5 ++ .../loan/model/FraudServiceRequest.java | 34 +++++++++ .../loan/model/FraudServiceResponse.java | 27 +++++++ .../example/loan/model/LoanApplication.java | 44 +++++++++++ .../loan/model/LoanApplicationResult.java | 32 ++++++++ .../loan/model/LoanApplicationStatus.java | 5 ++ .../src/main/resources/application.yml | 2 + .../loan/LoanApplicationServiceTests.java | 63 ++++++++++++++++ ...udDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1897 bytes .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 25 +++++++ .../fraudDetectionServer/maven-metadata.xml | 28 +++++++ 26 files changed, 498 insertions(+), 29 deletions(-) create mode 100644 spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/TestStubRunnerOptions.groovy create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/pom.xml create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/Application.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/LoanApplicationService.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/Client.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudCheckStatus.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceRequest.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceResponse.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplication.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationResult.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationStatus.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/main/resources/application.yml create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom create mode 100644 tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml diff --git a/README.adoc b/README.adoc index c4c64fa5b6..bef21750e4 100644 --- a/README.adoc +++ b/README.adoc @@ -632,7 +632,7 @@ The aforementioned contract is an agreement between two sides that: - if an HTTP request is sent with ** a method `PUT` on an endpoint `/fraudcheck` -** JSON body with `clientId` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999` +** JSON body with `clientPesel` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999` ** and with a header `Content-Type` equal to `application/vnd.fraud.v1+json` - then an HTTP response would be sent to the consumer that ** has status `200` @@ -875,7 +875,7 @@ public void validate_shouldMarkClientAsFraud() throws Exception { // given: MockMvcRequestSpecification request = given() .header("Content-Type", "application/vnd.fraud.v1+json") - .body("{\"clientId\":\"1234567890\",\"loanAmount\":99999}"); + .body("{\"clientPesel\":\"1234567890\",\"loanAmount\":99999}"); // when: ResponseOptions response = given().spec(request) diff --git a/docs/src/main/asciidoc/verifier/introduction.adoc b/docs/src/main/asciidoc/verifier/introduction.adoc index 4bc644683e..babec72446 100644 --- a/docs/src/main/asciidoc/verifier/introduction.adoc +++ b/docs/src/main/asciidoc/verifier/introduction.adoc @@ -201,7 +201,7 @@ The aforementioned contract is an agreement between two sides that: - if an HTTP request is sent with ** a method `PUT` on an endpoint `/fraudcheck` -** JSON body with `clientId` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999` +** JSON body with `clientPesel` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999` ** and with a header `Content-Type` equal to `application/vnd.fraud.v1+json` - then an HTTP response would be sent to the consumer that ** has status `200` @@ -375,7 +375,7 @@ public void validate_shouldMarkClientAsFraud() throws Exception { // given: MockMvcRequestSpecification request = given() .header("Content-Type", "application/vnd.fraud.v1+json") - .body("{\"clientId\":\"1234567890\",\"loanAmount\":99999}"); + .body("{\"clientPesel\":\"1234567890\",\"loanAmount\":99999}"); // when: ResponseOptions response = given().spec(request) diff --git a/docs/src/main/asciidoc/verifier/rest.adoc b/docs/src/main/asciidoc/verifier/rest.adoc index 9633291fbc..8e8d72d209 100644 --- a/docs/src/main/asciidoc/verifier/rest.adoc +++ b/docs/src/main/asciidoc/verifier/rest.adoc @@ -285,7 +285,7 @@ class LoanApplicationServiceSpec extends Specification { def 'should successfully apply for loan'() { given: LoanApplication application = - new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) + new LoanApplication(client: new Client(clientPesel: '12345678901'), amount: 123.123) when: LoanApplicationResult loanApplication == sut.loanApplication(application) then: 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 600f7c3c74..d66c1e87b1 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 @@ -196,7 +196,7 @@ class StubRunnerExecutor implements StubFinder { return condition ? this.stubServer.getStubUrl() : null; } - private void startStubServers(StubRunnerOptions stubRunnerOptions, + private void startStubServers(final StubRunnerOptions stubRunnerOptions, final StubConfiguration stubConfiguration, StubRepository repository) { final List mappings = repository .getProjectDescriptors(); @@ -206,7 +206,7 @@ class StubRunnerExecutor implements StubFinder { if (log.isDebugEnabled()) { log.debug("There are no HTTP related contracts. Won't start any servers"); } - this.stubServer = new StubServer(stubConfiguration, mappings, contracts, new NoOpHttpServerStub()); + this.stubServer = new StubServer(stubRunnerOptions, stubConfiguration, mappings, contracts, new NoOpHttpServerStub()); return; } if (contracts.isEmpty()) { @@ -215,14 +215,14 @@ class StubRunnerExecutor implements StubFinder { + "that's why will start the server - maybe you know what you're doing..."); } if (port != null && port >= 0) { - this.stubServer = new StubServer(stubConfiguration, mappings, contracts, + 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(stubConfiguration, + return new StubServer(stubRunnerOptions, stubConfiguration, mappings, contracts, new WireMockHttpServerStub(availablePort)); } 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 09d4323a2a..7aac4762e8 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 @@ -61,6 +61,11 @@ 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, @@ -72,6 +77,21 @@ 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, + 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; } public Integer port(StubConfiguration stubConfiguration) { @@ -90,18 +110,6 @@ public class StubRunnerOptions { return this.maxPortValue; } - public String getStubRepositoryRoot() { - return this.stubRepositoryRoot; - } - - public boolean isWorkOffline() { - return this.workOffline; - } - - public String getStubsClassifier() { - return this.stubsClassifier; - } - public Collection getDependencies() { return this.dependencies; } 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 c52376c5e4..515be3fd5a 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,6 +37,7 @@ public class StubRunnerOptionsBuilder { private String stubRepositoryRoot; private boolean workOffline = false; private String stubsClassifier = "stubs"; + private String contextPath = ""; public StubRunnerOptionsBuilder() { } @@ -95,18 +96,25 @@ public class StubRunnerOptionsBuilder { return this; } + public StubRunnerOptionsBuilder withContextPath(String contextPath) { + this.contextPath = contextPath; + return this; + } + public StubRunnerOptionsBuilder withOptions(StubRunnerOptions options) { this.minPortValue = options.minPortValue; this.maxPortValue = options.maxPortValue; 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.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping, + this.contextPath); } 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 73e25554ea..fd489f6b3c 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,6 +23,7 @@ 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; @@ -34,9 +35,11 @@ class StubServer { final StubConfiguration stubConfiguration; final Collection mappings; final Collection contracts; + private final StubRunnerOptions stubRunnerOptions; - StubServer(StubConfiguration stubConfiguration, Collection mappings, - Collection contracts, HttpServerStub httpServerStub) { + StubServer(StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration, + Collection mappings, Collection contracts, HttpServerStub httpServerStub) { + this.stubRunnerOptions = stubRunnerOptions; this.stubConfiguration = stubConfiguration; this.mappings = mappings; this.httpServerStub = httpServerStub; @@ -68,13 +71,23 @@ class StubServer { public URL getStubUrl() { try { - return new URL("http://localhost:" + getPort()); + return new URL("http://localhost:" + getPort() + prependSlashIfNecessary(this.stubRunnerOptions.contextPath)); } 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; } @@ -84,7 +97,7 @@ class StubServer { } private void registerStubMappings() { - WireMock wireMock = new WireMock("localhost", this.httpServerStub.port()); + WireMock wireMock = new WireMock("localhost", this.httpServerStub.port(), prependSlashIfNecessary(this.stubRunnerOptions.contextPath)); registerDefaultHealthChecks(wireMock); registerStubs(this.mappings, wireMock); } 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 ce617c87b0..b1f7b58fe7 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,6 +20,7 @@ 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; @@ -48,6 +49,8 @@ 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 @@ -63,7 +66,9 @@ public class StubRunnerConfiguration { .withWorkOffline(this.props.getRepositoryRoot() == null || this.props.isWorkOffline()) .withStubsClassifier(this.props.getClassifier()) - .withStubs(this.props.getIds()).build(); + .withStubs(this.props.getIds()) + .withContextPath(contextPath()) + .build(); BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, this.stubDownloader != null ? this.stubDownloader : new AetherStubDownloader(stubRunnerOptions), @@ -78,4 +83,11 @@ 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/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 bee5ab6820..a7bd585c31 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(stubConfiguration, mappingDescriptors, [], + StubServer pingStubServer = new StubServer(new TestStubRunnerOptions(), 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(stubConfiguration, mappingDescriptors, [], + StubServer pingStubServer = new StubServer(new TestStubRunnerOptions(), 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 new file mode 100644 index 0000000000..19c287d977 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/TestStubRunnerOptions.groovy @@ -0,0 +1,13 @@ +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/tests/pom.xml b/tests/pom.xml index ed4fc80f3e..eb3f9d028d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -25,6 +25,7 @@ spring-cloud-contract-stub-runner-boot-eureka spring-cloud-contract-stub-runner-boot-zookeeper spring-cloud-contract-stub-runner-camel + spring-cloud-contract-stub-runner-context-path spring-cloud-contract-stub-runner-integration spring-cloud-contract-stub-runner-stream diff --git a/tests/spring-cloud-contract-stub-runner-context-path/pom.xml b/tests/spring-cloud-contract-stub-runner-context-path/pom.xml new file mode 100644 index 0000000000..58ba9e5b4d --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-contract-tests + 1.0.1.BUILD-SNAPSHOT + .. + + spring-cloud-contract-stub-runner-context-path + jar + Spring Cloud Contract Stub Runner With Context Path + Spring Cloud Contract Stub Runner With Context Path + + 1.8 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.cloud + spring-cloud-starter-contract-stub-runner + test + + + junit + junit + test + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/Application.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/Application.java new file mode 100644 index 0000000000..6f36301172 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/Application.java @@ -0,0 +1,13 @@ +package com.example.loan; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/LoanApplicationService.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/LoanApplicationService.java new file mode 100644 index 0000000000..6bc690e4e4 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/LoanApplicationService.java @@ -0,0 +1,70 @@ +package com.example.loan; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import com.example.loan.model.FraudCheckStatus; +import com.example.loan.model.FraudServiceRequest; +import com.example.loan.model.FraudServiceResponse; +import com.example.loan.model.LoanApplication; +import com.example.loan.model.LoanApplicationResult; +import com.example.loan.model.LoanApplicationStatus; + +@Service +public class LoanApplicationService { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = + "application/vnd.fraud.v1+json"; + + private final RestTemplate restTemplate; + + private String fraudUrl = "http://localhost:8080"; + + public LoanApplicationService() { + this.restTemplate = new RestTemplate(); + } + + public LoanApplicationResult loanApplication(LoanApplication loanApplication) { + FraudServiceRequest request = + new FraudServiceRequest(loanApplication); + + FraudServiceResponse response = + sendRequestToFraudDetectionService(request); + + return buildResponseFromFraudResult(response); + } + + private FraudServiceResponse sendRequestToFraudDetectionService( + FraudServiceRequest request) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1); + + // tag::client_call_server[] + ResponseEntity response = + this.restTemplate.exchange(this.fraudUrl + "/fraudcheck", HttpMethod.PUT, + new HttpEntity<>(request, httpHeaders), + FraudServiceResponse.class); + // end::client_call_server[] + + return response.getBody(); + } + + private LoanApplicationResult buildResponseFromFraudResult(FraudServiceResponse response) { + LoanApplicationStatus applicationStatus = null; + if (FraudCheckStatus.OK == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLIED; + } else if (FraudCheckStatus.FRAUD == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLICATION_REJECTED; + } + + return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); + } + + public void setFraudUrl(String fraudUrl) { + this.fraudUrl = fraudUrl; + } +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/Client.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/Client.java new file mode 100644 index 0000000000..d588e93b4b --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/Client.java @@ -0,0 +1,21 @@ +package com.example.loan.model; + +public class Client { + + private String clientId; + + public Client() { + } + + public Client(String clientId) { + this.clientId = clientId; + } + + public String getClientId() { + return this.clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudCheckStatus.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudCheckStatus.java new file mode 100644 index 0000000000..c5217ef471 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.example.loan.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceRequest.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceRequest.java new file mode 100644 index 0000000000..85f3b37d06 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceRequest.java @@ -0,0 +1,34 @@ +package com.example.loan.model; + +import java.math.BigDecimal; + +public class FraudServiceRequest { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudServiceRequest() { + } + + public FraudServiceRequest(LoanApplication loanApplication) { + this.clientPesel = loanApplication.getClient().getClientId(); + this.loanAmount = loanApplication.getAmount(); + } + + public String getClientPesel() { + return this.clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return this.loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceResponse.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceResponse.java new file mode 100644 index 0000000000..eb5f64116d --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/FraudServiceResponse.java @@ -0,0 +1,27 @@ +package com.example.loan.model; + +public class FraudServiceResponse { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudServiceResponse() { + } + + public FraudCheckStatus getFraudCheckStatus() { + return this.fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return this.rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplication.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplication.java new file mode 100644 index 0000000000..85a7f8c5d9 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplication.java @@ -0,0 +1,44 @@ +package com.example.loan.model; + +import java.math.BigDecimal; + +public class LoanApplication { + + private Client client; + + private BigDecimal amount; + + private String loanApplicationId; + + public LoanApplication() { + } + + public LoanApplication(Client client, double amount) { + this.client = client; + this.amount = BigDecimal.valueOf(amount); + } + + public Client getClient() { + return this.client; + } + + public void setClient(Client client) { + this.client = client; + } + + public BigDecimal getAmount() { + return this.amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public String getLoanApplicationId() { + return this.loanApplicationId; + } + + public void setLoanApplicationId(String loanApplicationId) { + this.loanApplicationId = loanApplicationId; + } +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationResult.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationResult.java new file mode 100644 index 0000000000..5214e0d4f7 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationResult.java @@ -0,0 +1,32 @@ +package com.example.loan.model; + +public class LoanApplicationResult { + + private LoanApplicationStatus loanApplicationStatus; + + private String rejectionReason; + + public LoanApplicationResult() { + } + + public LoanApplicationResult(LoanApplicationStatus loanApplicationStatus, String rejectionReason) { + this.loanApplicationStatus = loanApplicationStatus; + this.rejectionReason = rejectionReason; + } + + public LoanApplicationStatus getLoanApplicationStatus() { + return this.loanApplicationStatus; + } + + public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { + this.loanApplicationStatus = loanApplicationStatus; + } + + public String getRejectionReason() { + return this.rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationStatus.java b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationStatus.java new file mode 100644 index 0000000000..34cf91a89f --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/java/com/example/loan/model/LoanApplicationStatus.java @@ -0,0 +1,5 @@ +package com.example.loan.model; + +public enum LoanApplicationStatus { + LOAN_APPLIED, LOAN_APPLICATION_REJECTED +} diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/main/resources/application.yml b/tests/spring-cloud-contract-stub-runner-context-path/src/main/resources/application.yml new file mode 100644 index 0000000000..0d28926451 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/main/resources/application.yml @@ -0,0 +1,2 @@ +server.port: 0 +server.context-path: /my-path \ No newline at end of file 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 new file mode 100644 index 0000000000..785d1339ad --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/java/com/example/loan/LoanApplicationServiceTests.java @@ -0,0 +1,63 @@ +package com.example.loan; + +import org.junit.Before; +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.StubFinder; +import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; +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 +@AutoConfigureStubRunner(repositoryRoot = "classpath:m2repo/repository/", + ids = { "org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer" }) +public class LoanApplicationServiceTests { +// end::autoconfigure_stubrunner[] + + @Autowired private LoanApplicationService service; + @Autowired private StubFinder stubFinder; + + @Before + public void setPort() { + this.service.setFraudUrl(this.stubFinder.findStubUrl("fraudDetectionServer").toString()); + } + + @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/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..fdb70e383f00ec1a31fd06d81aa618347b8aa5b3 GIT binary patch literal 1897 zcmWIWW@h1HVBp|jSmxB}!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9Q}aq3i`_uh=w%h>=Y@uFGBCR?

Ai(h6<{MwahD zlUYEPO`YKDf7pPh?fqZTiLE9AOJ5&*uI6jNTlgTP_uZB^0#VLZo0gcoT$1^!Uj3xi zi^3-YC+prG|F)Z-qmgTW_7%1hGv4Ip7?-NXu>9@sx>|Y6@ORS(h1?4TQ>#rQmmGhy z`&2onF`M?vx!ZC)*ELFVUsxaI8GW$!`OQxs|7Z$zoqXwb_0oisEj@R3M>M|AJ`~I_ zQzKv&iz%1;3*NTt=G)7^^Do}5`^e1o3HeZ_Sr<~2P( zH|KW#zDb8>96DXIt74fzkatY-vuQJwH#hIS^(%df(w-krM5KNk-@82KnLgJnc~DA1 zM2gvpoP`p=ppybdiXAzT;+J1SY`mQHJ8U4(^1hZUyEQ~W(f4%yQm%mf0)?i6tSW<( ziv-!GI;H&mEnmgsMH^J#SL~lVH|>DLl^@B0(h0%WF3i^2CiaeX@%mY}ZL|%3 zweJikKn{gkJOx;e1dsn^|PRW04*WXbl^_R{e!^wjnA)jN6SJhz{&mbWg`>|>$aKwmL3i7?|X+JN2z0s)4% zjvyLd(4lKXFX%vuL10OvCXj?{Ln`*rO#rDzE>l5#h{a_<8eW9q(*`Q*AOPgv`9LOI z8}^b9WSAT?B2rOHJ_)c{z&yv$(0GrqVff2IR!BLBRtBOw05z8*JD?aCHUxZw=>W7m lPn;W2Q#P_2m|2K)16n%AWiKlmD1_O8unOqAn?TbU7yzYKYMcN7 literal 0 HcmV?d00001 diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..40610c8cdb --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + pom + diff --git a/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml new file mode 100644 index 0000000000..281b9b3b80 --- /dev/null +++ b/tests/spring-cloud-contract-stub-runner-context-path/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + +