This commit is contained in:
Marcin Grzejszczak
2019-07-19 17:39:28 +02:00
parent a68ae38c89
commit cd4ad7b017
5 changed files with 164 additions and 319 deletions

View File

@@ -243,9 +243,7 @@ Stub Runner` properties, as shown in the following example:
+
[source,yaml,indent=0]
----
stubrunner:
ids: 'com.example:http-server-dsl:+:stubs:8080'
repositoryRoot: https://repo.spring.io/libs-snapshot
Unresolved directive in _verifier_how_it_works.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
----
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
@@ -552,9 +550,7 @@ Runner` properties, as shown in the following example:
+
[source,yaml,indent=0]
----
stubrunner:
ids: 'com.example:http-server-dsl:+:stubs:8080'
repositoryRoot: https://repo.spring.io/libs-snapshot
Unresolved directive in _verifier_how_it_works.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
----
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
@@ -1083,9 +1079,7 @@ achieving the same thing by changing the properties.
[source,yaml,indent=0]
----
stubrunner:
ids: 'com.example:http-server-dsl:+:stubs:8080'
repositoryRoot: https://repo.spring.io/libs-snapshot
Unresolved directive in _verifier_how_it_works.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/master/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
----
That's it!
@@ -1565,185 +1559,7 @@ You can read more about Spring Cloud Contract Verifier by reading the
== Contributing
:spring-cloud-build-branch: master
Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
=== Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the
https://cla.pivotal.io/sign/spring[Contributor License Agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main
repository, but it does mean that we can accept your contributions, and you will get an
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
=== Code of Conduct
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
conduct]. By participating, you are expected to uphold this code. Please report
unacceptable behavior to spring-code-of-conduct@pivotal.io.
=== Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse
you can import formatter settings using the
`eclipse-code-formatter.xml` file from the
https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
Cloud Build] project. If using IntelliJ, you can use the
https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is
for.
* Add the ASF license header comment to all new `.java` files (copy from existing files
in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or
other target branch in the main project).
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).
=== Checkstyle
Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:
.spring-cloud-build-tools/
----
└── src
   ├── checkstyle
   │   └── checkstyle-suppressions.xml <3>
   └── main
   └── resources
   ├── checkstyle-header.txt <2>
   └── checkstyle.xml <1>
----
<1> Default Checkstyle rules
<2> File header setup
<3> Default suppression rules
==== Checkstyle configuration
Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins.
.pom.xml
----
<properties>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> <1>
<maven-checkstyle-plugin.failsOnViolation>true
</maven-checkstyle-plugin.failsOnViolation> <2>
<maven-checkstyle-plugin.includeTestSourceDirectory>true
</maven-checkstyle-plugin.includeTestSourceDirectory> <3>
</properties>
<build>
<plugins>
<plugin> <4>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin> <5>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
<reporting>
<plugins>
<plugin> <5>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</build>
----
<1> Fails the build upon Checkstyle errors
<2> Fails the build upon Checkstyle violations
<3> Checkstyle analyzes also the test sources
<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules
<5> Add checkstyle plugin to your build and reporting phases
If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example:
.projectRoot/src/checkstyle/checkstyle-suppresions.xml
----
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
</suppressions>
----
It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script:
```bash
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
$ touch .springformat
```
=== IDE setup
==== Intellij IDEA
In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
The following files can be found in the https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools[Spring Cloud Build] project.
.spring-cloud-build-tools/
----
└── src
   ├── checkstyle
   │   └── checkstyle-suppressions.xml <3>
   └── main
   └── resources
   ├── checkstyle-header.txt <2>
   ├── checkstyle.xml <1>
   └── intellij
      ├── Intellij_Project_Defaults.xml <4>
      └── Intellij_Spring_Boot_Java_Conventions.xml <5>
----
<1> Default Checkstyle rules
<2> File header setup
<3> Default suppression rules
<4> Project defaults for Intellij that apply most of Checkstyle rules
<5> Project style conventions for Intellij that apply most of Checkstyle rules
.Code style
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style]
Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file.
.Inspection profiles
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style]
Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file.
.Checkstyle
To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle]
Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables:
- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL.
- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL.
- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`.
IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.
Unresolved directive in README.adoc - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[]
== How to build it

View File

@@ -12,4 +12,23 @@
:docinfo: shared,private
:sc-ext: java
:project-full-name: Spring Cloud Contract
:project-full-name: Spring Cloud Contract
// project-specific attributes
:core_path: ../../..
:plugins_path: ../../../spring-cloud-contract-tools
:converters_path: {plugins_path}/spring-cloud-contract-converters
:verifier_root_path: {core_path}/spring-cloud-contract-verifier
:contract_spec_path: {core_path}/specs/spring-cloud-contract-spec-java
:contract_spec_tests_path: {core_path}/specs/spring-cloud-contract-spec
:samples_path: {core_path}/samples
:verifier_core_path: {verifier_root_path}
:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner
:standalone_samples_path: {samples_path}/standalone/dsl
:standalone_messaging_samples_path: {samples_path}/standalone/messaging
:standalone_pact_path: {samples_path}/standalone/pact
:standalone_restdocs_path: {samples_path}/standalone/restdocs
: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}/../../

View File

@@ -1,22 +1,3 @@
:branch: master
:core_path: ../../..
:plugins_path: ../../../spring-cloud-contract-tools
:converters_path: {plugins_path}/spring-cloud-contract-converters
:verifier_root_path: {core_path}/spring-cloud-contract-verifier
:contract_spec_path: {core_path}/specs/spring-cloud-contract-spec-java
:contract_spec_tests_path: {core_path}/specs/spring-cloud-contract-spec
:samples_path: {core_path}/samples
:verifier_core_path: {verifier_root_path}
:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner
:standalone_samples_path: {samples_path}/standalone/dsl
:standalone_messaging_samples_path: {samples_path}/standalone/messaging
:standalone_pact_path: {samples_path}/standalone/pact
:standalone_restdocs_path: {samples_path}/standalone/restdocs
: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}/../../
include::_verifier_introduction.adoc[]
include::_verifier_faq.adoc[]

View File

@@ -1,12 +1,23 @@
:introduction_url: https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/{branch}
:samples_branch: 2.2.x
[[howto]]
= "`How-to`" Guides
include::_attributes.adoc[]
== Spring Cloud Contract FAQ
This section provides answers to some common '`how do I do that...`' questions
that often arise when using {project-full-name}. Its coverage is not exhaustive, but it
does cover quite a lot.
=== Why use Spring Cloud Contract Verifier and not X ?
If you have a specific problem that we do not cover here, you might want to check out
https://stackoverflow.com/tags/{project-name}[stackoverflow.com] to see if someone has
already provided an answer. This is also a great place to ask new questions (please use
the `{project-name}` tag).
For the time being Spring Cloud Contract is a JVM based tool. So it could be your first pick when you're already creating
software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make
We are also more than happy to extend this section. If you want to add a '`how-to`',
send us a {github-code}[pull request].
[[why-spring-cloud-contract]]
== Why use Spring Cloud Contract and not X ?
Spring Cloud Contract works great in a polyglot environment. This project has a lot of really interesting features but especially quite a few of them definitely make
Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are:
- Possibility to do CDC with messaging
@@ -18,11 +29,16 @@ Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Cont
- Spring Cloud Contract integrates with Pact out of the box and provides easy hooks to extend its functionality
- Via Docker adds support for any language & framework used
=== I don't want to write a contract in Groovy!
[[how-to-not-write-contracts-in-groovy]]
== I don't want to write a contract in Groovy!
No problem. You can write a contract in YAML!
// TODO: Add a link
No problem. You can write a contract in YAML! Check this section for more information
=== What is this value(consumer(), producer()) ?
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()) ?
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.
@@ -107,69 +123,19 @@ what you might want is the following response:
How can you then provide one time a matcher for the consumer and a concrete value for the producer and vice versa?
In Spring Cloud Contract we're allowing you to provide a *dynamic value*. That means that it can differ for both
sides of the communication. You can pass the values:
Either via the `value` method
[source,groovy,indent=0]
----
value(consumer(...), producer(...))
value(stub(...), test(...))
value(client(...), server(...))
----
or using the `$()` method
[source,groovy,indent=0]
----
$(consumer(...), producer(...))
$(stub(...), test(...))
$(client(...), server(...))
----
sides of the communication.
// TODO: Ensure that the link is correct
You can read more about this in the <<contract-dsl>> section.
Calling `value()` or `$()` tells Spring Cloud Contract that you will be passing a dynamic value.
Inside the `consumer()` method you pass the value that should be used on the consumer side (in the generated stub).
Inside the `producer()` method you pass the value that should be used on the producer side (in the generated test).
TIP: If on one side you have passed the regular expression and you haven't passed the other, then the
other side will get auto-generated.
Most often you will use that method together with the `regex` helper method. E.g. `consumer(regex('[0-9]{10}'))`.
To sum it up the contract for the aforementioned scenario would look more or less like this (the regular expression
for time and UUID are simplified and most likely invalid but we want to keep things very simple in this example):
[source,groovy,indent=0]
----
org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url '/someUrl'
body([
time : value(consumer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')),
id: value(consumer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}'))
body: "foo"
])
}
response {
status OK()
body([
time : value(producer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')),
id: value([producer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}'))
body: "bar"
])
}
}
----
IMPORTANT: Please read the https://groovy-lang.org/json.html[Groovy docs related to JSON] to understand how to
properly structure the request / response bodies.
=== How to do Stubs versioning?
[[how-to-do-stubs-versioning]]
== How to do Stubs versioning?
==== API Versioning
[[how-to-api-versioning]]
=== API Versioning
Let's try to answer a question what versioning really means. If you're referring to the API version then there are
different approaches.
@@ -177,13 +143,14 @@ different approaches.
- use Hypermedia, links and do not version your API by any means
- pass versions through headers / urls
I will not try to answer a question which approach is better. Whatever suits your needs and allows you to generate
We will not try to answer a question which approach is better. Whatever suits your needs and allows you to generate
business value should be picked.
Let's assume that you do version your API. In that case you should provide as many contracts as many versions you support.
You can create a subfolder for every version or append it to the contract name - whatever suits you more.
==== JAR versioning
[[how-to-jar-versioning]]
=== JAR versioning
If by versioning you mean the version of the JAR that contains the stubs then there are essentially two main approaches.
@@ -219,7 +186,8 @@ version. Example for 2.1.1.
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:2.1.1:stubs:8080"})
----
==== Dev or prod stubs
[[how-to-dev-or-prod-stubs]]
=== Dev or prod stubs
You can manipulate the classifier to run the tests against current development version of the stubs of other services
or the ones that were deployed to production. If you alter your build to deploy the stubs with the `prod-stubs` classifier
@@ -241,14 +209,16 @@ Example of tests using production version of stubs
You can pass those values also via properties from your deployment pipeline.
=== Common repo with contracts
[[how-to-common-repo-with-contracts]]
== 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 you will break with your local changes.
==== Repo structure
[[how-to-repo-structure]]
=== 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
@@ -304,13 +274,47 @@ It's using the assembly plugin in order to build the JAR with all the contracts.
include::{introduction_url}/samples/standalone/contracts/src/assembly/contracts.xml[indent=0]
----
==== Workflow
[[how-to-workflow]]
=== 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.
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.
==== Consumer
[plantuml, three-second, 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]
"API Consumer"->"Common repo": define contracts under \n[API Consumer] folder
"API Consumer"->"Common repo": install stubs of [API Producer]\nin local storage
"Common repo"->"Common Repo\nSCC Plugin": install stubs \nin local storage. \nDon't generate tests.
"Common Repo\nSCC Plugin"->"Local storage": install stubs
"Local storage"->"Common Repo\nSCC Plugin": stubs installed
"API Consumer"->"API Consumer": write a SCC Stub Runner \nbased contract test
"API Consumer"->"API Consumer\nSCC Stub Runner": fetch the stubs\n of [API Producer] \nfrom local storage
"API Consumer\nSCC Stub Runner"->"Local storage": test asks for [API Producer] stubs
"Local storage"->"API Consumer\nSCC Stub Runner": [API Producer] stubs found
"API Consumer\nSCC Stub Runner"->"API Consumer\nSCC Stub Runner": run in memory\n HTTP server stubs
"API Consumer\nSCC Stub Runner"->"API Consumer": HTTP server stubs running,\n ready for tests
"API Consumer"->"API Consumer\nSCC Stub Runner": send a request \nto the HTTP server stub
"API Consumer\nSCC Stub Runner"->"API Consumer": communication is correct. \nTests are passing
"API Consumer"->"Common repo": file pull request \nwith contracts
"API Producer"->"Common repo": take over \nthe pull request
"API Producer"->"Common repo": install the JAR \nwith all contracts\n in local storage
"Common repo"->"Local storage": install the JAR
"Local storage"->"Common repo": contracts JAR installed
"API Producer"->"Producer Build": run the build \nand fetch contracts from \nlocal storage
"Producer Build"->"Producer\nSCC Plugin": generate \ntests, stubs and stubs \nartifact (e.g. stubs-jar)
"Producer\nSCC Plugin"->"Local storage": fetch contract definitions for [API Prodcer]
"Local storage"->"Producer\nSCC Plugin": contracts fetched
"Producer\nSCC Plugin"->"Producer Build": tests and stubs created
"Producer Build"->"Nexus / Artifactory": upload contracts \nand stubs and the project arifact
"Producer Build"->"API Producer": Build successful
"API Producer"->"Common repo": merge the pull request
"Common repo"->"Nexus / Artifactory": upload the fresh JAR \nwith contract definitions
"API Producer"->"API Producer": start fetching contract definitions \nfrom Nexus / Artifactory
----
[[how-to-workflow-consumer]]
=== 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`)
@@ -318,7 +322,8 @@ and runs `mvn clean install -DskipTests` to install locally the stubs converted
TIP: You need to have https://maven.apache.org/download.cgi[Maven installed locally]
==== Producer
[[how-to-workflow-producer]]
=== 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:
@@ -336,13 +341,15 @@ when some incompatible changes are done.
The rest of the flow looks the same.
==== How can I define messaging contracts per topic not per producer?
[[how-to-define-messaging-contracts-per-topic]]
=== How can I define messaging contracts per topic not per producer?
To avoid messaging contracts duplication in the common repo, when few producers writing messages to one topic,
we could create the structure when the rest contracts would be placed in a folder per producer and messaging
contracts in the folder per topic.
===== For Maven Project
[[how-to-define-messaging-contracts-per-topic-maven]]
==== For Maven Project
To make it possible to work on the producer side we should specify an inclusion pattern for
filtering common repository jar by messaging topics we are interested in. ```includedFiles``` property of ```Maven Spring Cloud Contract plugin```
@@ -383,7 +390,8 @@ allows us to do that. Also ```contractsPath``` need to be specified since the de
</plugin>
----
===== For Gradle Project
[[how-to-define-messaging-contracts-per-topic-gradle]]
==== For Gradle Project
- Add a custom configuration for the common-repo dependency:
@@ -467,7 +475,8 @@ contracts {
}
----
=== Do I need a Binary Storage? Can't I use Git?
[[how-to-use-git-as-storage]]
== Do I need a Binary Storage? Can't I use Git?
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
@@ -520,7 +529,8 @@ the stub server mappings. On the consumer side, Stub Runner will scan this folde
to start stub servers with stub definitions. The folder structure will be a copy
of the one created in the `contracts` subfolder.
==== Protocol convention
[[how-to-protocol-convention]]
=== Protocol convention
In order to control the type and location of the source of contracts (whether it's
a binary storage or an SCM repository), you can use the protocol in the URL of
@@ -538,11 +548,12 @@ git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contr
git://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git
----
==== Producer
[[how-to-protocol-convention-producer]]
=== Producer
For the producer, to use the SCM approach, we can reuse the
same mechanism we use for external contracts. We route Spring Cloud Contract
to use the SCM implementation via the URL that contains
to use the SCM implementation via the URL that starts with
the `git://` protocol.
IMPORTANT: You have to manually add the `pushStubsToScm`
@@ -550,8 +561,9 @@ goal in Maven or execute (bind) the `pushStubsToScm` task in
Gradle. We don't push stubs to `origin` of your git
repository out of the box.
.Maven
[source,xml,indent=0]
====
[source,xml,indent=0,role="primary"]
.maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -589,8 +601,8 @@ repository out of the box.
</plugin>
----
.Gradle
[source,gradle,indent=0]
[source,groovy,indent=0,role="secondary"]
.gradle
----
contracts {
// We want to pick contracts from a Git repository
@@ -616,6 +628,7 @@ the `publish` task is executed
*/
publish.dependsOn("publishStubsToScm")
----
====
With such a setup:
@@ -628,21 +641,24 @@ to find contracts. E.g. for `com.example:foo:1.0.0` the path would be
* Once the tests pass, the stubs will be committed in the cloned repository
* Finally, a push will be done to that repo's `origin`
==== Producer with contracts stored locally
[[how-to-protocol-convention-producer-with-contracts-stored-locally]]
=== Producer with contracts stored locally
Another option to use the SCM as the destination for stubs and contracts is to store the contracts locally, with the producer, and only push the contracts and the stubs to SCM. Below, you can find the setup required to achieve this using Maven and Gradle.
.Maven
[source,xml,indent=0]
====
[source,xml,indent=0,role="primary"]
.maven
----
include::{samples_url}/producer_with_empty_git/pom.xml[tags=plugin,indent=0]
----
.Gradle
[source,xml,indent=0]
[source,groovy,indent=0,role="secondary"]
.gradle
----
include::{samples_url}/producer_with_empty_git/build.gradle[tags=plugin,indent=0]
----
====
With such a setup:
@@ -654,7 +670,8 @@ With such a setup:
** The stubs and contracts will be committed in the cloned repository
* Finally, a push will be done to that repo's `origin`
===== Keeping contracts with the producer and stubs in an external repository
[[how-to-protocol-convention-contracts-producer-stubs-external]]
=== Keeping contracts with the producer and stubs in an external repository
It is also possible to keep the contracts in the producer repository, but keep the stubs in an external git repo.
This is most useful when you want to use the base consumer-producer collaboration flow, but do not have a possibility to
@@ -663,7 +680,8 @@ use an artifact repository for storing the stubs.
In order to do that, use the usual producer setup, and then add the `pushStubsToScm` goal and set
`contractsRepositoryUrl` to the repository where you want to keep the stubs.
==== Consumer
[[how-to-protocol-convention-contracts-producer-stubs-external-consumer]]
=== Consumer
On the consumer side when passing the `repositoryRoot` parameter,
either from the `@AutoConfigureStubRunner` annotation, the
@@ -688,7 +706,8 @@ to find stub definitions and contracts. E.g. for `com.example:foo:1.0.0` the pat
* Stub servers will be started and fed with mappings
* Messaging definitions will be read and used in the messaging tests
=== Can I use the Pact Broker?
[[how-to-use-pact-broker]]
== 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
@@ -705,13 +724,15 @@ shares the files with the Producer. Those expectations are generated
from the Consumer's code and can break the Producer if the expectations
are not met.
==== Pact Consumer
[[how-to-pact-consumer]]
=== Pact Consumer
The consumer uses Pact framework to generate Pact files. The
Pact files are sent to the Pact Broker. An example of such
setup can be found https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/consumer_pact[here].
==== Producer
[[how-to-pact-producer]]
=== Producer
For the producer, to use the Pact files from the Pact Broker, we can reuse the
same mechanism we use for external contracts. We route Spring Cloud Contract
@@ -719,8 +740,9 @@ to use the Pact implementation via the URL that contains
the `pact://` protocol. It's enough to pass the URL to the
Pact Broker. An example of such setup can be found https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/producer_pact[here].
.Maven
[source,xml,indent=0]
====
[source,xml,indent=0,role="primary"]
.maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -757,8 +779,8 @@ Pact Broker. An example of such setup can be found https://github.com/spring-clo
</plugin>
----
.Gradle
[source,gradle,indent=0]
[source,groovy,indent=0,role="secondary"]
.gradle
----
buildscript {
repositories {
@@ -785,6 +807,7 @@ contracts {
// Base class mappings etc.
}
----
====
With such a setup:
@@ -792,7 +815,8 @@ With such a setup:
* Spring Cloud Contract will convert the Pact files into tests and stubs
* The JAR with the stubs gets automatically created as usual
==== Pact Consumer (Producer Contract approach)
[[how-to-pact-consumer-producer-contract]]
=== Pact Consumer (Producer Contract approach)
In the scenario where you don't want to do Consumer Contract approach
(for every single consumer define the expectations) but you'd prefer
@@ -803,8 +827,9 @@ Stub Runner option. An example of such setup can be found https://github.com/spr
First, remember to add Stub Runner and Spring Cloud Contract Pact module
as test dependencies.
.Maven
[source,xml,indent=0]
====
[source,xml,indent=0,role="primary"]
.maven
----
<dependencyManagement>
<dependencies>
@@ -834,8 +859,8 @@ as test dependencies.
</dependencies>
----
.Gradle
[source,gradle,indent=0]
[source,groovy,indent=0,role="secondary"]
.gradle
----
dependencyManagement {
imports {
@@ -850,6 +875,7 @@ dependencies {
testCompile("org.springframework.cloud:spring-cloud-contract-pact")
}
----
====
Next, just pass the URL of the Pact Broker to `repositoryRoot`, prefixed
with `pact://` protocol. E.g. `pact://http://localhost:8085`
@@ -877,7 +903,8 @@ With such a setup:
For more information about Pact support you can go to
the <<pact-stub-downloader>> section.
=== How can I debug the request/response being sent by the generated tests client?
[[how-to-debug]]
== How can I debug the request/response being sent by the generated tests client?
The generated tests all boil down to RestAssured in some form or fashion which relies on https://hc.apache.org/httpcomponents-client-ga/[Apache HttpClient]. HttpClient has a facility called https://hc.apache.org/httpcomponents-client-ga/logging.html#Wire_Logging[wire logging] which logs the entire request and response to HttpClient. Spring Boot has a logging https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html[common application property] for doing this sort of thing, just add this to your application properties
[source,properties,indent=0]
@@ -885,7 +912,8 @@ The generated tests all boil down to RestAssured in some form or fashion which r
logging.level.org.apache.http.wire=DEBUG
----
==== How can I debug the mapping/request/response being sent by WireMock?
[[how-to-debug-wiremock]]
== How can I debug the mapping/request/response being sent by WireMock?
Starting from version `1.2.0` we turn on WireMock logging to
info and the WireMock notifier to being verbose. Now you will
@@ -899,13 +927,15 @@ To turn off this feature just bump WireMock logging to `ERROR`
logging.level.com.github.tomakehurst.wiremock=ERROR
----
==== How can I see what got registered in the HTTP server stub?
[[how-to-see-registered-stubs]]
== How can I see what got registered in the HTTP server stub?
You can use the `mappingsOutputFolder` property on `@AutoConfigureStubRunner`, `StubRunnerRule` or
`StubRunnerExtension`to dump all mappings per artifact id. Also the port at which the given stub server
was started will be attached.
==== Can I reference text from file?
[[how-to-reference-text-from-file]]
== 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.

View File

@@ -1 +0,0 @@
index.htmladoc