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
This commit is contained in:
189
README.adoc
189
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]
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>Server Stubs</name>
|
||||
<description>POM used to install locally stubs for consumer side</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud-contract.version>1.0.0.BUILD-SNAPSHOT</spring-cloud-contract.version>
|
||||
<spring-cloud-dependencies.version>Camden.BUILD-SNAPSHOT</spring-cloud-dependencies.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud-dependencies.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<!-- By default it would search under src/test/resources/ -->
|
||||
<contractsDirectory>${project.basedir}</contractsDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
----
|
||||
|
||||
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]
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example.standalone</groupId>
|
||||
<artifactId>contracts</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>Spring Cloud Contract Verifier Http Server Sample</name>
|
||||
<description>Spring Cloud Contract Verifier Http Server Sample</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>contracts</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<attach>true</attach>
|
||||
<descriptor>${basedir}/src/assembly/contracts.xml</descriptor>
|
||||
<!-- If you want an explicit classifier remove the following line -->
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
----
|
||||
|
||||
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]
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
|
||||
<id>project</id>
|
||||
<formats>
|
||||
<format>jar</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<excludes>
|
||||
<exclude>**/${project.build.directory}/**</exclude>
|
||||
<exclude>mvnw</exclude>
|
||||
<exclude>mvnw.cmd</exclude>
|
||||
<exclude>.mvn/**</exclude>
|
||||
<exclude>src/**</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
----
|
||||
|
||||
*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]
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<contractsRepositoryUrl>http://link/to/your/nexus/or/artifactory/or/sth</contractsRepositoryUrl>
|
||||
<contractDependency>
|
||||
<groupId>com.example.standalone</groupId>
|
||||
<artifactId>contracts</artifactId>
|
||||
</contractDependency>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
|
||||
With this setup the JAR with groupid `com.example.standalone` and artifactid `contracts` will be downloaded
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -115,7 +115,7 @@ class StubRunnerDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
private List<ServiceInstance> 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<String> getServices() {
|
||||
List<String> list = new ArrayList<>();
|
||||
List<String> services = getServicesFromDelegate();
|
||||
RunningStubs runningStubs = this.stubFinder.findAllRunningStubs();
|
||||
services.addAll(runningStubs.getAllServicesNames());
|
||||
return services;
|
||||
list.addAll(services);
|
||||
list.addAll(runningStubs.getAllServicesNames());
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user