From 788b35aedb907afc73cff5a3122d765dcb27d6cb Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 23 Sep 2016 10:40:57 +0200 Subject: [PATCH] Stubbing service discovery out completely without this change if you have a DiscoveryClient bean it's used for delegation. For tests with Stub Runner actually we don't want to delegate. There is an option however to turn on this delegation fixes #82 --- README.adoc | 189 +++++++++++++++++- spring-cloud-contract-stub-runner/README.adoc | 5 + .../cloud/StubRunnerDiscoveryClient.java | 10 +- ...tubRunnerSpringCloudAutoConfiguration.java | 8 +- 4 files changed, 200 insertions(+), 12 deletions(-) diff --git a/README.adoc b/README.adoc index 4d492e96b2..35ac8d816b 100644 --- a/README.adoc +++ b/README.adoc @@ -1276,7 +1276,114 @@ Example of a `pom.xml` inside the `server` folder. [source,xml,indent=0] ---- -Unresolved directive in verifier/introduction.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/samples/standalone/contracts/com/example/server/pom.xml[indent=0] + + + 4.0.0 + + com.example + server + 0.0.1-SNAPSHOT + + Server Stubs + POM used to install locally stubs for consumer side + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.BUILD-SNAPSHOT + + + + + UTF-8 + 1.8 + 1.0.0.BUILD-SNAPSHOT + Camden.BUILD-SNAPSHOT + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud-dependencies.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-contract-maven-plugin + ${spring-cloud-contract.version} + true + + + ${project.basedir} + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + +---- As you can see there are no dependencies other than the Spring Cloud Contract Verifier Maven plugin. Those poms are necessary for the consumer side to run `mvn clean install -DskipTests` to locally install @@ -1286,13 +1393,77 @@ The `pom.xml` in the root folder can look like this: [source,xml,indent=0] ---- -Unresolved directive in verifier/introduction.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/samples/standalone/contracts/pom.xml[indent=0] + + + 4.0.0 + + com.example.standalone + contracts + 0.0.1-SNAPSHOT + + Spring Cloud Contract Verifier Http Server Sample + Spring Cloud Contract Verifier Http Server Sample + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + contracts + prepare-package + + single + + + true + ${basedir}/src/assembly/contracts.xml + + false + + + + + + + + +---- It's using the assembly plugin in order to build the JAR with all the contracts. Example of such setup is here: [source,xml,indent=0] ---- -Unresolved directive in verifier/introduction.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/samples/standalone/contracts/src/assembly/contracts.xml[indent=0] + + project + + jar + + false + + + ${project.basedir} + / + true + + **/${project.build.directory}/** + mvnw + mvnw.cmd + .mvn/** + src/** + + + + +---- *Workflow* @@ -1315,7 +1486,17 @@ of the JAR containing the contracts: [source,xml,indent=0] ---- -Unresolved directive in verifier/introduction.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/basic-remote-contracts/pom-with-repo.xml[tags=remote_config,indent=0] + + org.springframework.cloud + spring-cloud-contract-maven-plugin + + http://link/to/your/nexus/or/artifactory/or/sth + + com.example.standalone + contracts + + + ---- With this setup the JAR with groupid `com.example.standalone` and artifactid `contracts` will be downloaded diff --git a/spring-cloud-contract-stub-runner/README.adoc b/spring-cloud-contract-stub-runner/README.adoc index ab3906ba65..ed144ddd8c 100644 --- a/spring-cloud-contract-stub-runner/README.adoc +++ b/spring-cloud-contract-stub-runner/README.adoc @@ -195,6 +195,11 @@ You can match the artifactId of the stub with the name of your app by using the You can disable Stub Runner Ribbon support by providing: `stubrunner.cloud.ribbon.enabled` equal to `false` You can disable Stub Runner support by providing: `stubrunner.cloud.enabled` equal to `false` +TIP: By default all service discovery will be stubbed. That means that regardless of the fact if you have +an existing `DiscoveryClient` its results will be ignored. However, if you want to reuse it, just set + `stubrunner.cloud.delegate.enabled` to `true` and then your existing `DiscoveryClient` results will be + merged with the stubbed ones. + === Stub Runner Boot Application Spring Cloud Contract Verifier Stub Runner Boot is a Spring Boot application that exposes REST endpoints to diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java index 212fbec3e7..c115444aee 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java @@ -115,7 +115,7 @@ class StubRunnerDiscoveryClient implements DiscoveryClient { private List getInstancesFromDelegate(String serviceId) { try { - return this.delegate.getInstances(serviceId); + return new ArrayList<>(this.delegate.getInstances(serviceId)); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("Failed to fetch instances from delegate", e); @@ -134,15 +134,17 @@ class StubRunnerDiscoveryClient implements DiscoveryClient { @Override public List getServices() { + List list = new ArrayList<>(); List services = getServicesFromDelegate(); RunningStubs runningStubs = this.stubFinder.findAllRunningStubs(); - services.addAll(runningStubs.getAllServicesNames()); - return services; + list.addAll(services); + list.addAll(runningStubs.getAllServicesNames()); + return list; } private List getServicesFromDelegate() { try { - return this.delegate.getServices(); + return new ArrayList<>(this.delegate.getServices()); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("Failed to fetch services from delegate", e); diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java index b6909cd324..3d635d4222 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java @@ -19,7 +19,6 @@ package org.springframework.cloud.contract.stubrunner.spring.cloud; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.discovery.DiscoveryClient; @@ -41,9 +40,10 @@ import org.springframework.context.annotation.Primary; public class StubRunnerSpringCloudAutoConfiguration { @Bean - @ConditionalOnBean(DiscoveryClient.class) @Primary + @ConditionalOnBean(DiscoveryClient.class) @ConditionalOnStubbedDiscoveryEnabled + @ConditionalOnProperty(value = "stubrunner.cloud.delegate.enabled", havingValue = "true") public DiscoveryClient stubRunnerDiscoveryClientWrapper(DiscoveryClient discoveryClient, StubFinder stubFinder, StubMapperProperties stubMapperProperties, @@ -53,9 +53,9 @@ public class StubRunnerSpringCloudAutoConfiguration { @Bean @Primary - @ConditionalOnMissingBean(DiscoveryClient.class) @ConditionalOnStubbedDiscoveryEnabled - public DiscoveryClient stubRunnerDiscoveryClient(StubFinder stubFinder, + @ConditionalOnProperty(value = "stubrunner.cloud.delegate.enabled", havingValue = "false", matchIfMissing = true) + public DiscoveryClient noOpStubRunnerDiscoveryClient(StubFinder stubFinder, StubMapperProperties stubMapperProperties, @Value("${spring.application.name:unknown}") String springAppName) { return new StubRunnerDiscoveryClient(stubFinder, stubMapperProperties, springAppName);