Consumer Contracts (#83)
With this functionality you can have one centralized repository containing all contracts. This repo will have to produce a JAR containing all contracts. The layout of the repository can be arbitrary but some sensible defaults are assumed. The producer will be able to then download that JAR and produce tests and stubs from it. fixes #38
This commit is contained in:
committed by
GitHub
parent
93782cb049
commit
01f4ad76be
@@ -120,6 +120,9 @@ going through the process. CDC is all about communication.
|
||||
|
||||
The https://github.com/spring-cloud/spring-cloud-contract/tree/master/samples/standalone/dsl/http-server[server side code is available here] and https://github.com/spring-cloud/spring-cloud-contract/tree/master/samples/standalone/dsl/http-client[the client side code here].
|
||||
|
||||
TIP: In this case the ownership of the contracts lays on the producer side. It means that physically
|
||||
all the contract are present in the producer's repository
|
||||
|
||||
===== Technical note
|
||||
|
||||
If using the *SNAPSHOT* / *Milestone* / *Release Candidate* versions please add the following section to your
|
||||
@@ -720,4 +723,99 @@ Example of tests using production version of stubs
|
||||
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:prod-stubs:8080"})
|
||||
----
|
||||
|
||||
You can pass those values also via properties from your deployment pipeline.
|
||||
You can pass those values also via properties from your deployment pipeline.
|
||||
|
||||
===== Common repo with contracts
|
||||
|
||||
Another way of storing contracts other than having them with the producer is keeping them in a common place.
|
||||
It can be related to security issues where the consumers can't clone the producer's code. Also if you keep
|
||||
contracts in a single place then you, as a producer, will know how many consumers you have and which
|
||||
consumer will you break with your local changes.
|
||||
|
||||
* Repo structure *
|
||||
|
||||
Let's assume that we have a producer with coordinates `com.example:server` and 3 consumers: `client1`,
|
||||
`client2`, `client3`. Then in the repository with common contracts you would have the following setup
|
||||
(which you can checkout https://github.com/spring-cloud/spring-cloud-contract/tree/master/samples/standalone/contracts[here]:
|
||||
|
||||
[source,bash,indent=0]
|
||||
----
|
||||
├── com
|
||||
│ └── example
|
||||
│ └── server
|
||||
│ ├── client1
|
||||
│ │ └── expectation.groovy
|
||||
│ ├── client2
|
||||
│ │ └── expectation.groovy
|
||||
│ ├── client3
|
||||
│ │ └── expectation.groovy
|
||||
│ └── pom.xml
|
||||
├── mvnw
|
||||
├── mvnw.cmd
|
||||
├── pom.xml
|
||||
└── src
|
||||
└── assembly
|
||||
└── contracts.xml
|
||||
----
|
||||
|
||||
As you can see the under the slash-delimited groupid `/` artifact id folder (`com/example/server`) you have
|
||||
expectations of the 3 consumers (`client1`, `client2` and `client3`). Expectations are the standard Groovy DSL
|
||||
contract files as described throughout this documentation. This repository has to produce a JAR file that maps
|
||||
one to one to the contents of the repo.
|
||||
|
||||
Example of a `pom.xml` inside the `server` folder.
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include::{introduction_url}/samples/standalone/contracts/com/example/server/pom.xml[indent=0]
|
||||
----
|
||||
|
||||
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
|
||||
stubs of the producer project.
|
||||
|
||||
The `pom.xml` in the root folder can look like this:
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include::{introduction_url}/samples/standalone/contracts/pom.xml[indent=0]
|
||||
----
|
||||
|
||||
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]
|
||||
----
|
||||
include::{introduction_url}/samples/standalone/contracts/src/assembly/contracts.xml[indent=0]
|
||||
----
|
||||
|
||||
*Workflow*
|
||||
|
||||
The workflow would look similar to the one presented in the `Step by step guide to CDC`. The only difference
|
||||
is that the producer doesn't own the contracts anymore. So the consumer and the producer have to work on
|
||||
common contracts in a common repository.
|
||||
|
||||
_Consumer_
|
||||
|
||||
When the *consumer* wants to work on the contracts offline, instead of cloning the producer code, the
|
||||
consumer team clones the common repository, goes to the required producer's folder (e.g. `com/example/server`)
|
||||
and runs `mvn clean install -DskipTests` to install locally the stubs converted from the contracts.
|
||||
|
||||
TIP: You need to have http://maven.apache.org/download.cgi[Maven installed locally]
|
||||
|
||||
_Producer_
|
||||
|
||||
As a *producer* it's enough to alter the Spring Cloud Contract Verifier to provide the URL and the dependency
|
||||
of the JAR containing the contracts:
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include::{introduction_url}/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/basic-remote-contracts/pom-with-repo.xml[tags=remote_config,indent=0]
|
||||
----
|
||||
|
||||
With this setup the JAR with groupid `com.example.standalone` and artifactid `contracts` will be downloaded
|
||||
from `http://link/to/your/nexus/or/artifactory/or/sth`. It will be then unpacked in a local temporary folder
|
||||
and contracts present under the `com/example/server` will be picked as the ones used to generate the
|
||||
tests and the stubs. Due to this convention the producer team will know which consumer teams will be broken
|
||||
when some incompatible changes are done.
|
||||
|
||||
The rest of the flow looks the same.
|
||||
@@ -129,6 +129,11 @@ contracts {
|
||||
contractsDslDir = "${project.rootDir}/src/test/resources/contracts"
|
||||
basePackageForTests = 'org.springframework.cloud.verifier.tests'
|
||||
stubsOutputDir = project.file("${project.buildDir}/stubs")
|
||||
|
||||
// the following properties are used when you want to provide where the JAR with contract lays
|
||||
contractDependency = new org.springframework.cloud.contract.verifier.plugin.ContractVerifierExtension.Dependency()
|
||||
contractsPath = ''
|
||||
contractsWorkOffline = false
|
||||
}
|
||||
|
||||
tasks.create(type: Jar, name: 'verifierStubsJar', dependsOn: 'generateWireMockClientStubs') {
|
||||
@@ -185,6 +190,12 @@ contracts {
|
||||
- **stubsOutputDir** - dir where the generated WireMock stubs from Groovy DSL should be placed
|
||||
- **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework
|
||||
|
||||
The following properties are used when you want to provide where the JAR with contract lays
|
||||
|
||||
- **contractDependency** - the Dependency that provides `groupid:artifactid:version:classifier` coordinates. You can use the `contractDependency` closure to set it up
|
||||
- **contractsPath** - if contract deps are downloaded will default to `groupid/artifactid` where `groupid` will be slash separated. Otherwise will scan contracts under provided directory
|
||||
- **contractsWorkOffline** - in order not to download the dependencies each time you can download them once and work offline afterwards (reuse local Maven repo)
|
||||
|
||||
====== Base class for tests
|
||||
|
||||
When using Spring Cloud Contract Verifier in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified.
|
||||
@@ -331,6 +342,13 @@ To change default configuration just add `configuration` section to plugin defin
|
||||
- **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/resources/contracts`.
|
||||
- **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework
|
||||
|
||||
If you want to download your contract definitions from a Maven repository you can use
|
||||
|
||||
- **contractsRepositoryUrl** - URL to a repo with the artifacts with contracts, if not provided should use the current Maven ones
|
||||
- **contractDependency** - the contract dependency that contains all the packaged contracts
|
||||
- **contractsPath** - path to concrete contracts in the JAR with packaged contracts. Defaults to `groupid/artifactid` where `gropuid` is slash separated.
|
||||
- **contractsWorkOffline** - if the dependencies should be downloaded or local Maven only should be reused
|
||||
|
||||
For complete information take a look at https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/plugin-info.html[Plugin Documentation]
|
||||
|
||||
====== Base class for tests
|
||||
|
||||
Reference in New Issue
Block a user