Added more workflows

This commit is contained in:
Marcin Grzejszczak
2019-07-22 15:11:48 +02:00
parent 6a408f9a05
commit 6aca340f71
4 changed files with 346 additions and 39 deletions

View File

@@ -31,4 +31,4 @@
:tests_path: {core_path}/tests
:samples_branch: 2.2.x
:samples_url: https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/{samples_branch}
:introduction_url: ${core_path}/../../
:introduction_url: {core_path}/..

View File

@@ -134,7 +134,7 @@ This very brief tour walks through using Spring Cloud Contract:
You can find a somewhat longer tour
<<getting-started-first-application,here>>.
[plantuml, three-second, png]
[plantuml, getting-started-three-second, png]
----
"API Producer"->"API Producer": add Spring Cloud \nContract (SCC) plugin
"API Producer"->"API Producer": add SCC Verifier dependency
@@ -574,7 +574,7 @@ to the following in the build logs:
----
[[getting-started-cdc]]
== Step-by-step Guide to Consumer Driven Contracts (CDC)
== Step-by-step Guide to Consumer Driven Contracts (CDC) with contracts laying on the producer side
Consider an example of Fraud Detection and the Loan Issuance process. The business
scenario is such that we want to issue loans to people but do not want them to steal from
@@ -615,6 +615,12 @@ include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=repo
include::{introduction_url}/samples/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0]
----
For simplicity we will use the following acronyms:
- Loan Issuance - LI - the http client
- Fraud Detection - FD - the http server
- Spring Cloud Contract - SCC
=== Consumer side (Loan Issuance)
As a developer of the Loan Issuance service (a consumer of the Fraud Detection server), you might do the following steps:
@@ -632,26 +638,34 @@ As a developer of the Loan Issuance service (a consumer of the Fraud Detection s
. Deploy your app.
. Work online.
[plantuml, cdc, png]
Let's start with the Loan Issuance flow:
[plantuml, getting-started-cdc-client, png]
----
"Loan Issuance"->"Loan Issuance": start doing TDD\nby writing a test\nfor your feature
"Loan Issuance"->"Loan Issuance": write the \nmissing implementation
"Loan Issuance"->"Fraud Detection": clone the repository
"Loan Issuance"->"Fraud Detection Clone": start working on the clone
"Fraud Detection Clone"->"Fraud Detection Clone": add missing dependencies\ndefine contracts
"Fraud Detection Clone"->"Fraud Detection Clone": add the Spring Cloud \nContract plugin
"Fraud Detection Clone"->"Fraud Detection \nClone Build": install the stubs locally
"Fraud Detection \nClone Build"->"SCC Plugin": generate stubs \nand stubs \nartifact (e.g. stubs-jar)
"Fraud Detection \nClone Build"->"Local storage": install the stubs locally
"Local storage"->"Fraud Detection Build": stub sucessfully installed
"Fraud Detection Build"->"API Producer": Build successful
"API Consumer"->"API Consumer": add SCC Stub Runner \ndependency
"API Consumer"->"API Consumer": write a SCC Stub Runner \nbased contract test
"SCC Stub Runner"->"Nexus / Artifactory": test asks for [API Producer] stubs
"Nexus / Artifactory"->"SCC Stub Runner": fetch the [API Producer] stubs
"SCC Stub Runner"->"SCC Stub Runner": run in memory\n HTTP server stubs
"API Consumer"->"SCC Stub Runner": send a request \nto the HTTP server stub
"SCC Stub Runner"->"API Consumer": communication is correct
"Loan\nIssuance"->"Loan\nIssuance": start doing TDD\nby writing a test\nfor your feature
"Loan\nIssuance"->"Loan\nIssuance": write the \nmissing implementation
"Loan\nIssuance"->"Loan\nIssuance": run a test - it fails\ndue to no server running
"Loan\nIssuance"->"Fraud\nDetection\nClone": clone the repository
"Fraud\nDetection\nClone"->"Fraud\nDetection\nClone": add missing dependencies\n& define contracts
"Fraud\nDetection\nClone"->"Fraud\nDetection\nClone": add the SCC plugin
"Fraud\nDetection\nClone"->"FD \nClone Build": install the stubs locally
"FD \nClone Build"->"SCC Plugin \nin FD Clone": generate stubs \nand stubs \nartifact (e.g. stubs-jar)
"SCC Plugin \nin FD Clone"->"FD \nClone Build": stubs and artifacts\ngenerated
"FD \nClone Build"->"Local storage": install the stubs locally
"Local storage"->"FD \nClone Build": stub sucessfully installed
"FD \nClone Build"->"Fraud\nDetection\nClone": build successful
"Loan\nIssuance"->"Loan\nIssuance": add a SCC\nStub Runner\ndependency\nand setup
"Loan\nIssuance"->"LI\nSCC\nStub Runner": start stubs\nof FD from\nlocal storage
"LI\nSCC\nStub Runner"->"Local storage": find stubs of [FD]
"Local storage"->"LI\nSCC\nStub Runner": stubs of [FD] found
"LI\nSCC\nStub Runner"->"FD stub": run stubs of [FD]
"FD stub"->"LI\nSCC\nStub Runner": [FD] stub is running
"LI\nSCC\nStub Runner"->"Loan\nIssuance": stubs running and ready for the test
"Loan\nIssuance"->"Loan\nIssuance": run a test
"Loan\nIssuance"->"FD stub": the test\nsends a request\nto the running stub
"FD stub"->"Loan\nIssuance": stub responds successfuly
"Loan\nIssuance"->"Loan\nIssuance": the test passes successfully
"Loan\nIssuance"->"Fraud\nDetection": send a pull request\nwith the\nsuggested contracts
----
*Start doing TDD by writing a test for your feature.*
@@ -721,6 +735,7 @@ of an identifier or a timestamp, you need not hardcode a value. You want to allo
different ranges of values. To enable ranges of values, you can set regular expressions
matching those values for the consumer side. You can provide the body by means of either
a map notation or String with interpolations.
//TODO: Ensure that the links are correct
Consult the <<contract-dsl>> section for more information. We highly recommend using the map notation!
TIP: You must understand the map notation in order to set up contracts. Please read the
@@ -860,9 +875,35 @@ the server side. Currently, the consumer side work is done.
=== Producer side (Fraud Detection server)
As a developer of the Fraud Detection server (a server to the Loan Issuance service):
As a developer of the Fraud Detection server (a server to the Loan Issuance service) we would like to:
*Create an initial implementation.*
- take over the pull request
- write the missing implementation
- deploy the application
Let's look at the Fraud Detection flow:
[plantuml, getting-started-cdc-server, png]
----
"Fraud\nDetection"->"Fraud\nDetection": take over the\n pull request
"Fraud\nDetection"->"Fraud\nDetection": setup\nSpring Cloud\nContract plugin
"Fraud\nDetection"->"Fraud\nDetection\nBuild": run the build
"Fraud\nDetection\nBuild"->"SCC Plugin": generate tests\nstubs \nand stubs artifact \n(e.g. stubs-jar)
"SCC Plugin"->"Fraud\nDetection\nBuild": tests and stubs generated
"Fraud\nDetection\nBuild"->"Fraud\nDetection\nBuild": run tests
"Fraud\nDetection\nBuild"->"Fraud\nDetection": generated tests failed!
"Fraud\nDetection"->"Fraud\nDetection": setup\nbase classes\nfor contract tests
"Fraud\nDetection"->"Fraud\nDetection\nBuild": run the build
"Fraud\nDetection\nBuild"->"SCC Plugin": generate tests\nstubs \nand stubs artifact \n(e.g. stubs-jar)
"SCC Plugin"->"Fraud\nDetection\nBuild": tests and stubs generated
"Fraud\nDetection\nBuild"->"Fraud\nDetection\nBuild": run tests
"Fraud\nDetection\nBuild"->"Fraud\nDetection": all the tests passed!
"Fraud\nDetection"->"Fraud\nDetection": commit and push changes
"Fraud\nDetection"->"CI": commit pushed!\nTriggers the build
"CI"->"Nexus / Artifactory": build successful,\nupload artifacts
----
*Take over the pull request.*
As a reminder, you can see the initial implementation here:
@@ -873,8 +914,6 @@ include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com
}
----
*Take over the pull request.*
[source,bash,indent=0]
----
$ git checkout -b contract-change-pr master
@@ -991,7 +1030,29 @@ application and the stub artifacts.
=== Consumer Side (Loan Issuance) Final Step
As a developer of the Loan Issuance service (a consumer of the Fraud Detection server):
As a developer of the Loan Issuance service (a consumer of the Fraud Detection server) we will want to:
- merge our feature branch to `master`
- switch to online mode of working
[plantuml, getting-started-cdc-client, png]
----
"Loan\nIssuance"->"Loan\nIssuance": merge the\nfeature branch\nto master branch
"Loan\nIssuance"->"Loan\nIssuance": setup SCC Stub Runner\nto fetch stubs\nfrom Nexus / Artifactory
"Loan\nIssuance"->"LI\nSCC\nStub Runner": start stubs\nof FD from\nNexus / Artifactory
"LI\nSCC\nStub Runner"->"Local storage": find stubs of [FD]
"Local storage"->"LI\nSCC\nStub Runner": stubs of [FD] found
"LI\nSCC\nStub Runner"->"FD stub": run stubs of [FD]
"FD stub"->"LI\nSCC\nStub Runner": [FD] stub is running
"LI\nSCC\nStub Runner"->"Loan\nIssuance": stubs running and ready for the test
"Loan\nIssuance"->"Loan\nIssuance": run a test
"Loan\nIssuance"->"FD stub": the test\nsends a request\nto the running stub
"FD stub"->"Loan\nIssuance": stub responds successfuly
"Loan\nIssuance"->"Loan\nIssuance": the test passes successfully
"Loan\nIssuance"->"Fraud\nDetection": send a pull request\nwith the\nsuggested contracts
----
*Merge branch to master.*

View File

@@ -30,7 +30,7 @@ Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Cont
- Via Docker adds support for any language & framework used
[[how-to-not-write-contracts-in-groovy]]
== I don't want to write a contract in Groovy!
== How can I write contracts in a language different than Groovy?
// TODO: Add a link
No problem. You can write a contract in YAML! Check this section for more information
@@ -38,7 +38,7 @@ No problem. You can write a contract in YAML! Check this section for more inform
We are working on allowing more ways of describing the contracts. You can check the {github-issues}[github-issues] for more information.
[[how-to-provide-dynamic-values]]
== What is this value(consumer(), producer()) ?
== How can I provide dynamic values for a contract?
One of the biggest challenges related to stubs is their reusability. Only if they can be vastly used, will they serve their purpose.
What typically makes that difficult are the hard-coded values of request / response elements. For example dates or ids.
@@ -210,7 +210,7 @@ Example of tests using production version of stubs
You can pass those values also via properties from your deployment pipeline.
[[how-to-common-repo-with-contracts]]
== Common repo with contracts
== How can I use a common repo with contracts instead of storing them with the producer?
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
@@ -279,7 +279,7 @@ include::{introduction_url}/samples/standalone/contracts/src/assembly/contracts.
The workflow assumes that Spring Cloud Contract is setup both on the consumer and the producer side. There is also the proper plugin setup in the common repo with contracts. The CI jobs are set for common repo to build an artifact of all contracts and upload it to Nexus / Artifactory.
[plantuml, three-second, png]
[plantuml, how-to-common-repo, png]
----
"API Consumer"->"Common repo": create a folder \nfor producer [API Producer]
"API Consumer"->"Common repo": under [API Producer] create a folder \nfor consumer \n[API Consumer]
@@ -476,7 +476,7 @@ contracts {
----
[[how-to-use-git-as-storage]]
== Do I need a Binary Storage? Can't I use Git?
== How can I use Git as the storage for contracts and stubs?
In the polyglot world, there are languages that don't use binary storages like
Artifactory or Nexus. Starting from Spring Cloud Contract version 2.0.0 we provide
@@ -707,7 +707,7 @@ to find stub definitions and contracts. E.g. for `com.example:foo:1.0.0` the pat
* Messaging definitions will be read and used in the messaging tests
[[how-to-use-pact-broker]]
== Can I use the Pact Broker?
== How can I use the Pact Broker?
When using https://pact.io/[Pact] you can use the https://github.com/pact-foundation/pact_broker[Pact Broker]
to store and share Pact definitions. Starting from Spring Cloud Contract
@@ -935,8 +935,70 @@ You can use the `mappingsOutputFolder` property on `@AutoConfigureStubRunner`, `
was started will be attached.
[[how-to-reference-text-from-file]]
== Can I reference text from file?
== How can I reference text from file?
Yes! With version 1.2.0 we've added such a possibility. It's enough to call `file(...)` method in the
DSL and provide a path relative to where the contract lays.
If you're using YAML just use the `bodyFromFile` property.
If you're using YAML just use the `bodyFromFile` property.
[[how-to-generate-pact-from-scc]]
== How can I generate Pact / YAML / X files from Spring Cloud Contract Contracts?
Spring Cloud Contract comes with a `ToFileContractsTransformer` class that allows you to dump contracts as files for the given `ContractConverter`. It contains a `static void main` method, that allows you to execute the transformer as an executable. It takes the following arguments:
- argument 1 : *FQN* - fully qualified name of the `ContractConverter` (e.g. the `PactContractConverter`) *REQUIRED*
- argument 2 : *path* - path where the dumped files should be stored *OPTIONAL* - defaults to `target/converted-contracts`
- argument 3 : *path* - path were the contracts should be searched for *OPTIONAL* - defaults to `src/test/resources/contracts`
After executing the transformer, the Spring Cloud Contract files will be processed and depending on the provided FQN of the `ContractTransformer`, the contracts will be transformed to the required format and dumped to the provided folder.
Below you can find an example for Pact integration:
====
[source,xml,indent=0,role="primary"]
.maven
----
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>convert-dsl-to-pact</id>
<phase>process-test-classes</phase>
<configuration>
<classpathScope>test</classpathScope>
<mainClass>
org.springframework.cloud.contract.verifier.util.ToFileContractsTransformer
</mainClass>
<arguments>
<argument>
org.springframework.cloud.contract.verifier.spec.pact.PactContractConverter
</argument>
<argument>${project.basedir}/target/pacts</argument>
<argument>
${project.basedir}/src/test/resources/contracts
</argument>
</arguments>
</configuration>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
----
[source,groovy,indent=0,role="secondary"]
.gradle
----
task convertContracts(type: JavaExec) {
main = "org.springframework.cloud.contract.verifier.util.ToFileContractsTransformer"
classpath = sourceSets.test.compileClasspath
args("org.springframework.cloud.contract.verifier.spec.pact.PactContractConverter",
"${project.rootDir}/build/pacts", "${project.rootDir}/src/test/resources/contracts")
}
test.dependsOn("convertContracts")
----
====