This commit is contained in:
Marcin Grzejszczak
2023-09-11 19:00:22 +02:00
parent 7322a41390
commit 43318b0b05
119 changed files with 1255 additions and 2028 deletions

6
.gitignore vendored
View File

@@ -44,3 +44,9 @@ dependency-reduced-pom.xml
.vscode/
.flattened-pom.xml
node
node_modules
build
package.json
package-lock.json

View File

@@ -5,7 +5,9 @@ Edit the files in the src/main/asciidoc/ directory instead.
////
== Spring Cloud Contract
[[spring-cloud-contract]]
= Spring Cloud Contract
:page-section-summary-toc: 1
You always need confidence when pushing new features into a new application or service in
a distributed system. To that end, this project provides support for consumer-driven
@@ -13,380 +15,14 @@ contracts and service schemas in Spring applications, covering a range of option
writing tests, publishing them as assets, and asserting that a contract is kept by
producers and consumers -- for both HTTP and message-based interactions.
== Project page
[[project-page]]
= Project page
:page-section-summary-toc: 1
You can read more about Spring Cloud Contract by going to https://spring.io/projects/spring-cloud-contract[the project page]
== Contributing
[[contributing]]
= Contributing
:page-section-summary-toc: 1
: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-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.
=== Duplicate Finder
Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath.
==== Duplicate Finder configuration
Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`.
.pom.xml
[source,xml]
----
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
----
For other properties, we have set defaults as listed in the https://github.com/basepom/duplicate-finder-maven-plugin/wiki[plugin documentation].
You can easily override them but setting the value of the selected property prefixed with `duplicate-finder-maven-plugin`. For example, set `duplicate-finder-maven-plugin.skip` to `true` in order to skip duplicates check in your build.
If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your setup, make sure to add them in the plugin configuration section of your project:
[source,xml]
----
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
<configuration>
<ignoredClassPatterns>
<ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
<ignoredClassPattern>.*module-info</ignoredClassPattern>
</ignoredClassPatterns>
<ignoredResourcePatterns>
<ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
</ignoredResourcePatterns>
</configuration>
</plugin>
</plugins>
</build>
----
== How to Build Spring Cloud Contract
=== Cloning the repository on Windows
While cloning this project on Windows, some files in the git repository may exceed the Windows maximum file path limit of 255 characters, which may
result in an incorrectly (probably partially) checked out repository.
To resolve this issue, you can set the `core.longPaths` attribute to `true` or clone the Spring Cloud Contract repository.
To set the `core.longPaths` attribute to `true`, you have three options:
- Change it for all users of the machine (doing so requires administrator privileges):
[source,bash]
----
git config --system core.longPaths true
git clone https://github.com/spring-cloud/spring-cloud-contract.git
----
- Change it for the current user (no administrative privileges required):
[source,bash]
----
git config --global core.longPaths true
git clone https://github.com/spring-cloud/spring-cloud-contract.git
----
- Change for just this repository (administrative privileges depend on where the repository is being cloned to):
[source,bash]
----
git clone -c core.longPaths=true https://github.com/spring-cloud/spring-cloud-contract.git
----
IMPORTANT: You need to have all the necessary Groovy plugins
installed for your IDE to properly resolve the sources. For example, in
Intellij IDEA, having both the Eclipse Groovy Compiler Plugin and the GMavenPlus Intellij
Plugin results in properly imported project.
IMPORTANT: Spring Cloud Contract builds Docker images. Remember to
have Docker installed.
IMPORTANT: If you want to run the build in offline mode, you must have Maven 3.5.2+ installed.
=== Project structure
The following listing shows the Spring Cloud Contract folder structure:
```
├── config
├── docker
├── samples
├── scripts
├── specs
├── spring-cloud-contract-dependencies
├── spring-cloud-contract-shade
├── spring-cloud-contract-starters
├── spring-cloud-contract-stub-runner
├── spring-cloud-contract-stub-runner-boot
├── spring-cloud-contract-tools
├── spring-cloud-contract-verifier
├── spring-cloud-contract-wiremock
└── tests
```
The following list describes each of the top-level folders in the project structure:
- `config`: Folder contains setup for Spring Cloud Release Tools automated release process
- `docker`: Folder contains docker images
- `samples`: Folder contains test samples together with standalone ones used also to build documentation
- `scripts`: Contains scripts to build and test `Spring Cloud Contract` with Maven, Gradle and standalone projects
- `specs`: Contains specifications for the Contract DSL.
- `spring-cloud-contract-dependencies`: Contains Spring Cloud Contract BOM
- `spring-cloud-contract-shade`: Shaded dependencies used by the plugins
- `spring-cloud-contract-starters`: Contains Spring Cloud Contract Starters
- `spring-cloud-contract-spec`: Contains specification modules (contains concept of a Contract)
- `spring-cloud-contract-stub-runner`: Contains Stub Runner related modules
- `spring-cloud-contract-stub-runner-boot`: Contains Stub Runner Boot app
- `spring-cloud-contract-tools`: Gradle and Maven plugin for `Spring Cloud Contract Verifier`
- `spring-cloud-contract-verifier`: Core of the `Spring Cloud Contract Verifier` functionality
- `spring-cloud-contract-wiremock`: All WireMock related functionality
- `tests`: Integration tests for different messaging technologies
=== Commands
To build the core functionality together with the Maven Plugin, you can run the following
command:
```
./mvnw clean install -P integration
```
Calling that function builds the core, the Maven plugin, and the Gradle plugin and runs
end-to_end tests on the
standalone samples in the proper order (both for Maven and Gradle).
To build only the Gradle Plugin, you can run the following commands:
```
cd spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin
./gradlew clean build
```
=== Helpful scripts
We provide a couple of helpful scripts to build the project.
To build the project in parallel (by default, it uses four cores, but you can change it),
run the following command:
```
./scripts/parallelBuild.sh
```
To use eight 8 cores, run the following command:
```
CORES=8 ./scripts/parallelBuild.sh
```
To build the project without any integration tests (by default, this uses one core), run
the following command:
```
./scripts/noIntegration.sh
```
To use eight cores, run the following command:
```
CORES=8 ./scripts/noIntegration.sh
```
To generate the documentation (for both the root project and the maven plugin), run the
following command:
```
./scripts/generateDocs.sh
```
Unresolved directive in <stdin> - include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/contributing.adoc[]

View File

@@ -3,7 +3,7 @@
set -e
CURRENT_DIR="$( pwd )"
ADOC_OUTPUT_DIR="${CURRENT_DIR}/target/adoc/"
ADOC_OUTPUT_DIR="${1:-${CURRENT_DIR}/target/adoc/}"
pushd project
mkdir -p "${ADOC_OUTPUT_DIR}"
./gradlew dumpAllProps

View File

@@ -6,15 +6,10 @@ antora:
- '@antora/collector-extension'
- '@antora/atlas-extension'
- require: '@springio/antora-extensions/root-component-extension'
root_component_name: 'PROJECT_WITHOUT_SPRING'
# FIXME: Run antora once using this extension to migrate to the Asciidoc Tabs syntax
# and then remove this extension
- require: '@springio/antora-extensions/tabs-migration-extension'
unwrap_example_block: always
save_result: true
root_component_name: 'cloud-contract'
site:
title: PROJECT_FULL_NAME
url: https://docs.spring.io/PROJECT_NAME/reference/
title: Spring Cloud Contract
url: https://docs.spring.io/spring-cloud-contract/reference/
content:
sources:
- url: ./..
@@ -28,15 +23,16 @@ asciidoc:
hide-uri-scheme: '@'
tabs-sync-option: '@'
chomp: 'all'
plantuml-server-url: http://www.plantuml.com/plantuml
extensions:
- '@asciidoctor/tabs'
- '@springio/asciidoctor-extensions'
- '@springio/asciidoctor-extensions' #TODO: Add plantuml rendering
sourcemap: true
urls:
latest_version_segment: ''
runtime:
log:
failure_level: warn
failure_level: error # at least until we figure out what's wrong in contract files
format: pretty
ui:
bundle:

View File

@@ -1,6 +1,6 @@
name: PROJECT_WITHOUT_SPRING
name: cloud-contract
version: true
title: PROJECT_NAME
title: spring-cloud-contract
nav:
- modules/ROOT/nav.adoc
ext:

View File

@@ -0,0 +1 @@
../../../../samples

View File

@@ -0,0 +1 @@
../../../../specs

View File

@@ -0,0 +1 @@
../../../../spring-cloud-contract-stub-runner

View File

@@ -0,0 +1 @@
../../../../tests

View File

@@ -0,0 +1 @@
../../../../spring-cloud-contract-tools

View File

@@ -0,0 +1 @@
../../../../spring-cloud-contract-verifier

View File

@@ -0,0 +1 @@
../../../../spring-cloud-contract-wiremock

View File

@@ -1,62 +1,55 @@
* xref:index.adoc[]
* xref:spring-cloud-contract.adoc[]
* xref:_attributes.adoc[]
* xref:README.adoc[]
* xref:_additional-stubrunner-configprops.adoc[]
* xref:_building.adoc[]
* xref:_configprops.adoc[]
* xref:_index.adoc[]
* xref:_index_pdf.adoc[]
* xref:_index_single.adoc[]
* xref:_project-features-contract.adoc[]
** xref:_project-features-contract/groovy.adoc[]
** xref:_project-features-contract/java.adoc[]
** xref:_project-features-contract/kotlin.adoc[]
** xref:_project-features-contract/yml.adoc[]
** xref:_project-features-contract/limitations.adoc[]
** xref:_project-features-contract/common-top-elements.adoc[]
** xref:_project-features-contract/dsl-http-top-level-elements.adoc[]
** xref:_project-features-contract/dsl-request.adoc[]
** xref:_project-features-contract/dsl-response.adoc[]
** xref:_project-features-contract/dsl-dynamic-properties.adoc[]
** xref:_project-features-contract/dsl-async.adoc[]
** xref:_project-features-contract/dsl-xml.adoc[]
** xref:_project-features-contract/dsl-multiple.adoc[]
** xref:_project-features-contract/stateful-contracts.adoc[]
* xref:_project-features-flows.adoc[]
** xref:_project-features-flows/jax-rs.adoc[]
** xref:_project-features-flows/feature-webflux.adoc[]
** xref:_project-features-flows/feature-webflux-explicit.adoc[]
** xref:_project-features-flows/custom-mode.adoc[]
** xref:_project-features-flows/context-paths.adoc[]
** xref:_project-features-flows/rest-docs.adoc[]
** xref:_project-features-flows/graphql.adoc[]
** xref:_project-features-flows/grpc.adoc[]
* xref:_project-features-messaging.adoc[]
* xref:_project-features-stubrunner.adoc[]
** xref:_project-features-stubrunner/stub-runner-snapshot-versions.adoc[]
** xref:_project-features-stubrunner/stub-runner-publishing-stubs-as-jars.adoc[]
** xref:_project-features-stubrunner/stub-runner-core.adoc[]
** xref:_project-features-stubrunner/stub-runner-junit.adoc[]
** xref:_project-features-stubrunner/stub-runner-cloud.adoc[]
** xref:_project-features-stubrunner/stub-runner-boot.adoc[]
** xref:_project-features-stubrunner/stub-runner-stubs-per-consumer.adoc[]
** xref:_project-features-stubrunner/stub-runner-stubs-protocol.adoc[]
** xref:_project-features-stubrunner/stub-runner-generate-stubs-at-runtime.adoc[]
** xref:_project-features-stubrunner/stub-runner-fail-on-no-stubs.adoc[]
** xref:_project-features-stubrunner/stub-runner-common.adoc[]
* xref:_project-features-wiremock.adoc[]
* xref:advanced.adoc[]
* xref:appendix.adoc[]
* xref:docker-project.adoc[]
* xref:documentation-overview.adoc[]
* xref:legal.adoc[]
* xref:getting-started.adoc[]
** xref:getting-started/introducing-spring-cloud-contract.adoc[]
** xref:getting-started/three-second-tour.adoc[]
** xref:getting-started/first-application.adoc[]
** xref:getting-started/cdc.adoc[]
** xref:getting-started/whats-next.adoc[]
* xref:gradle-project.adoc[]
* xref:using.adoc[]
* xref:project-features.adoc[]
*** xref:project-features-contract/groovy.adoc[]
*** xref:project-features-contract/java.adoc[]
*** xref:project-features-contract/kotlin.adoc[]
*** xref:project-features-contract/yml.adoc[]
*** xref:project-features-contract/limitations.adoc[]
*** xref:project-features-contract/common-top-elements.adoc[]
** xref:project-features-contract.adoc[]
*** xref:project-features-contract/dsl-http-top-level-elements.adoc[]
*** xref:project-features-contract/dsl-request.adoc[]
*** xref:project-features-contract/dsl-response.adoc[]
*** xref:project-features-contract/dsl-dynamic-properties.adoc[]
*** xref:project-features-contract/dsl-async.adoc[]
*** xref:project-features-contract/dsl-xml.adoc[]
*** xref:project-features-contract/dsl-multiple.adoc[]
*** xref:project-features-contract/stateful-contracts.adoc[]
** xref:project-features-integrations.adoc[]
*** xref:project-features-flows/jax-rs.adoc[]
*** xref:project-features-flows/feature-webflux.adoc[]
*** xref:project-features-flows/feature-webflux-explicit.adoc[]
*** xref:project-features-flows/custom-mode.adoc[]
*** xref:project-features-flows/context-paths.adoc[]
*** xref:project-features-flows/rest-docs.adoc[]
*** xref:project-features-flows/graphql.adoc[]
*** xref:project-features-flows/grpc.adoc[]
** xref:project-features-messaging.adoc[]
** xref:project-features-stubrunner.adoc[]
*** xref:project-features-stubrunner/stub-runner-snapshot-versions.adoc[]
*** xref:project-features-stubrunner/stub-runner-publishing-stubs-as-jars.adoc[]
*** xref:project-features-stubrunner/stub-runner-core.adoc[]
*** xref:project-features-stubrunner/stub-runner-junit.adoc[]
*** xref:project-features-stubrunner/stub-runner-cloud.adoc[]
*** xref:project-features-stubrunner/stub-runner-boot.adoc[]
*** xref:project-features-stubrunner/stub-runner-stubs-per-consumer.adoc[]
*** xref:project-features-stubrunner/stub-runner-stubs-protocol.adoc[]
*** xref:project-features-stubrunner/stub-runner-generate-stubs-at-runtime.adoc[]
*** xref:project-features-stubrunner/stub-runner-fail-on-no-stubs.adoc[]
*** xref:project-features-stubrunner/stub-runner-common.adoc[]
** xref:project-features-wiremock.adoc[]
* Build Tools
** xref:docker-project.adoc[]
** xref:gradle-project.adoc[]
** xref:maven-project.adoc[]
* xref:howto.adoc[]
** xref:howto/why-spring-cloud-contract.adoc[]
** xref:howto/how-to-not-write-contracts-in-groovy.adoc[]
@@ -68,17 +61,15 @@
** xref:howto/how-to-debug-wiremock.adoc[]
** xref:howto/how-to-see-registered-stubs.adoc[]
** xref:howto/how-to-reference-text-from-file.adoc[]
** xref:howto/how-to-generate-pact-from-scc.adoc[]
** xref:howto/how-to-generate-from-scc.adoc[]
** xref:howto/how-to-work-with-transitivie.adoc[]
** xref:howto/contract-dsl-rest-docs.adoc[]
** xref:howto/how-to-use-stubs-from-a-location.adoc[]
** xref:howto/how-to-generate-stubs-at-runtime.adoc[]
** xref:howto/how-to-use-the-failonnostubs-feature.adoc[]
** xref:howto/how-to-mark-contract-in-progress.adoc[]
* xref:legal.adoc[]
* xref:maven-project.adoc[]
* xref:project-features.adoc[]
* xref:sagan-boot.adoc[]
* xref:sagan-index.adoc[]
* xref:using.adoc[]
* xref:yml-schema.adoc[]
* xref:advanced.adoc[]
* xref:appendix.adoc[]
** xref:building.adoc[]
** xref:configprops.adoc[]
** xref:yml-schema.adoc[]

View File

@@ -1,36 +0,0 @@
:doctype: book
:idprefix:
:idseparator: -
:tabsize: 4
:numbered:
:sectanchors:
:sectnums:
:icons: font
:hide-uri-scheme:
:docinfo: shared,private
:sc-ext: java
:project-full-name: Spring Cloud Contract
// project-specific attributes
:core_path: {project-root}
:plugins_path: {project-root}/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
:contract_kotlin_spec_path: {core_path}/specs/spring-cloud-contract-spec-kotlin
: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/dsl
:standalone_restdocs_path: {samples_path}/standalone/restdocs
:tests_path: {core_path}/tests
:samples_branch: main
:samples_url: https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/{samples_branch}
:samples_code: https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}
:doc_samples: {samples_code}/wiremock-for-contract-docs
:doc_samples_url: {samples_url}/wiremock-for-contract-docs
:wiremock_tests: {core_path}/spring-cloud-contract-wiremock
:introduction_url: {core_path}

View File

@@ -1,18 +0,0 @@
[[spring-cloud-contract-reference-documentation]]
= Spring Cloud Contract Reference Documentation
:page-section-summary-toc: 1
Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant
:docinfo: shared
The reference documentation consists of the following sections:
[horizontal]
<<legal.adoc#legal-information,Legal>> :: Legal information.
<<documentation-overview.adoc#contract-documentation,Documentation Overview>> :: About the Documentation, Getting Help, First Steps, and more.
xref:getting-started.adoc[Getting Started] :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application
xref:using.adoc[Using {project-full-name}] :: {project-full-name} usage examples and workflows.
xref:project-features.adoc[{project-full-name} Features] :: Contract DSL, Messaging, Spring Cloud Contract Stub Runner, and Spring Cloud Contract WireMock.
xref:project-features.adoc#features-build-tools[Build Tools] :: Maven Plugin, Gradle Plugin, and Docker.
xref:howto.adoc["`How-to`" Guides] :: Stubs versioning, Debugging, and more.
<<appendix.adoc#appendix,Appendices>> :: Properties, Metadata, Configuration, Dependencies, and more.

View File

@@ -1,6 +0,0 @@
[[spring-cloud-contract-reference-documentation]]
= Spring Cloud Contract Reference Documentation
:page-section-summary-toc: 1
Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant

View File

@@ -1,7 +0,0 @@
[[spring-cloud-contract-reference-documentation]]
= Spring Cloud Contract Reference Documentation
:page-section-summary-toc: 1
Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant
:docinfo: shared

View File

@@ -1,6 +0,0 @@
[[contract-yml]]
= Contract DSL in YAML
:page-section-summary-toc: 1
To see a schema of a YAML contract, visit the {docs-url}/reference/html/yml-schema.html[YML Schema] page.

View File

@@ -1,5 +0,0 @@
[[feature-integrations]]
= Integrations
:page-section-summary-toc: 1

View File

@@ -1,32 +0,0 @@
[[features-stub-runner-publishing-stubs-as-jars]]
= Publishing Stubs as JARs
The easiest approach to publishing stubs as jars is to centralize the way stubs are kept.
For example, you can keep them as jars in a Maven repository.
TIP: For both Maven and Gradle, the setup comes ready to work. However, you can customize
it if you want to.
The following example shows how to publish stubs as jars:
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<!-- First disable the default jar setup in the properties section -->
include:../:{samples_url}/producer_with_restdocs/pom.xml[tags=skip_jar,indent=0]
<!-- Next add the assembly plugin to your build -->
include:../:{samples_url}/producer_with_restdocs/pom.xml[tags=assembly,indent=0]
<!-- Finally setup your assembly. Below you can find the contents of src/main/assembly/stub.xml -->
include:../:{samples_url}/producer_with_restdocs/src/assembly/stub.xml[indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
include:../:{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0]
----
====

View File

@@ -1,6 +1,8 @@
[[contract-customization]]
= Spring Cloud Contract customization
include::partial$_attributes.adoc[]
In this section, we describe how to customize various parts of Spring Cloud Contract.
[[customization-customization]]
@@ -28,35 +30,11 @@ https://github.com/spring-cloud-samples/spring-cloud-contract-samples[here].
The following examples show three classes that can be reused in the DSLs.
`PatternUtils` contains functions used by both the consumer and the producer.
The following listing shows the `PatternUtils` class:
{samples_url}/common/src/main/java/com/example/PatternUtils.java[PatternUtils] contains functions used by both the consumer and the producer.
====
[source,java]
----
include::{samples_url}/common/src/main/java/com/example/PatternUtils.java[]
----
====
{samples_url}/common/src/main/java/com/example/ConsumerUtils.java[ConsumerUtils] contains functions used by the consumer.
`ConsumerUtils` contains functions used by the consumer.
The following listing shows the `ConsumerUtils` class:
====
[source,java]
----
include::{samples_url}/common/src/main/java/com/example/ConsumerUtils.java[]
----
====
`ProducerUtils` contains functions used by the producer.
The following listing shows the `ProducerUtils` class:
====
[source,java]
----
include::{samples_url}/common/src/main/java/com/example/ProducerUtils.java[]
----
====
{samples_url}/common/src/main/java/com/example/ProducerUtils.java[ProducerUtils] contains functions used by the producer.
[[customization-test-dep]]
=== Adding a Test Dependency in the Project's Dependencies
@@ -64,53 +42,17 @@ include::{samples_url}/common/src/main/java/com/example/ProducerUtils.java[]
To add a test dependency in the project's dependencies, you must first add the common jar
dependency as a test dependency. Because your contracts files
are available on the test resources path, the common jar classes automatically become
visible in your Groovy files. The following examples show how to test the dependency:
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
include::{samples_url}/producer/pom.xml[tags=test_dep,indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
include::{samples_url}/producer/build.gradle[tags=test_dep,indent=0]
----
====
visible in your Groovy files. The following {samples_url}/producer/[example] show how to test the dependency.
[[customization-plugin-dep]]
=== Adding a Test Dependency in the Plugin's Dependencies
Now, you must add the dependency for the plugin to reuse at runtime, as the
following example shows:
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
include::{samples_url}/producer/pom.xml[tags=test_dep_in_plugin,indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
include::{samples_url}/producer/build.gradle[tags=test_dep_in_plugin,indent=0]
----
====
Now, you must add the dependency for the plugin to reuse at runtime.
[[customization-referencing]]
=== Referencing Classes in DSLs
You can now reference your classes in your DSL, as the following example shows:
====
[source,groovy]
----
include::{samples_url}/producer/src/test/resources/contracts/beer/rest/shouldGrantABeerIfOldEnough.groovy[indent=0]
----
====
You can now reference your classes in your DSL, as the {samples_url}/producer/src/test/resources/contracts/beer/rest/shouldGrantABeerIfOldEnough.groovy[following example shows].
IMPORTANT: You can set the Spring Cloud Contract plugin up by setting `convertToYaml` to
`true`. That way, you do NOT have to add the dependency with the extended functionality
@@ -131,22 +73,18 @@ provide your own extensions, you can register an implementation of the
Since we use the `spring.factories` extension approach, you can create an entry similar to
the following in the `META-INF/spring.factories` file:
====
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/test/resources/META-INF/spring.factories[indent=0]
----
====
The following example shows a custom extension:
.TestWireMockExtensions.groovy
====
[source,groovy,indent=0]
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/TestWireMockExtensions.groovy[indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/TestWireMockExtensions.groovy[indent=0]
----
====
IMPORTANT: If you want the transformation to be applied only for a mapping that explicitly
requires it, override the `applyGlobally()` method and set it to `false` .
@@ -158,14 +96,12 @@ You can register a bean of type `org.springframework.cloud.contract.wiremock.Wir
to customize the WireMock configuration (for example, to add custom transformers).
The following example shows how to do so:
====
[source,java,indent=0]
----
include::{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockConfigurationCustomizerTests.java[tags=customizer_1]
// perform your customization here
include::{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockConfigurationCustomizerTests.java[tags=customizer_2]
----
====
[[customization-wiremock-from-metadata]]
=== Customization of WireMock via Metadata
@@ -231,12 +167,10 @@ can generate stubs for other HTTP server implementations).
The `ContractConverter` interface lets you register your own implementation of a contract
structure converter. The following code listing shows the `ContractConverter` interface:
====
[source,java]
----
include::{contract_spec_path}/src/main/java/org/springframework/cloud/contract/spec/ContractConverter.java[indent=0,lines=17..-1]
----
====
Your implementation must define the condition on which it should start the
conversion. Also, you must define how to perform that conversion in both directions.
@@ -247,13 +181,11 @@ implementation.
The following example shows a typical `spring.factories` file:
====
[source]
----
org.springframework.cloud.contract.spec.ContractConverter=\
org.springframework.cloud.contract.verifier.converter.YamlContractConverter
----
====
[[customization-custom-test-generator]]
=== Using the Custom Test Generator
@@ -264,23 +196,19 @@ way the verifier builds Java tests, you can register your own implementation.
The `SingleTestGenerator` interface lets you register your own implementation. The
following code listing shows the `SingleTestGenerator` interface:
====
[source,groovy]
----
include::{verifier_core_path}/src/main/java/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.java[indent=0,lines=17..-1]
include::{verifier_root_path}/src/main/java/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.java[indent=0,lines=17..-1]
----
====
Again, you must provide a `spring.factories` file, such as the one shown in the following
example:
====
[source]
----
org.springframework.cloud.contract.verifier.builder.SingleTestGenerator=/
com.example.MyGenerator
----
====
[[customization-custom-stub-generator]]
=== Using the Custom Stub Generator
@@ -289,22 +217,18 @@ If you want to generate stubs for stub servers other than WireMock, you can plug
own implementation of the `StubGenerator` interface. The following code listing shows the
`StubGenerator` interface:
====
[source,groovy]
----
include::{converters_path}/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGenerator.java[indent=0,lines=16..-1]
----
====
Again, you must provide a `spring.factories` file, such as the one shown in the following
example:
====
[source]
----
include::{converters_path}/src/main/resources/META-INF/spring.factories[indent=0]
----
====
The default implementation is the WireMock stub generation.
@@ -323,23 +247,19 @@ you have written a stub generator and placed your stubs in a JAR file.
In order for Stub Runner to know how to run your stubs, you have to define a custom
HTTP Stub server implementation, which might resemble the following example:
====
[source,groovy]
----
include::{tests_path}/spring-cloud-contract-stub-runner-moco/src/test/groovy/org/springframework/cloud/contract/stubrunner/provider/moco/MocoHttpServerStub.groovy[indent=0,lines=16..-1]
----
====
Then you can register it in your `spring.factories` file, as the following
example shows:
====
[source]
----
org.springframework.cloud.contract.stubrunner.HttpServerStub=\
org.springframework.cloud.contract.stubrunner.provider.moco.MocoHttpServerStub
----
====
Now you can run stubs with Moco.
@@ -352,7 +272,6 @@ implementation is used. If you provide more than one, the first one on the list
You can customize the way your stubs are downloaded by creating an implementation of the
`StubDownloaderBuilder` interface, as the following example shows:
====
[source,java]
----
package com.example;
@@ -378,19 +297,16 @@ class CustomStubDownloaderBuilder implements StubDownloaderBuilder {
}
}
----
====
Then you can register it in your `spring.factories` file, as the following
example shows:
====
[source]
----
# Example of a custom Stub Downloader Provider
org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder=\
com.example.CustomStubDownloaderBuilder
----
====
Now you can pick a folder with the source of your stubs.

View File

@@ -4,6 +4,7 @@
= Common application properties
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches.
This appendix provides a list of common {project-full-name} properties and references to the underlying classes that consume them.
@@ -11,10 +12,3 @@ This appendix provides a list of common {project-full-name} properties and refer
NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list.
Also, you can define your own properties.
[[default-application-properties]]
== Default application properties
[[additional-application-properties]]
== Additional application properties

View File

@@ -0,0 +1,6 @@
[[configuration-properties]]
= Configuration Properties
Below you can find a list of configuration properties.
include::partial$_configprops.adoc[]

View File

@@ -1,6 +1,8 @@
[[docker]]
= Docker Project
include::partial$_attributes.adoc[]
In this section, we publish a `springcloud/spring-cloud-contract` Docker image
that contains a project that generates tests and runs them in `EXPLICIT` mode
against a running application.
@@ -75,24 +77,20 @@ The Docker image requires some environment variables to point to
your running application, to the Artifact manager instance, and so on.
The following list describes the environment variables:
// TODO: reenable
//include::{project-root}/docker/spring-cloud-contract-docker/target/adoc/props.adoc[indent=0]
include::partial$props.adoc[indent=0]
The following environment variables are used when tests are run:
// TODO: reenable
//include::{project-root}/docker/spring-cloud-contract-docker/target/adoc/appProps.adoc[indent=0]
include::partial$appProps.adoc[indent=0]
### Customizing the gradle build
You can provide a customized `gradle.build` to be run in the container by mounting your customized build file as a volume when running the container:
====
[source,bash]
----
$ docker run -v <absolute-path-of-your-custom-file>:/spring-cloud-contract/build.gradle springcloud/spring-cloud-contract:<version>
----
====
[[docker-example-of-usage]]
=== Example of Usage via HTTP
@@ -100,28 +98,23 @@ $ docker run -v <absolute-path-of-your-custom-file>:/spring-cloud-contract/build
In this section, we explore a simple MVC application. To get started, clone the following
git repository and cd to the resulting directory, by running the following commands:
====
[source,bash]
----
$ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
$ cd bookstore
----
====
The contracts are available in the `/contracts` folder.
Since we want to run tests, we can run the following command:
====
[source,bash]
----
$ npm test
----
====
However, for learning purposes, we split it into pieces, as follows:
====
[source,bash]
----
# Stop docker infra (nodejs, artifactory)
@@ -150,7 +143,6 @@ $ docker run --rm -e "APPLICATION_BASE_URL=${APPLICATION_BASE_URL}" -e "PUBLISH
# Kill app
$ pkill -f "node app"
----
====
Through bash scripts, the following happens:
@@ -188,9 +180,11 @@ in case of polyglot applications) then you'll have to have the following prerequ
The contract needs to call a `triggerMessage(...)` method. That method is already provided in the base class for all tests in the docker image and will send out a request to the HTTP endpoint on the producer side. Below you can find examples of such contracts.
====
[tabs]
======
Groovy::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
import org.springframework.cloud.contract.spec.Contract
@@ -224,8 +218,9 @@ Contract.make {
}
----
YAML::
+
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
description: 'Send a pong message in response to a ping message'
label: 'ping_pong'
@@ -245,7 +240,7 @@ metadata:
messageProperties:
receivedRoutingKey: '#'
----
====
======
[[docker-example-of-usage-messaging-endpoint]]
==== HTTP Endpoint to Trigger a Message
@@ -256,7 +251,7 @@ code that sends a message to a broker. If such code is not generated then we nee
The endpoint must have the following configuration:
- URL: `/springcloudcontract/{label}` where `label` can be any text
- URL: `/springcloudcontract/\{label}` where `label` can be any text
- Method: `POST`
- Basing on the `label` will generate a message that will be sent to a given destination according to the contract definition
@@ -264,7 +259,6 @@ Below you have an example of such an endpoint. If you're interested in
providing an example in your language don't hesitate to file an issue in
the https://github.com/spring-cloud/spring-cloud-contract/issues/new?assignees=&labels=&template=feature_request.md&title=New+Polyglot+Sample+of+a+HTTP+controller[Spring Cloud Contract repository at Github].
====
[source,python,indent=0,subs="verbatim,attributes"]
.Python
----
@@ -300,7 +294,6 @@ if 'CONTRACT_TEST' in os.environ:
else:
raise ValueError('No such label expected.')
----
====
[[docker-example-of-usage-messaging-producer]]
==== Running Message Tests on the Producer Side
@@ -311,7 +304,6 @@ with attached contracts, however we will also add variables for the messaging
code to work. In this case let's assume that the contracts are being stored in
a Git repository.
====
[source,bash]
----
#!/bin/bash
@@ -369,7 +361,6 @@ kill $APP_PID
yes | docker-compose kill
----
====
What will happen is:
@@ -398,7 +389,7 @@ Since the Spring Cloud Contract Stub Runner Docker Image uses the standalone ver
[[docker-stubrunner-env-vars]]
=== Environment Variables
You can run the docker image and pass any of the xref:_project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-common-properties-junit-spring[common properties for JUnit and Spring]
You can run the docker image and pass any of the xref:project-features-stubrunner/stub-runner-common.adoc[common properties for JUnit and Spring]
as environment variables. The convention is that all the
letters should be upper case.
The dot (`.`) should be replaced with underscore (`_`) characters. For example,
@@ -417,18 +408,15 @@ We want to use the stubs created in this <<docker-server-side>> step.
Assume that we want to run the stubs on port `9876`. You can see the NodeJS code
by cloning the repository and changing to the directory indicated in the following commands:
====
[source,bash]
----
$ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
$ cd bookstore
----
====
Now we can run the Stub Runner Boot application with the stubs, by running the following
commands:
====
[source,bash]
----
# Provide the Spring Cloud Contract Docker version
@@ -449,7 +437,6 @@ $ docker run --rm \
-p "9876:9876" \
springcloud/spring-cloud-contract-stub-runner:"${SC_CONTRACT_DOCKER_VERSION}"
----
====
When the preceding commands run,
@@ -462,7 +449,6 @@ When the preceding commands run,
On the server side, we built a stateful stub. We can use curl to assert
that the stubs are setup properly. To do so, run the following commands:
====
[source,bash]
----
# let's run the first request (no response is returned)
@@ -471,11 +457,10 @@ $ curl -H "Content-Type:application/json" -X POST --data '{ "title" : "Title", "
$ curl -X GET http://localhost:9876/api/books
# You will receive contents of the JSON
----
====
IMPORTANT: If you want use the stubs that you have built locally, on your host,
you should set the `-e STUBRUNNER_STUBS_MODE=LOCAL` environment variable and mount
the volume of your local m2 (`-v "${HOME}/.m2/:/home/scc/.m2:ro"`).
the volume of your local m2 (`-v "$\{HOME}/.m2/:/home/scc/.m2:ro"`).
[[docker-stubrunner-example-messaging]]
=== Example of Usage with Messaging
@@ -576,7 +561,7 @@ yes | docker-compose kill
----
<1> We need to have the middleware running first
<2> The application needs to be up and running
<3> Via the `STANDALONE_PROTOCOL` environment variable we will fetch a https://camel.apache.org/components/latest/index.html[Apache Camel Component]. The artifact that we will fetch is `org.apache.camel.springboot:camel-${STANDALONE_PROTOCOL}-starter`. In other words `STANDALONE_PROTOCOL` is matching Camel's component.
<3> Via the `STANDALONE_PROTOCOL` environment variable we will fetch a https://camel.apache.org/components/latest/index.html[Apache Camel Component]. The artifact that we will fetch is `org.apache.camel.springboot:camel-$\{STANDALONE_PROTOCOL}-starter`. In other words `STANDALONE_PROTOCOL` is matching Camel's component.
<4> We're setting addresses (we could be setting credentials) via Camel's Spring Boot Starter mechanisms. Example for https://camel.apache.org/components/latest/rabbitmq-component.html#_spring_boot_auto_configuration[Apache Camel's RabbitMQ Spring Boot Auto-Configuration]
[[docker-stubrunner-running-middlware]]

View File

@@ -1,129 +0,0 @@
[[documentation]]
= Spring Cloud Contract Documentation
This section provides a brief overview of {project-full-name} reference documentation. It serves
as a map for the rest of the document.
[[contract-documentation-about]]
== About the Documentation
The {project-full-name} reference guide is available as
* {docs-url}/reference/html[Multi-page HTML]
* {docs-url}/reference/htmlsingle[Single-page HTML]
* {docs-url}/reference/pdf/{project-name}.pdf[PDF]
Copies of this document may be made for your own use and for distribution to others,
provided that you do not charge any fee for such copies and further provided that each
copy contains this Copyright Notice, whether distributed in print or electronically.
[[documentation-getting-help]]
== Getting Help
If you have trouble with {project-full-name}, we would like to help.
* Try the xref:howto.adoc[How-to documents]. They provide solutions to the most
common questions.
* Learn the {project-full-name} basics. If you are
starting out with {project-full-name}, try one of the https://spring.io/guides[guides].
* Ask a question. We monitor https://stackoverflow.com[stackoverflow.com] for questions
tagged with https://stackoverflow.com/tags/{project-name}[`{project-name}`].
* Report bugs with {project-full-name} at https://github.com/spring-cloud/{project-name}/issues.
* Chat with us at http://https://gitter.im/spring-cloud/{project-name}[{project-full-name} Gitter]
NOTE: All of {project-full-name} is open source, including the documentation. If you find
problems with the docs or if you want to improve them, please {github-code}[get
involved].
[[contract-documentation-first-steps]]
== First Steps
If you are getting started with {project-full-name} or 'Spring' in general, start with
xref:getting-started.adoc[the following topics]:
* *From scratch:*
<<getting-started.adoc#getting-started-introducing-{project-name}, Overview>> |
xref:getting-started/three-second-tour.adoc[Three-second Tour] |
xref:getting-started/first-application.adoc[First application]
* *Tutorial:*
xref:getting-started/cdc.adoc[Introduction] |
<<getting-started.adoc#consumer-side-loan-issuance, Consumer, Part 1>> |
<<getting-started.adoc#producer-side-fraud-detection-server, Producer>> |
xref:getting-started/cdc.adoc#getting-started-cdc-consumer-final[Consumer, Part 2]
[[working-with-{project-full-name}]]
== Working with {project-full-name}
Ready to actually start using {project-full-name}? xref:using.adoc[We have you covered]
:
* *Provider contract testing:*
** xref:using.adoc#flows-provider-nexus[Provider contract testing with stubs in Nexus or Artifactory]
** xref:using.adoc#flows-provider-git[Provider contract testing with stubs in Git]
** xref:using.adoc#flows-provider-non-spring[Provider contract testing with stubs in Artifactory for a non-Spring application]
** xref:using.adoc#flows-provider-non-jvm[Provider contract testing with stubs in Artifactory in non JVM world]
** xref:using.adoc#flows-provider-rest-docs[Provider contract testing with REST Docs and stubs in Nexus / Artifactory]
* *Consumer-Driven contract testing:*
** xref:using.adoc#flows-cdc-contracts-producer[Consumer Driven Contracts with contracts on the producer side]
** xref:using.adoc#flows-cdc-contracts-external[Consumer Driven Contracts with contracts in external repo]
** xref:using.adoc#flows-cdc-contracts-stubs-git[Consumer Driven Contracts with contracts on the producer side, pushed to git]
TIP: We talk about *Provider Contracts* when it is the producer of the API that defines the contracts and
publishes it for all its consumers to use. This approach is useful for producers that cannot
directly collaborate with their consumers -- for example, when there are too many consumers or
the consumers are external (do not work within the same company).
TIP: We use the term, *Consumer-Driven Contracts*, to refer to workflows where the consumers of an API
play a vital role in the process of creating the contracts. We recommended this approach, because it is easy
to implement when both producer and consumer teams work for the same organizations and the number
of consumers is not extremely large.
[[learning-about-{project-full-name}-features]]
== Learning about {project-full-name} Features
Need more details about {project-full-name}'s core features?
xref:project-features.adoc[The following content is for you]:
* *Core Features:*
xref:_project-features-contract.adoc[Contract DSL] |
xref:_project-features-contract/common-top-elements.adoc#features-http[Contracts for HTTP] |
xref:_project-features-messaging.adoc[Contracts for Messaging]
* *Integrations:*
xref:_project-features-flows/jax-rs.adoc[JAX-RS] |
xref:_project-features-flows/context-paths.adoc[Context Paths] |
xref:_project-features-flows/rest-docs.adoc[RESTDocs]
* *Modules:*
xref:_project-features-stubrunner.adoc[Stub Runner] |
xref:_project-features-wiremock.adoc[WireMock]
// TODO: links don't work in "build Tools" section
* *Build Tools:*
link:maven-project.html[Contract Verifier - Maven] |
link:gradle-project.html[Contract Verifier - Gradle] |
link:docker-project.html[Docker]
[[advanced-topics]]
== Advanced Topics
Finally, we have a few topics for more advanced users:
* *Customizing the DSL:*
<<advanced.adoc#contract-dsl-customization, DSL Customization>> |
<<advanced.adoc#contract-dsl-extending-common-jar, Common JAR>> |
<<advanced.adoc#contract-dsl-test-dep, Test Dependency>> |
<<advanced.adoc#contract-dsl-plugin-dep, Plugin Dependency>> |
<<advanced.adoc#contract-dsl-referencing, Referencing the DSL>>
* *Customizing WireMock:*
xref:advanced.adoc#customization-wiremock-extension[Extensions] |
xref:advanced.adoc#customization-wiremock-configuration[Configuration]
* *Customizing {project-full-name}:*
<<advanced.adoc#contract-dsl-pluggable-architecture, Pluggable Architecture>> |
<<advanced.adoc#contract-dsl-custom-contract-converter, Contract Converter>> |
<<advanced.adoc#contract-dsl-custom-test-generator, Test Generator>> |
<<advanced.adoc#contract-dsl-custom-stub-generator, Stub Generator>> |
<<advanced.adoc#contract-dsl-custom-stub-runner, Stub Runner>> |
<<advanced.adoc#contract-dsl-custom-stub-downloader, Stub Downloader>>

View File

@@ -2,6 +2,8 @@
= Getting Started
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
If you are getting started with {project-full-name} or Spring in general, start by reading
this section. It answers the basic "`what?`", "`how?`" and "`why?`" questions. It
includes an introduction to {project-full-name}, along with installation instructions. We then

View File

@@ -1,6 +1,8 @@
[[getting-started-cdc]]
= Step-by-step Guide to Consumer Driven Contracts (CDC) with Contracts on the Producer Side
include::partial$_attributes.adoc[]
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
us. The current implementation of our system grants loans to everybody.
@@ -33,21 +35,23 @@ in the producer's repository.
If you use the SNAPSHOT, Milestone, or Release Candidate versions, you need to add the
following section to your build:
====
[tabs]
======
Maven::
+
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=repos,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=repos,indent=0]
----
======
////
////
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0]
include::{samples_path}/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0]
----
====
For simplicity, we use the following acronyms:
@@ -109,12 +113,10 @@ We start with the loan issuance flow, which the following UML diagram shows:
The following listing shows a test that we might use to check whether a loan amount is too
large:
====
[source,groovy,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=client_tdd,indent=0]
include::{samples_path}/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=client_tdd,indent=0]
----
====
Assume that you have written a test of your new feature. If a loan application for a big
amount is received, the system should reject that loan application with some description.
@@ -127,12 +129,10 @@ that you need to send the request containing the ID of the client and the amount
client wants to borrow. You want to send it to the `/fraudcheck` URL by using the `PUT` method.
To do so, you might use code similar to the following:
====
[source,groovy,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/main/java/com/example/loan/LoanApplicationService.java[tags=client_call_server,indent=0]
include::{samples_path}/standalone/dsl/http-client/src/main/java/com/example/loan/LoanApplicationService.java[tags=client_call_server,indent=0]
----
====
For simplicity, the port of the Fraud Detection service is set to `8080`, and the
application runs on `8090`.
@@ -146,12 +146,10 @@ NOTE: If you start the test at this point, it breaks, because no service current
You can start by playing around with the server side contract. To do so, you must first
clone it, by running the following command:
====
[source,bash,indent=0]
----
$ git clone https://your-git-server.com/server-side.git local-http-server-repo
----
====
[[getting-started-cdc-consumer-define]]
=== Define the Contract Locally in the Repository of the Fraud Detection Service
@@ -164,21 +162,16 @@ is important because the producer's test base class name references that folder.
The following example shows our contract, in both Groovy and YAML:
====
[source,groovy,indent=0,role="primary"]
.groovy
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
----
////
////
[source,yaml,indent=0,role="secondary"]
.yaml
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
----
====
The YML contract is quite straightforward. However, when you take a look at the contract
written with a statically typed Groovy DSL, you might wonder what the
@@ -196,7 +189,7 @@ The previously shown contract is an agreement between two sides that:
* If an HTTP request is sent with all of:
** A `PUT` method on the `/fraudcheck` endpoint
** A JSON body with a `client.id` that matches the regular expression `[0-9]{10}` and
** A JSON body with a `client.id` that matches the regular expression `[0-9]\{10}` and
`loanAmount` equal to `99999`
** A `Content-Type` header with a value of `application/vnd.fraud.v1+json`
* Then an HTTP response is sent to the consumer that
@@ -214,21 +207,17 @@ install the stubs locally.
We can add either a Maven or a Gradle plugin. In this example, we show how to add Maven.
First, we add the `Spring Cloud Contract` BOM, as the following example shows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_bom,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=contract_bom,indent=0]
----
====
Next, add the `Spring Cloud Contract Verifier` Maven plugin, as the following example shows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
----
====
Since the plugin was added, you get the `Spring Cloud Contract Verifier` features, which,
from the provided contracts:
@@ -239,17 +228,14 @@ from the provided contracts:
You do not want to generate tests, since you, as the consumer, want only to play with the
stubs. You need to skip the test generation and invokation. To do so, run the following commands:
====
[source,bash,indent=0]
----
$ cd local-http-server-repo
$ ./mvnw clean install -DskipTests
----
====
Once you run those commands, you should you see something like the following content in the logs:
====
[source,bash,indent=0]
----
[INFO] --- spring-cloud-contract-maven-plugin:1.0.0.BUILD-SNAPSHOT:generateStubs (default-generateStubs) @ http-server ---
@@ -265,16 +251,13 @@ Once you run those commands, you should you see something like the following con
[INFO] Installing /some/path/http-server/pom.xml to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.pom
[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar
----
====
The following line is extremely important:
====
[source,bash,indent=0]
----
[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar
----
====
It confirms that the stubs of the `http-server` have been installed in the local
repository.
@@ -288,39 +271,32 @@ Application service`):
. Add the `Spring Cloud Contract` BOM, as follows:
+
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=contract_bom,indent=0]
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=contract_bom,indent=0]
----
====
. Add the dependency to `Spring Cloud Contract Stub Runner`, as follows:
+
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
----
====
. Annotate your test class with `@AutoConfigureStubRunner`. In the annotation, provide the
`group-id` and `artifact-id` for the Stub Runner to download the stubs of your
collaborators.
+
====
[source,groovy,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=autoconfigure_stubrunner,indent=0]
include::{samples_path}/standalone/dsl/http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java[tags=autoconfigure_stubrunner,indent=0]
----
====
. (Optional) Because you are playing with the collaborators offline, you
can also provide the offline work switch (`StubRunnerProperties.StubsMode.LOCAL`).
Now, when you run your tests, you see something like the following output in the logs:
====
[source,bash,indent=0]
----
2016-07-19 14:22:25.403 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Desired version is + - will try to resolve the latest version
@@ -331,7 +307,6 @@ Now, when you run your tests, you see something like the following output in the
2016-07-19 14:22:25.475 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacked file to [/var/folders/0p/xwq47sq106x1_g3dtv6qfm940000gq/T/contracts100276532569594265]
2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}]
----
====
This output means that Stub Runner has found your stubs and started a server for your application
with a group ID of `com.example` and an artifact ID of `http-server` with version `0.0.1-SNAPSHOT` of
@@ -384,42 +359,34 @@ The following UML diagram shows the fraud detection flow:
As a reminder, the following listing shows the initial implementation:
====
[source,java,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
}
----
====
Then you can run the following commands:
====
[source,bash,indent=0]
----
$ git checkout -b contract-change-pr master
$ git pull https://your-git-server.com/server-side-fork.git contract-change-pr
----
====
You must add the dependencies needed by the autogenerated tests, as follows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
----
====
In the configuration of the Maven plugin, you must pass the `packageWithBaseClasses` property, as follows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
----
====
IMPORTANT: This example uses "`convention-based`" naming by setting the
`packageWithBaseClasses` property. Doing so means that the two last packages combine to
@@ -433,16 +400,13 @@ or whatever is necessary. In this case, you should use https://github.com/rest-a
start the server side `FraudDetectionController`. The following listing shows the
`FraudBase` class:
====
[source,java,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/java/com/example/fraud/FraudBase.java[]
include::{samples_path}/standalone/dsl/http-server/src/test/java/com/example/fraud/FraudBase.java[]
----
====
Now, if you run the `./mvnw clean install`, you get something like the following output:
====
[source,bash,indent=0]
----
Results :
@@ -450,13 +414,11 @@ Results :
Tests in error:
ContractVerifierTest.validate_shouldMarkClientAsFraud:32 » IllegalState Parsed...
----
====
This error occurs because you have a new contract from which a test was generated, and it
failed since you have not implemented the feature. The auto-generated test would look
like the following test method:
====
[source,java,indent=0]
----
@Test
@@ -479,7 +441,6 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
assertThatJson(parsedJson).field("['rejection.reason']").isEqualTo("Amount too high");
}
----
====
If you used the Groovy DSL, you can see that all the `producer()` parts of the Contract that were present in the
`value(consumer(...), producer(...))` blocks got injected into the test.
@@ -497,15 +458,13 @@ in the response. In other words, you have the `red` part of `red`, `green`, and
Because you know the expected input and expected output, you can write the missing
implementation as follows:
====
[source,java,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=new_impl,indent=0]
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=server_api,indent=0]
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=new_impl,indent=0]
include::{samples_path}/standalone/dsl/http-server/src/main/java/com/example/fraud/FraudDetectionController.java[tags=initial_impl,indent=0]
}
----
====
When you run `./mvnw clean install` again, the tests pass. Since the Spring Cloud
Contract Verifier plugin adds the tests to the `generated-test-sources`, you can
@@ -517,14 +476,12 @@ actually run those tests from your IDE.
Once you finish your work, you can deploy your changes. To do so, you must first merge the
branch by running the following commands:
====
[source,bash,indent=0]
----
$ git checkout master
$ git merge --no-ff contract-change-pr
$ git push origin master
----
====
Your CI might run a command such as `./mvnw clean deploy`, which would publish both the
application and the stub artifacts.
@@ -560,13 +517,11 @@ The following UML diagram shows the final state of the process:
The following commands show one way to merge a branch into master with Git:
====
[source,bash,indent=0]
----
$ git checkout master
$ git merge --no-ff contract-change-pr
----
====
[[getting-started-cdc-consumer-final-online]]
=== Working Online
@@ -577,12 +532,10 @@ side are automatically downloaded from Nexus/Artifactory. You can set the value
`stubsMode` to `REMOTE`. The following code shows an example of
achieving the same thing by changing the properties:
====
[source,yaml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
include::{samples_path}/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
----
====
That's it. You have finished the tutorial.

View File

@@ -1,6 +1,8 @@
[[getting-started-first-application]]
= Developing Your First Spring Cloud Contract-based Application
include::partial$_attributes.adoc[]
This brief tour walks through using Spring Cloud Contract. It consists of the following topics:
* xref:getting-started/first-application.adoc#getting-started-first-application-producer[On the Producer Side]
@@ -13,7 +15,23 @@ For the sake of this example, the `Stub Storage` is Nexus/Artifactory.
The following UML diagram shows the relationship of the parts of Spring Cloud Contract:
image::getting-started-three-second.png[Getting started first application]
[plantuml, getting-started-three-second, png]
----
"API Producer"->"API Producer": add Spring Cloud \nContract (SCC) plugin
"API Producer"->"API Producer": add SCC Verifier dependency
"API Producer"->"API Producer": define contracts
"API Producer"->"Build": run build
"Build"->"SCC Plugin": generate \ntests, stubs and stubs \nartifact (e.g. stubs-jar)
"Build"->"Stub Storage": upload contracts \nand stubs and the project arifact
"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"->"Stub Storage": test asks for [API Producer] stubs
"Stub Storage"->"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
----
[[getting-started-first-application-producer]]
== On the Producer Side
@@ -21,17 +39,14 @@ image::getting-started-three-second.png[Getting started first application]
To start working with `Spring Cloud Contract`, you can add the Spring Cloud Contract Verifier
dependency and plugin to your build file, as the following example shows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
----
====
The following listing shows how to add the plugin, which should go in the build/plugins
portion of the file:
====
[source,xml,indent=0]
----
<plugin>
@@ -41,7 +56,6 @@ portion of the file:
<extensions>true</extensions>
</plugin>
----
====
[TIP]
====
@@ -64,9 +78,11 @@ For the HTTP stubs, a contract defines what kind of response should be returned
given request (taking into account the HTTP methods, URLs, headers, status codes, and so
on). The following example shows an HTTP stub contract in both Groovy and YAML:
====
[tabs]
======
groovy::
+
[source,groovy,indent=0,role="primary"]
.groovy
----
package contracts
@@ -95,8 +111,9 @@ org.springframework.cloud.contract.spec.Contract.make {
}
----
yaml::
+
[source,yaml,indent=0,role="secondary"]
.yaml
----
request:
method: PUT
@@ -119,7 +136,7 @@ response:
headers:
Content-Type: application/json;charset=UTF-8
----
====
======
If you need to use messaging, you can define:
@@ -130,19 +147,22 @@ was sent, the message body, and the header).
The following example shows a Camel messaging contract:
====
[tabs]
======
groovy::
+
[source,groovy,indent=0,role="primary"]
.groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl]
----
yaml::
+
[source,yaml,indent=0,role="secondary"]
.yaml
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_message_scenario1.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_message_scenario1.yml[indent=0]
----
====
======
Running `./mvnw clean install` automatically generates tests that verify the application
compliance with the added contracts. By default, the generated tests are under
@@ -163,9 +183,11 @@ of the other frameworks, add its library to your classpath.
The following listing shows samples for all frameworks:
====
[tabs]
======
mockmvc::
+
[source,java,indent=0,role="primary"]
.mockmvc
----
@Test
public void validate_shouldMarkClientAsFraud() throws Exception {
@@ -188,8 +210,9 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
}
----
jaxrs::
+
[source,java,indent=0,role="secondary"]
.jaxrs
----
@SuppressWarnings("rawtypes")
public class FooTest {
@@ -225,8 +248,9 @@ public class FooTest {
}
----
webtestclient::
+
[source,java,indent=0,role="secondary"]
.webtestclient
----
@Test
public void validate_shouldRejectABeerIfTooYoung() throws Exception {
@@ -247,7 +271,7 @@ public class FooTest {
assertThatJson(parsedJson).field("['status']").isEqualTo("NOT_OK");
}
----
====
======
As the implementation of the functionalities described by the contracts is not yet
present, the tests fail.
@@ -260,7 +284,6 @@ contain all the setup necessary information needed to run them (for example,
The following example, from `pom.xml`, shows how to specify the base test class:
====
[source,xml,indent=0]
----
<build>
@@ -283,11 +306,9 @@ The following example, from `pom.xml`, shows how to specify the base test class:
----
<1> The `baseClassForTests` element lets you specify your base test class. It must be a child
of a `configuration` element within `spring-cloud-contract-maven-plugin`.
====
The following example shows a minimal (but functional) base test class:
====
[source,java, indent=0]
----
package com.example.contractTest;
@@ -304,7 +325,6 @@ public class BaseTestClass {
}
}
----
====
This minimal class really is all you need to get your tests to work. It serves as a
starting place to which the automatically generated tests attach.
@@ -312,7 +332,6 @@ starting place to which the automatically generated tests attach.
Now we can move on to the implementation. For that, we first need a data class, which we
then use in our controller. The following listing shows the data class:
====
[source,java, indent=0]
----
package com.example.Test;
@@ -343,7 +362,6 @@ public class LoanRequest {
}
}
----
====
The preceding class provides an object in which we can store the parameters. Because the
client ID in the contract is called `client.id`, we need to use the
@@ -351,7 +369,6 @@ client ID in the contract is called `client.id`, we need to use the
Now we can move along to the controller, which the following listing shows:
====
[source,java, indent=0]
----
package com.example.docTest;
@@ -379,7 +396,6 @@ public class FraudController {
<3> If it is too much, we return the JSON (created with a simple string here) that the
test expects.
<4> If we had a test to catch when the amount is allowable, we could match it to this output.
====
The `FraudController` is about as simple as things get. You can do much more, including
logging, validating the client ID, and so on.
@@ -389,7 +405,6 @@ application and the stub artifacts are built and installed in the local Maven re
Information about installing the stubs jar to the local repository appears in the logs, as
the following example shows:
====
[source,bash,indent=0]
----
[INFO] --- spring-cloud-contract-maven-plugin:1.0.0.BUILD-SNAPSHOT:generateStubs (default-generateStubs) @ http-server ---
@@ -405,7 +420,6 @@ the following example shows:
[INFO] Installing /some/path/http-server/pom.xml to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT.pom
[INFO] Installing /some/path/http-server/target/http-server-0.0.1-SNAPSHOT-stubs.jar to /path/to/your/.m2/repository/com/example/http-server/0.0.1-SNAPSHOT/http-server-0.0.1-SNAPSHOT-stubs.jar
----
====
You can now merge the changes and publish both the application and the stub artifacts
in an online repository.
@@ -418,12 +432,10 @@ WireMock instance or messaging route that simulates the actual service.
To get started, add the dependency to `Spring Cloud Contract Stub Runner`, as follows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
----
====
You can get the Producer-side stubs installed in your Maven repository in either of two
ways:
@@ -431,13 +443,11 @@ ways:
* By checking out the Producer side repository and adding contracts and generating the
stubs by running the following commands:
+
====
[source,bash,indent=0]
----
$ cd local-http-server-repo
$ ./mvnw clean install -DskipTests
----
====
NOTE: The tests are skipped because the Producer-side contract implementation is not yet
in place, so the automatically-generated contract tests fail.
@@ -445,18 +455,15 @@ in place, so the automatically-generated contract tests fail.
pass the stub artifact IDs and artifact repository URL as `Spring Cloud Contract Stub
Runner` properties, as the following example shows:
+
====
[source,yaml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
include::{samples_path}/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
----
====
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
provide the `group-id` and `artifact-id` for `Spring Cloud Contract Stub Runner` to run
the collaborators' stubs for you, as the following example shows:
====
[source,java, indent=0]
----
@RunWith(SpringRunner.class)
@@ -467,7 +474,6 @@ public class LoanApplicationServiceTests {
. . .
}
----
====
TIP: Use the `REMOTE` `stubsMode` when downloading stubs from an online repository and
`LOCAL` for offline work.
@@ -476,7 +482,6 @@ In your integration test, you can receive stubbed versions of HTTP responses or
that are expected to be emitted by the collaborator service. You can see entries similar
to the following in the build logs:
====
[source,bash,indent=0]
----
2016-07-19 14:22:25.403 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Desired version is + - will try to resolve the latest version
@@ -487,5 +492,4 @@ to the following in the build logs:
2016-07-19 14:22:25.475 INFO 41050 --- [ main] o.s.c.c.stubrunner.AetherStubDownloader : Unpacked file to [/var/folders/0p/xwq47sq106x1_g3dtv6qfm940000gq/T/contracts100276532569594265]
2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}]
----
====

View File

@@ -1,6 +1,8 @@
[[getting-started-introducing-spring-cloud-contract]]
= Introducing Spring Cloud Contract
include::partial$_attributes.adoc[]
Spring Cloud Contract moves TDD to the level of software architecture.
It lets you perform consumer-driven and producer-driven contract testing.
@@ -106,21 +108,23 @@ amount it wants to borrow from us. You also want to send it to the `/fraudcheck`
the `PUT` method. The following listing shows a contract to check whether a client should
be marked as a fraud in both Groovy and YAML:
====
[tabs]
======
groovy::
+
[source,groovy,indent=0,role="primary"]
.groovy
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
----
======
////
////
[source,yaml,indent=0,role="secondary"]
.yaml
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
----
====
IMPORTANT: It is expected that contracts are coming from a **trusted source**. You should never download nor interact with contracts coming from untrusted locations.

View File

@@ -1,6 +1,8 @@
[[getting-started-three-second-tour]]
= A Three-second Tour
include::partial$_attributes.adoc[]
This very brief tour walks through using Spring Cloud Contract. It consists of the
following topics:
@@ -40,17 +42,14 @@ expressed in either Groovy DSL or YAML to the contracts directory, which is set
Then you can add the Spring Cloud Contract Verifier dependency and plugin to your build file, as
the following example shows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
include::{samples_path}/standalone/dsl/http-server/pom.xml[tags=verifier_test_dependencies,indent=0]
----
====
The following listing shows how to add the plugin, which should go in the build/plugins
portion of the file:
====
[source,xml,indent=0]
----
<plugin>
@@ -60,7 +59,6 @@ portion of the file:
<extensions>true</extensions>
</plugin>
----
====
Running `./mvnw clean install` automatically generates tests that verify the application
compliance with the added contracts. By default, the tests get generated under
@@ -77,7 +75,6 @@ controller setup or messaging test setup).
The following example, from `pom.xml`, shows how to specify the base test class:
====
[source,xml,indent=0]
----
<build>
@@ -100,7 +97,6 @@ The following example, from `pom.xml`, shows how to specify the base test class:
----
<1> The `baseClassForTests` element lets you specify your base test class. It must be a child
of a `configuration` element within `spring-cloud-contract-maven-plugin`.
====
Once the implementation and the test base class are in place, the tests pass, and both the
application and the stub artifacts are built and installed in the local Maven repository.
@@ -116,12 +112,10 @@ WireMock instance or messaging route that simulates the actual service.
To do so, add the dependency to `Spring Cloud Contract Stub Runner`, as the
following example shows:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
include::{samples_path}/standalone/dsl/http-client/pom.xml[tags=stub_runner,indent=0]
----
====
You can get the Producer-side stubs installed in your Maven repository in either of two
ways:
@@ -129,13 +123,11 @@ ways:
* By checking out the Producer side repository and adding contracts and generating the stubs
by running the following commands:
+
====
[source,bash,indent=0]
----
$ cd local-http-server-repo
$ ./mvnw clean install -DskipTests
----
====
TIP: The tests are being skipped because the producer-side contract implementation is not
in place yet, so the automatically-generated contract tests fail.
@@ -144,18 +136,15 @@ in place yet, so the automatically-generated contract tests fail.
pass the stub artifact IDs and artifact repository URL as `Spring Cloud Contract
Stub Runner` properties, as the following example shows:
+
====
[source,yaml,indent=0]
----
include:../:{introduction_url}/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
include::{samples_path}/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]
----
====
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
provide the `group-id` and `artifact-id` values for `Spring Cloud Contract Stub Runner` to
run the collaborators' stubs for you, as the following example shows:
====
[source,java, indent=0]
----
@RunWith(SpringRunner.class)
@@ -166,7 +155,6 @@ public class LoanApplicationServiceTests {
. . .
}
----
====
TIP: Use the `REMOTE` `stubsMode` when downloading stubs from an online repository and
`LOCAL` for offline work.

View File

@@ -1,6 +1,8 @@
[[getting-started-whats-next]]
= Next Steps
include::partial$_attributes.adoc[]
Hopefully, this section provided some of the {project-full-name} basics and got you on your way
to writing your own applications. If you are a task-oriented type of developer, you might
want to jump over to https://spring.io and check out some

View File

@@ -1,23 +1,7 @@
[[gradle-project]]
= Gradle Project
To learn how to set up the Gradle project for Spring Cloud Contract Verifier, read the
following sections:
* xref:gradle-project.adoc#gradle-prerequisites[Prerequisites]
* xref:gradle-project.adoc#gradle-add-gradle-plugin[Add Gradle Plugin with Dependencies]
* xref:gradle-project.adoc#gradle-and-rest-assured[Gradle and Rest Assured 2.0]
* xref:gradle-project.adoc#gradle-snapshot-versions[Snapshot Versions for Gradle]
* xref:gradle-project.adoc#gradle-add-stubs[Add stubs]
* xref:gradle-project.adoc#gradle-default-setup[Default Setup]
* xref:gradle-project.adoc#gradle-configure-plugin[Configuring the Plugin]
* xref:gradle-project.adoc#gradle-configuration-options[Configuration Options]
* xref:gradle-project.adoc#gradle-single-base-class[Single Base Class for All Tests]
* xref:gradle-project.adoc#gradle-different-base-classes[Different Base Classes for Contracts]
* xref:gradle-project.adoc#gradle-invoking-generated-tests[Invoking Generated Tests]
* xref:gradle-project.adoc#gradle-publishing-stubs-to-artifact-repo[Publishing Stubs to Artifact Repository]
* xref:gradle-project.adoc#gradle-pushing-stubs-to-scm[Pushing Stubs to SCM]
* xref:gradle-project.adoc#gradle-consumer[Spring Cloud Contract Verifier on the Consumer Side]
include::partial$_attributes.adoc[]
[[gradle-prerequisites]]
== Prerequisites
@@ -34,39 +18,42 @@ documentation] for more information.
To add a Gradle plugin with dependencies, you can use code similar to the following:
====
[tabs]
======
Plugin DSL GA versions::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Plugin DSL GA versions
----
// build.gradle
plugins {
id "groovy"
// this will work only for GA versions of Spring Cloud Contract
id "org.springframework.cloud.contract" version "${GAVerifierVersion}"
id "org.springframework.cloud.contract" version "$\{GAVerifierVersion}"
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${GAVerifierVersion}"
mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:$\{GAVerifierVersion}"
}
}
dependencies {
testImplementation "org.apache.groovy:groovy-all:${groovyVersion}"
testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}"
// example with adding Spock core and Spock Spring
testImplementation "org.spockframework:spock-core:${spockVersion}"
testImplementation "org.spockframework:spock-spring:${spockVersion}"
testImplementation "org.spockframework:spock-core:$\{spockVersion}"
testImplementation "org.spockframework:spock-spring:$\{spockVersion}"
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
----
Plugin DSL non GA versions::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Plugin DSL non GA versions
----
// settings.gradle
pluginManagement {
plugins {
id "org.springframework.cloud.contract" version "${verifierVersion}"
id "org.springframework.cloud.contract" version "$\{verifierVersion}"
}
repositories {
// to pick from local .m2
@@ -88,21 +75,22 @@ plugins {
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifierVersion}"
mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:$\{verifierVersion}"
}
}
dependencies {
testImplementation "org.apache.groovy:groovy-all:${groovyVersion}"
testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}"
// example with adding Spock core and Spock Spring
testImplementation "org.spockframework:spock-core:${spockVersion}"
testImplementation "org.spockframework:spock-spring:${spockVersion}"
testImplementation "org.spockframework:spock-core:$\{spockVersion}"
testImplementation "org.spockframework:spock-spring:$\{spockVersion}"
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
----
Legacy Plugin Application::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Legacy Plugin Application
----
// build.gradle
buildscript {
@@ -110,10 +98,10 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springboot_version}"
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifier_version}"
classpath "org.springframework.boot:spring-boot-gradle-plugin:$\{springboot_version}"
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:$\{verifier_version}"
// here you can also pass additional dependencies such as Kotlin spec e.g.:
// classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:${verifier_version}"
// classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:$\{verifier_version}"
}
}
@@ -122,19 +110,19 @@ apply plugin: 'org.springframework.cloud.contract'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifier_version}"
mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:$\{verifier_version}"
}
}
dependencies {
testImplementation "org.apache.groovy:groovy-all:${groovyVersion}"
testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}"
// example with adding Spock core and Spock Spring
testImplementation "org.spockframework:spock-core:${spockVersion}"
testImplementation "org.spockframework:spock-spring:${spockVersion}"
testImplementation "org.spockframework:spock-core:$\{spockVersion}"
testImplementation "org.spockframework:spock-spring:$\{spockVersion}"
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
----
====
======
[[gradle-and-rest-assured]]
== Gradle and Rest Assured 2.0
@@ -142,7 +130,6 @@ dependencies {
By default, Rest Assured 3.x is added to the classpath. However, to use Rest Assured 2.x,
you can add it instead, as the following listing shows:
====
[source,groovy,indent=0]
----
buildscript {
@@ -150,8 +137,8 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springboot_version}"
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifier_version}"
classpath "org.springframework.boot:spring-boot-gradle-plugin:$\{springboot_version}"
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:$\{verifier_version}"
}
}
@@ -162,7 +149,6 @@ dependencies {
testCompile "com.jayway.restassured:spring-mock-mvc:2.5.0"
}
----
====
That way, the plugin automatically sees that Rest Assured 2.x is present on the classpath
and modifies the imports accordingly.
@@ -173,13 +159,11 @@ and modifies the imports accordingly.
You can add the additional snapshot repository to your `settings.gradle` to use snapshot versions,
which are automatically uploaded after every successful build, as the following listing shows:
====
[source,groovy,indent=0]
----
include::{standalone_samples_path}/http-server/settings.gradle[tags=repos,indent=0]
}
----
====
[[gradle-add-stubs]]
== Add stubs
@@ -190,8 +174,8 @@ will also look for contracts in `src/test/resources/contracts`, however, this di
is deprecated as of Spring Cloud Contract 3.0.0.
It should also be noted, that with this new Gradle source set, you should also migrate
any base classes used within your contract tests to `src/contractTest/{language}` where
`{language}` should be replaced with Java or Groovy as needed for your purposes.
any base classes used within your contract tests to `src/contractTest/\{language}` where
`\{language}` should be replaced with Java or Groovy as needed for your purposes.
The directory that contains stub definitions is treated as a class name, and each stub
definition is treated as a single test. Spring Cloud Contract Verifier assumes that it
@@ -199,13 +183,11 @@ contains at least one level of directories that are to be used as the test class
If more than one level of nested directories is present, all except the last one is used
as the package name. Consider the following structure:
====
[source,groovy,indent=0]
----
src/contractTest/resources/contracts/myservice/shouldCreateUser.groovy
src/contractTest/resources/contracts/myservice/shouldReturnUser.groovy
----
====
Given the preceding structure, Spring Cloud Contract Verifier creates a test class named
`defaultBasePackage.MyService` with two methods:
@@ -226,18 +208,17 @@ tests, invoke the `generateContractTests` task.
The default Gradle Plugin setup creates the following Gradle part of the build (in
pseudocode):
====
[source,groovy,indent=0]
----
contracts {
testFramework ='JUNIT'
testMode = 'MockMvc'
generatedTestJavaSourcesDir = project.file("${project.buildDir}/generated-test-sources/contractTest/java")
generatedTestGroovySourcesDir = project.file("${project.buildDir}/generated-test-sources/contractTest/groovy")
generatedTestResourcesDir = project.file("${project.buildDir}/generated-test-resources/contracts")
contractsDslDir = project.file("${project.projectDir}/src/contractTest/resources/contracts")
generatedTestJavaSourcesDir = project.file("$\{project.buildDir}/generated-test-sources/contractTest/java")
generatedTestGroovySourcesDir = project.file("$\{project.buildDir}/generated-test-sources/contractTest/groovy")
generatedTestResourcesDir = project.file("$\{project.buildDir}/generated-test-resources/contracts")
contractsDslDir = project.file("$\{project.projectDir}/src/contractTest/resources/contracts")
basePackageForTests = 'org.springframework.cloud.verifier.tests'
stubsOutputDir = project.file("${project.buildDir}/stubs")
stubsOutputDir = project.file("$\{project.buildDir}/stubs")
sourceSet = null
}
@@ -254,7 +235,6 @@ def copyContracts = tasks.register(type: Copy, name: 'copyContracts') {
verifierStubsJar.dependsOn copyContracts
----
====
[[gradle-configure-plugin]]
== Configuring the Plugin
@@ -262,7 +242,6 @@ verifierStubsJar.dependsOn copyContracts
To change the default configuration, you can add a `contracts` snippet to your Gradle
configuration, as the following listing shows:
====
[source,groovy,indent=0]
----
contracts {
@@ -271,11 +250,9 @@ contracts {
generatedTestJavaSourcesDir = project.file('src/generatedContract')
}
----
====
To download contracts from a remote source, you can use the following snippets as needed:
====
[source,groovy,indent=0]
----
contracts {
@@ -300,22 +277,19 @@ contracts {
contractsPath = ''
}
----
====
Since we are using Gradle's Jar packaging task, there are several options and capabilities that you may wish to utilize to further extend what is created by the `verifierStubsJar`. In order to do this, you would use the native mechanisms provided directly by Gradle for customizing an existing task like so:
NOTE: for the sake of the example, we desire to add a `git.properties` file to the `verifierStubsJar`.
====
[source,groovy,inden=0]
----
verifierStubsJar {
from("${buildDir}/resources/main/") {
from("$\{buildDir}/resources/main/") {
include("git.properties")
}
}
----
====
It should also be noted that as of 3.0.0, the default publication has been disabled. As a result this means, that you are able to create any named jar and publish it as you would normally have done via Gradle configuration options. This means that you can build a jar file customized just the way you would like and publish that for absolute full control over the jar's layout and contents.
@@ -399,12 +373,10 @@ When using Spring Cloud Contract Verifier in MockMvc (the default), you need to
specification for all generated acceptance tests. In this class, you need to point to an
endpoint, which should be verified. The following example shows how to do so:
====
[source,groovy,indent=0]
----
include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0]
----
====
If you use `Explicit` mode, you can use a base class to initialize the whole tested application,
as you might see in regular integration tests. If you use the `JAXRSCLIENT` mode, this
@@ -454,12 +426,10 @@ generated from `src/contractTest/resources/contract/com/` contracts extend the
To ensure that the provider side is compliant with your defined contracts, you need to run
the following command:
====
[source,bash,indent=0]
----
./gradlew contractTest
----
====
[[gradle-publishing-stubs-to-artifact-repo]]
== Publishing Stubs to Artifact Repository
@@ -469,7 +439,6 @@ you will need to configure the publishing section for Gradle to
include the `verifierStubsJar`. To do that, you can use the
example configuration below:
====
[source,groovy,indent=0]
----
apply plugin: 'maven-publish'
@@ -484,7 +453,6 @@ publishing {
}
}
----
====
Since 3.0.0, the internal stubs publication has been deprecated
and disabled by default. It is recommended to include the
@@ -498,12 +466,10 @@ stubs, you might want to automate the step of pushing stubs to
the repository. To do that, you can call the `pushStubsToScm`
task by running the following command:
====
[source,bash,indent=0]
----
$ ./gradlew pushStubsToScm
----
====
Under xref:advanced.adoc#scm-stub-downloader[Using the SCM Stub Downloader], you can find all possible
configuration options that you can pass either through
@@ -519,19 +485,16 @@ in exactly the same way as in the case of a provider. If you do not want to use
you need to copy the contracts stored in `src/contractTest/resources/contracts` and generate
WireMock JSON stubs by using the following command:
====
[source,bash,indent=0]
----
./gradlew generateClientStubs
----
====
NOTE: The `stubsOutputDir` option has to be set for stub generation to work.
When present, you can use JSON stubs in automated tests to consume a service. The
following example shows how to do so:
====
[source,groovy,indent=0]
----
@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
@@ -556,7 +519,6 @@ class LoanApplicationServiceSpec extends Specification {
}
}
----
====
In the preceding example, `LoanApplication` makes a call to the `FraudDetection` service.
This request is handled by a WireMock server configured with stubs that were generated by

View File

@@ -2,6 +2,8 @@
= "`How-to`" Guides
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
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.

View File

@@ -1,40 +1,48 @@
[[contract-dsl-rest-docs]]
= How Can I Generate Spring REST Docs Snippets from the Contracts?
include::partial$_attributes.adoc[]
When you want to include the requests and responses of your API by using Spring REST Docs,
you only need to make some minor changes to your setup if you are using MockMvc and RestAssuredMockMvc.
To do so, include the following dependencies (if you have not already done so):
====
[tabs]
======
maven::
+
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.maven
----
include:../:{standalone_restdocs_path}/http-server/pom.xml[tags=dependencies,indent=0]
include::{standalone_restdocs_path}/http-server/pom.xml[tags=dependencies,indent=0]
----
gradle::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.gradle
----
include:../:{standalone_restdocs_path}/http-server/build.gradle[tags=dependencies,indent=0]
include::{standalone_restdocs_path}/http-server/build.gradle[tags=dependencies,indent=0]
----
====
======
Next, you need to make some changes to your base class. The following examples use
`WebAppContext` and the standalone option with RestAssured:
====
[tabs]
======
WebAppContext::
+
[source,java,indent=0,subs="verbatim,attributes",role="primary"]
.WebAppContext
----
include:../:{standalone_restdocs_path}/http-server/src/test/java/com/example/fraud/FraudBaseWithWebAppSetup.java[tags=base_class,indent=0]
include::{standalone_restdocs_path}/http-server/src/test/java/com/example/fraud/FraudBaseWithWebAppSetup.java[tags=base_class,indent=0]
----
Standalone::
+
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Standalone
----
include:../:{standalone_restdocs_path}/http-server/src/test/java/com/example/fraud/FraudBaseWithStandaloneSetup.java[tags=base_class,indent=0]
include::{standalone_restdocs_path}/http-server/src/test/java/com/example/fraud/FraudBaseWithStandaloneSetup.java[tags=base_class,indent=0]
----
====
======
TIP: You need not specify the output directory for the generated snippets (since version 1.2.0.RELEASE of Spring REST Docs).

View File

@@ -1,6 +1,8 @@
[[how-to-common-repo-with-contracts]]
= How Can I use a Common Repository with Contracts Instead of Storing Them with the Producer?
include::partial$_attributes.adoc[]
Another way of storing contracts, rather than having them with the producer, is to keep
them in a common place. This situation can be related to security issues (where the
consumers cannot clone the producer's code). Also, if you keep contracts in a single place,
@@ -16,7 +18,6 @@ contracts, you could have the following setup (which you can check out
https://github.com/spring-cloud/spring-cloud-contract/tree/{github-tag}/samples/standalone/contracts[here]).
The following listing shows such a structure:
====
[source,bash,indent=0]
----
├── com
@@ -36,7 +37,6 @@ The following listing shows such a structure:
└── assembly
└── contracts.xml
----
====
Under the slash-delimited `groupid/artifact id` folder (`com/example/server`), you have
expectations of the three consumers (`client1`, `client2`, and `client3`). Expectations are the standard Groovy DSL
@@ -45,12 +45,10 @@ one-to-one to the contents of the repository.
The following example shows a `pom.xml` file inside the `server` folder:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/contracts/com/example/server/pom.xml[indent=0]
include::{samples_path}/standalone/contracts/com/example/server/pom.xml[indent=0]
----
====
There are no dependencies other than the Spring Cloud Contract Maven Plugin.
Those `pom.xml` files are necessary for the consumer side to run `mvn clean install -DskipTests` to locally install
@@ -58,22 +56,18 @@ the stubs of the producer project.
The `pom.xml` file in the root folder can look like the following:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/contracts/pom.xml[indent=0]
include::{samples_path}/standalone/contracts/pom.xml[indent=0]
----
====
It uses the assembly plugin to build the JAR with all the contracts. The following example
shows such a setup:
====
[source,xml,indent=0]
----
include:../:{introduction_url}/samples/standalone/contracts/src/assembly/contracts.xml[indent=0]
include::{samples_path}/standalone/contracts/src/assembly/contracts.xml[indent=0]
----
====
[[how-to-workflow]]
== Workflow
@@ -134,12 +128,10 @@ TIP: You need to have https://maven.apache.org/download.cgi[Maven installed loca
As a producer, you can alter the Spring Cloud Contract Verifier to provide the URL and
the dependency of the JAR that contains the contracts, as follows:
====
[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]
include::{tools_path}/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 a `groupid` of `com.example.standalone` and an `artifactid` of
`contracts` is downloaded from `https://link/to/your/nexus/or/artifactory/or/sth`. It is
@@ -167,7 +159,6 @@ lets us do so. Also, `contractsPath` need to be specified, since the default pat
the common repository `groupid/artifactid`. The following example shows a Maven
plugin for Spring Cloud Contract:
====
[source,xml,indent=0]
----
<plugin>
@@ -201,7 +192,6 @@ plugin for Spring Cloud Contract:
</configuration>
</plugin>
----
====
NOTE: Many of the values in the preceding Maven plugin can be changed. We included it for
illustration purposes rather than trying to provide a "`typical`" example.
@@ -213,7 +203,6 @@ To work with a Gradle project:
. Add a custom configuration for the common repository dependency, as follows:
+
====
[source,groovy,indent=0]
----
ext {
@@ -228,11 +217,9 @@ configurations {
}
}
----
====
. Add the common repository dependency to your classpath, as follows:
+
====
[source,groovy,indent=0]
----
dependencies {
@@ -240,11 +227,9 @@ dependencies {
testCompile "${contractsGroupId}:${contractsArtifactId}:${contractsVersion}"
}
----
====
. Download the dependency to an appropriate folder, as follows:
+
====
[source,groovy,indent=0]
----
task getContracts(type: Copy) {
@@ -252,11 +237,9 @@ task getContracts(type: Copy) {
into new File(project.buildDir, "downloadedContracts")
}
----
====
. Unzip the JAR, as follows:
+
====
[source,groovy,indent=0]
----
task unzipContracts(type: Copy) {
@@ -267,11 +250,9 @@ task unzipContracts(type: Copy) {
into outputDir
}
----
====
. Cleanup unused contracts, as follows:
+
====
[source,groovy,indent=0]
----
task deleteUnwantedContracts(type: Delete) {
@@ -283,28 +264,23 @@ task deleteUnwantedContracts(type: Delete) {
"**/${second-topic}/**"])
}
----
====
. Create task dependencies, as follows:
+
====
[source,groovy,indent=0]
----
unzipContracts.dependsOn("getContracts")
deleteUnwantedContracts.dependsOn("unzipContracts")
build.dependsOn("deleteUnwantedContracts")
----
====
. Configure the plugin by specifying the directory that contains the contracts, by setting
the `contractsDslDir` property, as follows:
+
====
[source,groovy,indent=0]
----
contracts {
contractsDslDir = new File("${buildDir}/unpackedContracts")
}
----
====

View File

@@ -2,6 +2,8 @@
= How Can I Debug the Mapping, Request, or Response Being Sent by WireMock?
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
Starting from version `1.2.0`, we set WireMock logging to
`info` and set the WireMock notifier to being verbose. Now you can
exactly know what request was received by the WireMock server and which
@@ -9,10 +11,8 @@ matching response definition was picked.
To turn off this feature, set WireMock logging to `ERROR`, as follows:
====
[source,properties,indent=0]
----
logging.level.com.github.tomakehurst.wiremock=ERROR
----
====

View File

@@ -2,6 +2,8 @@
= How Can I Debug the Request/Response Being Sent by the Generated Tests Client?
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
The generated tests all boil down to RestAssured in some form or fashion. RestAssured
relies on the https://hc.apache.org/httpcomponents-client-ga/[Apache HttpClient].
HttpClient has a facility called
@@ -10,10 +12,8 @@ which logs the entire request and response to HttpClient. Spring Boot has a logg
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html[common application property]
for doing this sort of thing. To use it, add it to your application properties, as follows:
====
[source,properties,indent=0]
----
logging.level.org.apache.http.wire=DEBUG
----
====

View File

@@ -1,6 +1,8 @@
[[how-to-do-stubs-versioning]]
= How to Do Stubs versioning?
include::partial$_attributes.adoc[]
This section covers versioning of the stubs, which you can handle in a number of different ways:
* xref:howto/how-to-do-stubs-versioning.adoc#how-to-api-versioning[API Versioning]
@@ -31,42 +33,34 @@ Assume that you do continuous delivery and deployment, which means that you gene
the jar each time you go through the pipeline and that the jar can go to production at any time. For example, your jar version
looks like the following (because it got built on the 20.10.2016 at 20:15:21) :
====
[source,groovy,indent=0]
----
1.0.0.20161020-201521-RELEASE
----
====
In that case, your generated stub jar should look like the following:
====
[source,groovy,indent=0]
----
1.0.0.20161020-201521-RELEASE-stubs.jar
----
====
In this case, you should, inside your `application.yml` or `@AutoConfigureStubRunner` when
referencing stubs, provide the latest version of the stubs. You can do that by passing the
`+` sign. the following example shows how to do so:
====
[source,java,indent=0]
----
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})
----
====
If the versioning, however, is fixed (for example, `1.0.4.RELEASE` or `2.1.1`), you have to set the concrete value of the jar
version. The following example shows how to do so for version 2.1.1:
====
[source,java,indent=0]
----
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:2.1.1:stubs:8080"})
----
====
[[how-to-dev-or-prod-stubs]]
== Development or Production Stubs
@@ -78,21 +72,17 @@ deployment, you can run tests in one case with development stubs and in another
The following example works for tests that use the development version of the stubs:
====
[source,java,indent=0]
----
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})
----
====
The following example works for tests that use the production version of stubs:
====
[source,java,indent=0]
----
@AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:prod-stubs:8080"})
----
====
You can also pass those values also in properties from your deployment pipeline.

View File

@@ -0,0 +1,17 @@
[[how-to-generate-from-scc]]
= How Can I Generate YAML, or X files from Spring Cloud Contract Contracts?
include::partial$_attributes.adoc[]
Spring Cloud Contract comes with a `ToFileContractsTransformer` class that lets you dump
contracts as files for the given `ContractConverter`. It contains a `static void main`
method that lets you run the transformer as an executable. It takes the following
arguments:
- argument 1 : `FQN`: Fully qualified name of the `ContractConverter` (for example, `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 calling the transformer, the Spring Cloud Contract files are processed and,
depending on the provided FQN of the `ContractTransformer`, the contracts are transformed
to the required format and dumped to the provided folder.

View File

@@ -1,67 +0,0 @@
[[how-to-generate-pact-from-scc]]
= How Can I Generate Pact, YAML, or X files from Spring Cloud Contract Contracts?
Spring Cloud Contract comes with a `ToFileContractsTransformer` class that lets you dump
contracts as files for the given `ContractConverter`. It contains a `static void main`
method that lets you run the transformer as an executable. It takes the following
arguments:
- argument 1 : `FQN`: Fully qualified name of the `ContractConverter` (for example, `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 calling the transformer, the Spring Cloud Contract files are processed and,
depending on the provided FQN of the `ContractTransformer`, the contracts are transformed
to the required format and dumped to the provided folder.
The following example shows how to configure Pact integration for both Maven and Gradle:
====
[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")
----
====

View File

@@ -2,5 +2,7 @@
= How Can I Generate Stubs at Runtime
:page-section-summary-toc: 1
If you want to generate stubs at runtime for contracts, switch the `generateStubs` property in the `@AutoConfigureStubRunner` annotation, or call the `withGenerateStubs(true)` method on the JUnit Rule or Extension. You can read more about this in xref:_project-features-stubrunner/stub-runner-generate-stubs-at-runtime.adoc[this section] of the documentation.
include::partial$_attributes.adoc[]
If you want to generate stubs at runtime for contracts, switch the `generateStubs` property in the `@AutoConfigureStubRunner` annotation, or call the `withGenerateStubs(true)` method on the JUnit Rule or Extension. You can read more about this in xref:../project-features-stubrunner/stub-runner-generate-stubs-at-runtime.adoc[this section] of the documentation.

View File

@@ -2,6 +2,8 @@
= How Can I Mark that a Contract Is in Progress
:page-section-summary-toc: 1
If a contract is in progress, it means that the, on the producer side, tests are not generated, but the stub is generated. You can read more about this in xref:_project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[this section] of the documentation.
include::partial$_attributes.adoc[]
If a contract is in progress, it means that the, on the producer side, tests are not generated, but the stub is generated. You can read more about this in xref:project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[this section] of the documentation.
In a CI build, before going to production, you would like to ensure that no in-progress contracts are on the classpath, because they may lead to false positives. For this reason, by default, in the Spring Cloud Contract plugin, we set the value of `failOnInProgress` to `true`. If you want to allow such contracts when tests are to be generated, set the flag to `false`.

View File

@@ -2,7 +2,7 @@
= How Can I Write Contracts in a Language Other than Groovy?
:page-section-summary-toc: 1
You can write a contract in YAML. See xref:_project-features-contract.adoc[this section] for more information.
You can write a contract in YAML. See xref:../project-features-contract.adoc[this section] for more information.
We are working on allowing more ways of describing the contracts. You can check the {github-issues}[github-issues] for more information.

View File

@@ -1,11 +1,12 @@
[[how-to-provide-dynamic-values]]
= How Can I Provide Dynamic Values to a Contract?
include::partial$_attributes.adoc[]
One of the biggest challenges related to stubs is their reusability. Only if they can be widely used can they serve their purpose.
The hard-coded values (such as dates and IDs) of request and response elements generally make that difficult.
Consider the following JSON request:
====
[source,json,indent=0]
----
{
@@ -14,11 +15,9 @@ Consider the following JSON request:
"body" : "foo"
}
----
====
Now consider the following JSON response:
====
[source,json,indent=0]
----
{
@@ -27,7 +26,6 @@ Now consider the following JSON response:
"body" : "bar"
}
----
====
Imagine the pain required to set the proper value of the `time` field (assume that this content is generated by the
database) by changing the clock in the system or by providing stub implementations of data providers. The same is related
@@ -38,7 +36,6 @@ works as usual, generating data without you having to stub out anything. Assume
JSON, the most important part is the `body` field. You can focus on that and provide matching for other fields. In other words,
you would like the stub to work as follows:
====
[source,json,indent=0]
----
{
@@ -47,12 +44,10 @@ you would like the stub to work as follows:
"body" : "foo"
}
----
====
As far as the response goes, as a consumer, you need a concrete value on which you can operate.
Consequently, the following JSON is valid:
====
[source,json,indent=0]
----
{
@@ -61,14 +56,12 @@ Consequently, the following JSON is valid:
"body" : "bar"
}
----
====
In the previous sections, we generated tests from contracts. So, from the producer's side, the situation looks
much different. We parse the provided contract, and, in the test, we want to send a real request to your endpoints.
So, for the case of a producer for the request, we cannot have any sort of matching. We need concrete values on which the
producer's backend can work. Consequently, the following JSON would be valid:
====
[source,json,indent=0]
----
{
@@ -77,14 +70,12 @@ producer's backend can work. Consequently, the following JSON would be valid:
"body" : "foo"
}
----
====
On the other hand, from the point of view of the validity of the contract, the response does not necessarily have to
contain concrete values for `time` or `id`. Suppose you generate those on the producer side. Again, you
have to do a lot of stubbing to ensure that you always return the same values. That is why, from the producer's side,
you might want the following response:
====
[source,json,indent=0]
----
{
@@ -93,13 +84,12 @@ you might want the following response:
"body" : "bar"
}
----
====
How can you then provide a matcher for the consumer and a concrete value for the producer (and the opposite at some other time)?
Spring Cloud Contract lets you provide a dynamic value. That means that it can differ for both
sides of the communication.
You can read more about this in the xref:_project-features-contract.adoc[Contract DSL] section.
You can read more about this in the xref:project-features-contract.adoc[Contract DSL] section.
IMPORTANT: Read the https://groovy-lang.org/json.html[Groovy docs related to JSON] to understand how to
properly structure the request and response bodies.

View File

@@ -2,6 +2,8 @@
= How Can I Reference Text from File?
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
In version 1.2.0, we added this ability. You can call a `file(...)` method in the
DSL and provide a path relative to where the contract lies.
If you use YAML, you can use the `bodyFromFile` property.

View File

@@ -2,6 +2,8 @@
= How Can I See What Got Registered in the HTTP Server Stub?
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
You can use the `mappingsOutputFolder` property on `@AutoConfigureStubRunner`, `StubRunnerRule`, or
`StubRunnerExtension` to dump all mappings for each artifact ID. Also, the port at which the given stub server
was started is attached.

View File

@@ -1,6 +1,8 @@
[[how-to-use-git-as-storage]]
= How Can I Use Git as the Storage for Contracts and Stubs?
include::partial$_attributes.adoc[]
In the polyglot world, there are languages that do not use binary storage, as
Artifactory and Nexus do. Starting from Spring Cloud Contract version 2.0.0, we provide
mechanisms to store contracts and stubs in a SCM (Source Control Management) repository. Currently, the
@@ -9,7 +11,6 @@ only supported SCM is Git.
The repository would have to have the following setup
(which you can checkout from https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/contracts_git/[here]):
====
[source,indent=0]
----
.
@@ -31,7 +32,6 @@ The repository would have to have the following setup
├── shouldGrantABeerIfOldEnough.json
└── shouldRejectABeerIfTooYoung.json
----
====
Under the `META-INF` folder:
@@ -73,14 +73,12 @@ For the SCM functionality, currently, we support the Git repository. To use it,
in the property where the repository URL needs to be placed, you have to prefix
the connection URL with `git://`. The following listing shows some examples:
====
[source,indent=0]
----
git://file:///foo/bar
git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git
git://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git
----
====
[[how-to-protocol-convention-producer]]
== Producer
@@ -97,9 +95,11 @@ repository.
The following listing includes the relevant parts both Maven and Gradle build files:
====
[tabs]
======
Maven::
+
[source,xml,indent=0,role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -137,8 +137,9 @@ The following listing includes the relevant parts both Maven and Gradle build fi
</plugin>
----
Gradle::
+
[source,groovy,indent=0,role="secondary"]
.Gradle
----
contracts {
// We want to pick contracts from a Git repository
@@ -164,12 +165,11 @@ the `publish` task is invoked
*/
publish.dependsOn("publishStubsToScm")
----
====
======
You can also further customize the `publishStubsToScm` gradle task. In the following example,
the task is customized to pick contracts from a local git repository:
====
[source,groovy,indent=0]
.gradle
----
@@ -191,7 +191,6 @@ publishStubsToScm {
contractsMode = "LOCAL"
}
----
====
IMPORTANT:: Starting with the `2.3.0.RELEASE`, the `customize{}` closure previously used for the
`publishStubsToScm` customization is no longer available. The settings should be applied directly
@@ -213,21 +212,7 @@ to find contracts. For example, for `com.example:foo:1.0.0`, the path would be
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.
The following listing shows the setup required to achieve this with Maven and Gradle:
====
[source,xml,indent=0,role="primary"]
.Maven
----
include:../:{samples_url}/producer_with_empty_git/pom.xml[tags=plugin,indent=0]
----
[source,groovy,indent=0,role="secondary"]
.Gradle
----
include:../:{samples_url}/producer_with_empty_git/build.gradle[tags=plugin,indent=0]
----
====
The following {samples_url}/producer_with_empty_git/[project] shows the setup required to achieve this with Maven and Gradle.
With such a setup:
@@ -257,7 +242,6 @@ either from the `@AutoConfigureStubRunner` annotation, the
JUnit 4 rule, JUnit 5 extension, or properties, you can pass the URL of the
SCM repository, prefixed with the `git://` protocol. The following example shows how to do so:
====
[source,java,indent=0]
----
@AutoConfigureStubRunner(
@@ -266,7 +250,6 @@ SCM repository, prefixed with the `git://` protocol. The following example shows
ids="com.example:bookstore:0.0.1.RELEASE"
)
----
====
With such a setup:

View File

@@ -2,5 +2,7 @@
= How Can I Use Stubs from a Location
:page-section-summary-toc: 1
If you want to fetch contracts or stubs from a given location without cloning a repository or fetching a JAR, use the `stubs://` protocol when providing the repository root argument for Stub Runner or the Spring Cloud Contract plugin. You can read more about this in xref:_project-features-stubrunner/stub-runner-stubs-protocol.adoc[this section] of the documentation.
include::partial$_attributes.adoc[]
If you want to fetch contracts or stubs from a given location without cloning a repository or fetching a JAR, use the `stubs://` protocol when providing the repository root argument for Stub Runner or the Spring Cloud Contract plugin. You can read more about this in xref:../project-features-stubrunner/stub-runner-stubs-protocol.adoc[this section] of the documentation.

View File

@@ -2,7 +2,9 @@
= How Can I Make The Build Pass if There Are No Contracts or Stubs
:page-section-summary-toc: 1
If you want Stub Runner not to fail if no stubs were found, switch the `generateStubs` property in the `@AutoConfigureStubRunner` annotation or call the `withFailOnNoStubs(false)` method on the JUnit Rule or Extension. You can read more about this in xref:_project-features-stubrunner/stub-runner-fail-on-no-stubs.adoc[this section] of the documentation.
include::partial$_attributes.adoc[]
If you want Stub Runner not to fail if no stubs were found, switch the `generateStubs` property in the `@AutoConfigureStubRunner` annotation or call the `withFailOnNoStubs(false)` method on the JUnit Rule or Extension. You can read more about this in xref:../project-features-stubrunner/stub-runner-fail-on-no-stubs.adoc[this section] of the documentation.
If you want the plugins not to fail the build when no contracts were found, you can set the `failOnNoStubs` flag in Maven or call the `contractRepository { failOnNoStubs(false) }` closure in Gradle.

View File

@@ -1,12 +1,13 @@
[[how-to-work-with-transitivie]]
= How Can I Work with Transitive Dependencies?
include::partial$_attributes.adoc[]
The Spring Cloud Contract plugins add the tasks that create the stubs jar for you. One
problem that arises is that, when reusing the stubs, you can mistakenly import all of
that stub's dependencies. When building a Maven artifact, even though you have a couple
of different jars, all of them share one `pom.xml` file, as the following listing shows:
====
[source,bash,indent=0]
----
├── producer-0.0.1.BUILD-20160903.075506-1-stubs.jar
@@ -19,7 +20,6 @@ of different jars, all of them share one `pom.xml` file, as the following listin
├── ...
└── ...
----
====
There are three possibilities of working with those dependencies so as not to have any
issues with transitive dependencies:

View File

@@ -2,6 +2,8 @@
= Why use Spring Cloud Contract?
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
Spring Cloud Contract works great in a polyglot environment. This project has a lot of
really interesting features. Quite a few of these features definitely make
Spring Cloud Contract Verifier stand out on the market of Consumer Driven Contract

View File

@@ -0,0 +1,6 @@
[[spring-cloud-contract-reference-documentation]]
= Spring Cloud Contract Reference Documentation
:page-section-summary-toc: 1
Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant
Spring Cloud Contract moves TDD to the level of software architecture. It lets you perform consumer-driven and producer-driven contract testing.

View File

@@ -5,7 +5,7 @@
{project-version}
Copyright &#169; 2012-2020
Copyright &#169; 2012-2023
Copies of this document may be made for your own use and for distribution to
others, provided that you do not charge any fee for such copies and further

View File

@@ -1,44 +1,24 @@
[[maven-project]]
= Maven Project
To learn how to set up the Maven project for Spring Cloud Contract Verifier, read the
following sections:
* xref:maven-project.adoc#maven-add-plugin[Adding the Maven Plugin]
* xref:maven-project.adoc#maven-rest-assured[Maven and Rest Assured 2.0]
* xref:maven-project.adoc#maven-snapshot-versions[Using Snapshot and Milestone Versions for Maven]
* xref:maven-project.adoc#maven-add-stubs[Adding stubs]
* xref:maven-project.adoc#maven-run-plugin[Run Plugin]
* xref:maven-project.adoc#maven-configure-plugin[Configure plugin]
* xref:maven-project.adoc#maven-configuration-options[Configuration Options]
* xref:maven-project.adoc#maven-single-base[Single Base Class for All Tests]
* xref:maven-project.adoc#maven-different-base[Using Different Base Classes for Contracts]
* xref:maven-project.adoc#maven-invoking-generated-tests[Invoking Generated Tests]
* xref:maven-project.adoc#maven-pushing-stubs-to-scm[Pushing Stubs to SCM]
* xref:maven-project.adoc#maven-sts[Maven Plugin and STS]
You can also check the plugin's documentation link:../../spring-cloud-contract-maven-plugin/index.html[here].
include::partial$_attributes.adoc[]
[[maven-add-plugin]]
== Adding the Maven Plugin
To add the Spring Cloud Contract BOM, include the following section in your `pom.xml` file:
====
[source,xml,indent=0]
----
include::{standalone_samples_path}/http-server/pom.xml[tags=contract_bom,indent=0]
----
====
Next, add the `Spring Cloud Contract Verifier` Maven plugin, as follows:
====
[source,xml,indent=0]
----
include::{standalone_samples_path}/http-server/pom.xml[tags=contract_maven_plugin,indent=0]
----
====
You can read more in the
spring-cloud-contract-maven-plugin/index.html[Spring
@@ -46,7 +26,6 @@ Cloud Contract Maven Plugin Documentation].
Sometimes, regardless of the picked IDE, you can see that the `target/generated-test-source` folder is not visible on the IDE's classpath. To ensure that it is always there, you can add the following entry to your `pom.xml`
====
[source,xml,indent=0]
----
<plugin>
@@ -68,7 +47,6 @@ Sometimes, regardless of the picked IDE, you can see that the `target/generated-
</executions>
</plugin>
----
====
[[maven-rest-assured]]
== Maven and Rest Assured 2.0
@@ -76,7 +54,6 @@ Sometimes, regardless of the picked IDE, you can see that the `target/generated-
By default, Rest Assured 3.x is added to the classpath. However, you can use Rest
Assured 2.x by adding it to the plugins classpath, as follows:
====
[source,groovy,indent=0]
----
<plugin>
@@ -125,7 +102,6 @@ Assured 2.x by adding it to the plugins classpath, as follows:
</dependency>
</dependencies>
----
====
That way, the plugin automatically sees that Rest Assured 2.x is present on the classpath
and modifies the imports accordingly.
@@ -136,12 +112,10 @@ and modifies the imports accordingly.
To use Snapshot and Milestone versions, you have to add the following section to your
`pom.xml`:
====
[source,xml,indent=0]
----
include::{standalone_samples_path}/http-server/pom.xml[tags=repos,indent=0]
----
====
[[maven-add-stubs]]
== Adding stubs
@@ -153,13 +127,11 @@ that it contains at least one directory to be used as the test class name. If th
than one level of nested directories, all except the last one is used as the package name.
Consider the following structure:
====
[source,groovy,indent=0]
----
src/test/resources/contracts/myservice/shouldCreateUser.groovy
src/test/resources/contracts/myservice/shouldReturnUser.groovy
----
====
Given that structure, Spring Cloud Contract Verifier creates a test class named
`defaultBasePackage.MyService` with two methods:
@@ -188,7 +160,6 @@ mvn org.springframework.cloud:spring-cloud-contract-maven-plugin:run \
To change the default configuration, you can add a `configuration` section to the plugin
definition or the `execution` definition, as follows:
====
[source,xml,indent=0]
----
<plugin>
@@ -209,7 +180,6 @@ definition or the `execution` definition, as follows:
</configuration>
</plugin>
----
====
[[maven-configuration-options]]
== Configuration Options
@@ -295,7 +265,6 @@ When using Spring Cloud Contract Verifier in the default (`MockMvc`), you need t
specification for all generated acceptance tests. In this class, you need to point to an
endpoint, which should be verified. The following example shows how to do so:
====
[source,groovy,indent=0]
----
package org.mycompany.tests
@@ -310,11 +279,9 @@ class MvcSpec extends Specification {
}
}
----
====
If necessary, you can also setup the whole context, as the following example shows:
====
[source,java,indent=0]
----
import io.restassured.module.mockmvc.RestAssuredMockMvc;
@@ -338,13 +305,11 @@ public abstract class BaseTestClass {
}
}
----
====
If you use `EXPLICIT` mode, you can use a base class to initialize the whole tested app,
similar to what you might do in regular integration tests. The following example shows
how to do so:
====
[source,java,indent=0]
----
import io.restassured.RestAssured;
@@ -369,7 +334,6 @@ public abstract class BaseTestClass {
}
}
----
====
If you use the `JAXRSCLIENT` mode, this base class should also contain a `protected WebTarget webTarget` field. Right
now, the only way to test the JAX-RS API is to start a web server.
@@ -394,12 +358,10 @@ In other words, the system takes the last two parts of the package, if they exis
forms a class with a `Base` suffix. This rule takes precedence over `baseClassForTests`.
The following example shows how it works in the `contracts` closure:
====
[source,xml,indent=0]
----
include::{plugins_path}/spring-cloud-contract-maven-plugin/src/test/projects/basic-generated-baseclass/pom.xml[tags=convention,indent=0]
----
====
[[by-mapping]]
=== By Mapping
@@ -409,12 +371,10 @@ name of the base class for the matched contract. You have to provide a list call
`baseClassMappings` that consists of `baseClassMapping` objects that each take a
`contractPackageRegex` to `baseClassFQN` mapping. Consider the following example:
====
[source,xml,indent=0]
----
include::{plugins_path}/spring-cloud-contract-maven-plugin/src/test/projects/basic-baseclass-from-mappings/pom.xml[tags=mapping,indent=0]
----
====
Assume that you have contracts under these two locations:
@@ -435,7 +395,6 @@ goal.
For Groovy Spock code, you can use the following:
====
[source,xml,indent=0]
----
<plugin>
@@ -467,7 +426,6 @@ For Groovy Spock code, you can use the following:
</configuration>
</plugin>
----
====
To ensure that the provider side is compliant with defined contracts, you need to invoke
`mvn generateTest test`.
@@ -480,7 +438,6 @@ stubs, you might want to automate the step of pushing stubs to
the repository. To do that, you can add the `pushStubsToScm`
goal. The following example shows how to do so:
====
[source,xml,indent=0]
----
<plugin>
@@ -518,14 +475,12 @@ goal. The following example shows how to do so:
</executions>
</plugin>
----
====
Under xref:advanced.adoc#scm-stub-downloader[Using the SCM Stub Downloader], you can find all possible
configuration options that you can pass through
the `<configuration><contractsProperties>` map, a system property,
or an environment variable. For instance, you could specify a concrete branch to checkout, instead of the default one
====
[source,xml,indent=0]
----
<plugin>
@@ -566,7 +521,6 @@ or an environment variable. For instance, you could specify a concrete branch to
</executions>
</plugin>
----
====
[[maven-sts]]
@@ -578,7 +532,6 @@ image::{github-raw}/docs/src/main/asciidoc/images/sts_exception.png[STS Exceptio
When you click on the error marker, you should see something like the following:
====
[source,bash]
----
plugin:1.1.0.M1:convert:default-convert:process-test-resources) org.apache.maven.plugin.PluginExecutionException: Execution default-convert of goal org.springframework.cloud:spring-
@@ -589,11 +542,9 @@ When you click on the error marker, you should see something like the following:
org.eclipse.m2e.core.internal.builder.plexusbuildapi.EclipseIncrementalBuildContext.hasDelta(EclipseIncrementalBuildContext.java:53) at
org.sonatype.plexus.build.incremental.ThreadBuildContext.hasDelta(ThreadBuildContext.java:59) at
----
====
To fix this issue, provide the following section in your `pom.xml`:
====
[source,xml]
----
<build>
@@ -629,7 +580,6 @@ To fix this issue, provide the following section in your `pom.xml`:
</pluginManagement>
</build>
----
====
[[maven-plugin-with-spock-tests]]
== Maven Plugin with Spock Tests
@@ -641,21 +591,7 @@ in Maven, you need some additional setup in order to make the tests compile and
First of all, you must use a plugin, such as the https://github.com/groovy/GMavenPlus[GMavenPlus] plugin,
to add Groovy to your project. In GMavenPlus plugin, you need to explicitly set test sources, including both the
path where your base test classes are defined and the path were the generated contract tests are added.
The following example shows how to do so:
====
[source,xml,indent=0]
----
include::{samples_url}/producer_with_spock/pom.xml[tags=gmavenplus-setup,indent=0]
----
====
The {samples_url}/producer_with_spock/pom.xml[following example] shows how to do so.
If you uphold the Spock convention of ending the test class names with `Spec`, you also need to adjust your Maven
Surefire plugin setup, as the following example shows:
====
[source,xml,indent=0]
----
include::{samples_url}/producer_with_spock/pom.xml[tags=spock-surefire-setup,indent=0]
----
====
Surefire plugin setup, as the {samples_url}/producer_with_spock/pom.xml[following example] shows.

View File

@@ -1,6 +1,7 @@
[[contract-dsl]]
= Contract DSL
include::partial$_attributes.adoc[]
Spring Cloud Contract supports DSLs written in the following languages:
@@ -17,25 +18,25 @@ The following example shows a contract definition:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=dsl_example,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=dsl_example,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include::{verifier_core_path}/src/test/resources/yml/contract_rest.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_rest.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include::{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest.java[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest.java[tags=class,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include::{verifier_core_path}/src/test/resources/kotlin/contract_rest.kts[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_rest.kts[tags=class,indent=0]
----
====

View File

@@ -1,14 +1,16 @@
[[contract-common-top-elements]]
= Common Top-Level Elements
include::partial$_attributes.adoc[]
The following sections describe the most common top-level elements:
* xref:_project-features-contract/common-top-elements.adoc#contract-dsl-description[Description]
* xref:_project-features-contract/common-top-elements.adoc#contract-dsl-name[Name]
* xref:_project-features-contract/common-top-elements.adoc#contract-dsl-ignoring-contracts[Ignoring Contracts]
* xref:_project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[Contracts in Progress]
* xref:_project-features-contract/common-top-elements.adoc#contract-dsl-passing-values-from-files[Passing Values from Files]
* xref:_project-features-contract/common-top-elements.adoc#contract-dsl-metadata[Metadata]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-description[Description]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-name[Name]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-ignoring-contracts[Ignoring Contracts]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[Contracts in Progress]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-passing-values-from-files[Passing Values from Files]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-metadata[Metadata]
[[contract-dsl-description]]
== Description
@@ -20,25 +22,25 @@ following code shows an example:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=description,indent=0]
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=description,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_rest.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_rest.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=description,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=description,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=description,indent=0]
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=description,indent=0]
----
====
@@ -61,25 +63,25 @@ The following example shows how to add a name to a contract:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=name,indent=0]
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=name,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=name,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=name,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=name,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=name,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=name,indent=0]
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=name,indent=0]
----
====
@@ -94,25 +96,25 @@ example shows how to do so:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=ignored,indent=0]
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=ignored,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=ignored,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=ignored,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=ignored,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=ignored,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=ignored,indent=0]
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=ignored,indent=0]
----
====
@@ -130,25 +132,25 @@ example shows how to do so:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=in_progress,indent=0]
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=in_progress,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=in_progress,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=in_progress,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=in_progress,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=in_progress,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=in_progress,indent=0]
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=in_progress,indent=0]
----
====
@@ -177,25 +179,25 @@ Further assume that your contract is as follows:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/resources/classpath/readFromFile.groovy[indent=0]
include::{verifier_root_path}/src/test/resources/classpath/readFromFile.groovy[indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_from_file.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_from_file.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_from_file.java[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_from_file.java[tags=class,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/readFromFile.kts[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/readFromFile.kts[tags=class,indent=0]
----
====
@@ -205,13 +207,13 @@ Further assume that the JSON files are as follows:
[source,json,indent=0,subs="verbatim,attributes",role="primary"]
.request.json
----
include:../:{verifier_core_path}/src/test/resources/classpath/request.json[indent=0]
include::{verifier_root_path}/src/test/resources/classpath/request.json[indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.response.json
----
include:../:{verifier_core_path}/src/test/resources/classpath/response.json[indent=0]
include::{verifier_root_path}/src/test/resources/classpath/response.json[indent=0]
----
====
@@ -228,25 +230,25 @@ The following example shows how to pass the contents of binary files:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/resources/body_builder/worksWithPdf.groovy[indent=0]
include::{verifier_root_path}/src/test/resources/body_builder/worksWithPdf.groovy[indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_pdf.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_pdf.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_from_pdf.java[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_from_pdf.java[tags=class,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{contract_kotlin_spec_path}/src/test/resources/contracts/shouldWorkWithBinaryPayload.kts[tags=class,indent=0]
include::{contract_kotlin_spec_path}/src/test/resources/contracts/shouldWorkWithBinaryPayload.kts[tags=class,indent=0]
----
====
@@ -265,36 +267,36 @@ delays or integrate with third party WireMock extensions.
[source,groovy,indent=0,role="primary"]
.groovy
----
include:../:{standalone_samples_path}/http-server/src/test/resources/contracts/fraud/shouldReturnFraudStats.groovy[tags=metadata,indent=0]
include::{standalone_samples_path}/http-server/src/test/resources/contracts/fraud/shouldReturnFraudStats.groovy[tags=metadata,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.yml
----
include:../:{standalone_samples_path}/http-server/src/test/resources/contracts/yml/fraud/shouldReturnFraudStats.yml[tags=metadata,indent=0]
include::{standalone_samples_path}/http-server/src/test/resources/contracts/yml/fraud/shouldReturnFraudStats.yml[tags=metadata,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=metadata,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=metadata,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.kotlin
----
include:../:{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=metadata,indent=0]
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=metadata,indent=0]
----
====
In the following sections you can find examples of the supported metadata entries.
////
include:../:{project-root}/docs/target/metadata.adoc[indent=0]
include::{project-root}/docs/target/metadata.adoc[indent=0]
////
[[features-http]]
= Contracts for HTTP
== Contracts for HTTP
Spring Cloud Contract lets you verify applications that use REST or HTTP as a
means of communication. Spring Cloud Contract verifies that, for a request that matches the

View File

@@ -1,6 +1,8 @@
[[contract-dsl-async]]
= Asynchronous Support
include::partial$_attributes.adoc[]
If you use asynchronous communication on the server side (your controllers are
returning `Callable`, `DeferredResult`, and so on), then, inside your contract, you must
provide an `async()` method in the `response` section. The following code shows an example:

View File

@@ -1,6 +1,8 @@
[[contract-dsl-dynamic-properties]]
= Dynamic properties
include::partial$_attributes.adoc[]
The contract can contain some dynamic properties: timestamps, IDs, and so on. You do not
want to force the consumers to stub their clocks to always return the same value of time
so that it gets matched by the stub.
@@ -20,7 +22,7 @@ IMPORTANT: Entries inside the `matchers` must reference existing elements of the
== Dynamic Properties inside the Body
IMPORTANT: This section is valid only for the Coded DSL (Groovy, Java, and so on). See the
xref:_project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
xref:project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
You can set the properties inside the body either with the `value` method or, if you use
the Groovy map notation, with `$()`. The following example shows how to set dynamic
@@ -53,7 +55,7 @@ method. Subsequent sections take a closer look at what you can do with those val
== Regular Expressions
IMPORTANT: This section is valid only for the Groovy DSL. See the
xref:_project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
xref:project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
You can use regular expressions to write your requests in the contract DSL. Doing so is
particularly useful when you want to indicate that a given response should be provided
@@ -63,7 +65,7 @@ need to use patterns and not exact values both for your tests and your server-si
Make sure that regex matches a whole region of a sequence, as, internally,
https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html#matches[`Pattern.matches()`]
is called. For instance, `abc` does not match `aabc`, but `.abc` does.
There are several additional xref:_project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-regex-limitations[known limitations] as well.
There are several additional xref:project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-regex-limitations[known limitations] as well.
The following example shows how to use regular expressions to write a request:
@@ -71,19 +73,19 @@ The following example shows how to use regular expressions to write a request:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=regex,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=regex,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=regex,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=regex,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=regex,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=regex,indent=0]
----
====
@@ -93,7 +95,7 @@ the provided regular expression. The following code shows an example for Groovy:
[source,groovy,indent=0]
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=dsl_one_side_data_generation_example,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=dsl_one_side_data_generation_example,indent=0]
----
In the preceding example, the opposite side of the communication has the respective data
@@ -104,14 +106,14 @@ use in your contracts, as the following example shows:
[source,java,indent=0]
----
include:../:{contract_spec_path}/src/main/java/org/springframework/cloud/contract/spec/internal/RegexPatterns.java[tags=regexps,indent=0]
include::{contract_spec_path}/src/main/java/org/springframework/cloud/contract/spec/internal/RegexPatterns.java[tags=regexps,indent=0]
----
In your contract, you can use it as follows (example for the Groovy DSL):
[source,groovy,indent=0]
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=contract_with_regex,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=contract_with_regex,indent=0]
----
To make matters even simpler, you can use a set of predefined objects that automatically
@@ -120,7 +122,7 @@ All of those methods start with the `any` prefix, as follows:
[source,java,indent=0]
----
include:../:{contract_spec_path}/src/main/java/org/springframework/cloud/contract/spec/internal/RegexCreatingProperty.java[tags=regex_creating_props,indent=0]
include::{contract_spec_path}/src/main/java/org/springframework/cloud/contract/spec/internal/RegexCreatingProperty.java[tags=regex_creating_props,indent=0]
----
The following example shows how you can reference those methods:
@@ -129,13 +131,13 @@ The following example shows how you can reference those methods:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=regex_creating_props,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=regex_creating_props,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=regex_creating_props,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=regex_creating_props,indent=0]
----
====
@@ -154,7 +156,7 @@ See https://github.com/spring-cloud/spring-cloud-contract/issues/900[Issue 900].
== Passing Optional Parameters
IMPORTANT: This section is valid only for Groovy DSL. See the
xref:_project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
xref:project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
You can provide optional parameters in your contract. However, you can provide
optional parameters only for the following:
@@ -168,19 +170,19 @@ The following example shows how to provide optional parameters:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=optionals,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=optionals,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=optionals,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=optionals,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=optionals,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=optionals,indent=0]
----
====
@@ -193,7 +195,7 @@ If you use Spock, the following test would be generated from the previous exampl
[source,groovy,indent=0]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=optionals_test,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=optionals_test,indent=0]
----
====
@@ -201,14 +203,14 @@ The following stub would also be generated:
[source,groovy,indent=0]
----
include:../:{plugins_path}/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy[tags=wiremock,indent=0]
include::{plugins_path}/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy[tags=wiremock,indent=0]
----
[[contract-dsl-custom-methods]]
== Calling Custom Methods on the Server Side
IMPORTANT: This section is valid only for the Groovy DSL. See the
xref:_project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
xref:project-features-contract/dsl-dynamic-properties.adoc#contract-dsl-matchers[Dynamic Properties in the Matchers Sections] section for YAML examples of a similar feature.
You can define a method call that runs on the server side during the test. Such a
method can be added to the class defined as `baseClassForTests` in the configuration. The
@@ -218,19 +220,19 @@ following code shows an example of the contract portion of the test case:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=method,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=method,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=method,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=method,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=method,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=method,indent=0]
----
====
@@ -238,7 +240,7 @@ The following code shows the base class portion of the test case:
[source,groovy,indent=0]
----
include:../:{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0]
include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0]
----
IMPORTANT: You cannot use both a `String` and `execute` to perform concatenation. For
@@ -265,7 +267,7 @@ The following example shows how to read an object from JSON:
[source,groovy,indent=0]
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy[tags=body_execute,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy[tags=body_execute,indent=0]
----
The preceding example results in calling the `hashCode()` method in the request body.
@@ -329,13 +331,13 @@ Consider the following contract:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=template_contract,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=template_contract,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_reference_request.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_reference_request.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
@@ -399,7 +401,7 @@ contract {
response {
status = OK
body(mapOf(
"text" to "Don't worry ${fromRequest().body("$.name")} thanks for your interested in drinking beer",
"text" to "Don't worry $\{fromRequest().body("$.name")} thanks for your interested in drinking beer",
"quantity" to v(c(5), p(anyNumber))
))
headers {
@@ -645,13 +647,13 @@ Consider the following example:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy[tags=matchers,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy[tags=matchers,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_matchers.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_matchers.yml[indent=0]
----
====
@@ -731,7 +733,7 @@ The resulting WireMock stub is in the following example:
[source,json,indent=0]
----
include:../:{plugins_path}/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy[tags=matchers,indent=0]
include::{plugins_path}/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy[tags=matchers,indent=0]
----
IMPORTANT: If you use a `matcher`, the part of the request and response that the

View File

@@ -1,6 +1,8 @@
[[contract-dsl-http-top-level-elements]]
= HTTP Top-Level Elements
include::partial$_attributes.adoc[]
You can call the following methods in the top-level closure of a contract definition:
* `request`: Mandatory
@@ -13,29 +15,29 @@ The following example shows how to define an HTTP request contract:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=http_dsl,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=http_dsl,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=priority,indent=0]
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=priority,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
...
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=response,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=response,indent=0]
...
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=http_dsl,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=http_dsl,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=http_dsl,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=http_dsl,indent=0]
----
====

View File

@@ -1,6 +1,8 @@
[[contract-dsl-multiple]]
= Multiple Contracts in One File
include::partial$_attributes.adoc[]
You can define multiple contracts in one file. Such a contract might resemble the
following example:
@@ -8,13 +10,13 @@ following example:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{plugins_path}/spring-cloud-contract-maven-plugin/src/test/projects/multiple-contracts/src/test/resources/contracts/com/hello/v1/WithList.groovy[lines=18..-1,indent=0]
include::{plugins_path}/spring-cloud-contract-maven-plugin/src/test/projects/multiple-contracts/src/test/resources/contracts/com/hello/v1/WithList.groovy[lines=18..-1,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/multiple_contracts.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/multiple_contracts.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]

View File

@@ -1,6 +1,8 @@
[[contract-dsl-request]]
= HTTP Request
include::partial$_attributes.adoc[]
The HTTP protocol requires only the method and the URL to be specified in a request. The
same information is mandatory in request definition of the contract.
@@ -10,25 +12,25 @@ The following example shows a contract for a request:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=request,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=request,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request_obligatory,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=request_obligatory,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=request,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=request,indent=0]
----
====
@@ -41,25 +43,25 @@ The following example uses `url`:
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=url,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=url,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_rest_with_path.yml[tags=url_path,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_rest_with_path.yml[tags=url_path,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=url,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=url,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=url,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=url,indent=0]
----
====
@@ -69,27 +71,27 @@ include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_example
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=urlpath,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=urlpath,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
...
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=query_params,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=query_params,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=urlpath,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=urlpath,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=urlpath,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=urlpath,indent=0]
----
====
@@ -99,27 +101,27 @@ include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_example
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=headers,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=headers,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
...
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=headers,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=headers,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=headers,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=headers,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=headers,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=headers,indent=0]
----
====
@@ -129,27 +131,27 @@ include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_example
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=cookies,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=cookies,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
...
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=cookies,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=cookies,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=cookies,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=cookies,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=cookies,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=cookies,indent=0]
----
====
@@ -159,27 +161,27 @@ include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_example
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=body,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=body,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=request,indent=0]
...
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=body,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=body,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=body,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=body,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=body,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=body,indent=0]
----
====
@@ -190,25 +192,25 @@ include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_example
[source,groovy,indent=0,role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=multipartdsl,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy[tags=multipartdsl,indent=0]
----
[source,yaml,indent=0,role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_multipart.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_multipart.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_multipart.java[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_multipart.java[tags=class,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/multipart.kts[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/multipart.kts[tags=class,indent=0]
----
====
@@ -265,7 +267,7 @@ From the contract in the preceding example, the generated test and stub look as
[source,json,indent=0,subs="verbatim,attributes",role="secondary"]
.Stub
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockGroovyDslSpec.groovy[tags=multipartwiremock,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockGroovyDslSpec.groovy[tags=multipartwiremock,indent=0]
----
====

View File

@@ -1,6 +1,8 @@
[[contract-dsl-response]]
= HTTP Response
include::partial$_attributes.adoc[]
The response must contain an HTTP status code and may contain other information. The
following code shows an example:
@@ -8,32 +10,32 @@ following code shows an example:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=response,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=response,indent=0]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=response,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=response,indent=0]
...
include:../:{verifier_core_path}/src/test/resources/yml/contract.yml[tags=response_obligatory,indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=response_obligatory,indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=response,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_docs_examples.java[tags=response,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=response,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_docs_examples.kts[tags=response,indent=0]
----
====
Besides status, the response may contain headers, cookies, and a body, which are
specified the same way as in the request (see xref:_project-features-contract/dsl-request.adoc[HTTP Request]).
specified the same way as in the request (see xref:project-features-contract/dsl-request.adoc[HTTP Request]).
TIP: In the Groovy DSL, you can reference the `org.springframework.cloud.contract.spec.internal.HttpStatus`
methods to provide a meaningful status instead of a digit. For example, you can call

View File

@@ -1,6 +1,8 @@
[[contract-dsl-xml]]
= XML Support for HTTP
include::partial$_attributes.adoc[]
For HTTP contracts, we also support using XML in the request and response body.
The XML body has to be passed within the `body` element
as a `String` or `GString`. Also, body matchers can be provided for
@@ -14,25 +16,25 @@ The following example shows a Groovy DSL contract with XML in the response body:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/XmlMethodBodyBuilderSpec.groovy[tags=xmlgroovy]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/XmlMethodBodyBuilderSpec.groovy[tags=xmlgroovy]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include:../:{verifier_core_path}/src/test/resources/yml/contract_rest_xml.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_rest_xml.yml[indent=0]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Java
----
include:../:{verifier_core_path}/src/test/resources/contractsToCompile/contract_xml.java[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_xml.java[tags=class,indent=0]
----
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
.Kotlin
----
include:../:{verifier_core_path}/src/test/resources/kotlin/contract_xml.kts[tags=class,indent=0]
include::{verifier_root_path}/src/test/resources/kotlin/contract_xml.kts[tags=class,indent=0]
----
====
@@ -60,9 +62,9 @@ public void validate_xmlMatches() throws Exception {
// and:
assertThat(valueFromXPath(parsedXml, "/test/list/elem/text()")).isEqualTo("abc");
assertThat(valueFromXPath(parsedXml,"/test/list/elem[2]/text()")).isEqualTo("def");
assertThat(valueFromXPath(parsedXml, "/test/duck/text()")).matches("[0-9]{3}");
assertThat(valueFromXPath(parsedXml, "/test/duck/text()")).matches("[0-9]\{3}");
assertThat(nodeFromXPath(parsedXml, "/test/duck/xxx")).isNull();
assertThat(valueFromXPath(parsedXml, "/test/alpha/text()")).matches("[\\p{L}]*");
assertThat(valueFromXPath(parsedXml, "/test/alpha/text()")).matches("[\\p\{L}]*");
assertThat(valueFromXPath(parsedXml, "/test/*/complex/text()")).isEqualTo("foo");
assertThat(valueFromXPath(parsedXml, "/test/duck/@type")).isEqualTo("xtype");
}

View File

@@ -2,6 +2,8 @@
= Contract DSL in Groovy
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
If you are not familiar with Groovy, do not worry. You can use Java syntax in the
Groovy DSL files as well.

View File

@@ -1,6 +1,8 @@
[[contract-java]]
= Contract DSL in Java
include::partial$_attributes.adoc[]
To write a contract definition in Java, you need to create a class that implements either the `Supplier<Contract>` interface (for a single contract) or `Supplier<Collection<Contract>>` (for multiple contracts).
You can also write the contract definitions under `src/test/java` (for example, `src/test/java/contracts`) so that you do not have to modify the classpath of your project. In this case, you have to provide a new location of contract definitions to your Spring Cloud Contract plugin.

View File

@@ -1,6 +1,8 @@
[[contract-kotlin]]
= Contract DSL in Kotlin
include::partial$_attributes.adoc[]
To get started with writing contracts in Kotlin, you need to start with a (newly created) Kotlin Script file (`.kts`).
As with the Java DSL, you can put your contracts in any directory of your choice.
By default, the Maven plugin will look at the `src/test/resources/contracts` directory and Gradle plugin will
@@ -52,7 +54,7 @@ buildscript {
// ...
}
dependencies {
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${scContractVersion}"
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:$\{scContractVersion}"
}
}

View File

@@ -2,6 +2,8 @@
= Limitations
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
WARNING: The support for verifying the size of JSON arrays is experimental. If you want
to turn it on, set the value of the following system property to `true`:
`spring.cloud.contract.verifier.assert.size`. By default, this feature is set to `false`.

View File

@@ -1,6 +1,8 @@
[[contract-stateful-contracts]]
= Stateful Contracts
include::partial$_attributes.adoc[]
Stateful contracts (also known as scenarios) are contract definitions that should be read
in order. This might be useful in the following situations:

View File

@@ -0,0 +1,6 @@
[[contract-yml]]
= Contract DSL in YAML
:page-section-summary-toc: 1
To see a schema of a YAML contract, visit the xref:../yml-schema.adoc[YML Schema] page.

View File

@@ -1,6 +1,8 @@
[[features-context-paths]]
= Working with Context Paths
include::partial$_attributes.adoc[]
Spring Cloud Contract supports context paths.
[IMPORTANT]
@@ -43,14 +45,14 @@ Consider the following contract:
[source,groovy,indent=0]
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy[tags=context_path_contract,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy[tags=context_path_contract,indent=0]
----
The following example shows how to set up a base class and RestAssured:
[source,groovy,indent=0]
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy[tags=context_path_baseclass,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy[tags=context_path_baseclass,indent=0]
----
If you do it this way:

View File

@@ -1,6 +1,8 @@
[[features-custom-mode]]
= Custom Mode
include::partial$_attributes.adoc[]
IMPORTANT: This mode is experimental and can change in the future.
The Spring Cloud Contract lets you provide your own, custom, implementation of the

View File

@@ -1,6 +1,8 @@
[[feature-webflux-explicit]]
= WebFlux with Explicit Mode
include::partial$_attributes.adoc[]
You can also use WebFlux with the explicit mode in your generated tests
to work with WebFlux. The following example shows how to configure using explicit mode:
@@ -28,19 +30,5 @@ contracts {
----
====
The following example shows how to set up a base class and RestAssured for Web Flux:
====
[source,groovy,indent=0]
----
include:../:{samples_url}/producer_webflux/src/test/java/com/example/BeerRestBase.java[tags=annotations,indent=0]
// your tests go here
// in this config class you define all controllers and mocked services
include:../:{samples_url}/producer_webflux/src/test/java/com/example/BeerRestBase.java[tags=config,indent=0]
}
----
====
The following {samples_url}/producer_webflux/[example] shows how to set up a base class and RestAssured for Web Flux.

View File

@@ -1,6 +1,8 @@
[[feature-webflux]]
= WebFlux with WebTestClient
include::partial$_attributes.adoc[]
You can work with WebFlux by using WebTestClient. The following listing shows how to
configure WebTestClient as the test mode:

View File

@@ -1,6 +1,8 @@
[[features-graphql]]
= GraphQL
include::partial$_attributes.adoc[]
Since https://graphql.org/[GraphQL] is essentially HTTP you can write a contract for it by creating a standard HTTP contract with an additional `metadata` entry with key `verifier` and a mapping `tool=graphql`.
====

View File

@@ -1,6 +1,8 @@
[[features-grpc]]
= GRPC
include::partial$_attributes.adoc[]
https://grpc.io/[GRPC] is an RPC framework built on top of HTTP/2 for which Spring Cloud Contract has basic support.
IMPORTANT: Spring Cloud Contract has an experimental support for basic use cases of GRPC. Unfortunately, due to GRPC's tweaking of the HTTP/2 Header frames, it's impossible to assert the `grpc-status` header.

View File

@@ -1,6 +1,8 @@
[[features-jax-rs]]
= JAX-RS
include::partial$_attributes.adoc[]
The Spring Cloud Contract supports the JAX-RS 2 Client API. The base class needs
to define `protected WebTarget webTarget` and server initialization. The only option for
testing JAX-RS API is to start a web server. Also, a request with a body needs to have a
@@ -20,7 +22,7 @@ The following example shows a generated test API:
====
[source,groovy,indent=0]
----
include:../:{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy[tags=jaxrs,indent=0]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy[tags=jaxrs,indent=0]
----
====

View File

@@ -1,6 +1,8 @@
[[features-rest-docs]]
= Working with REST Docs
include::partial$_attributes.adoc[]
You can use https://projects.spring.io/spring-restdocs[Spring REST Docs] to generate
documentation (for example, in Asciidoc format) for an HTTP API with Spring MockMvc,
WebTestClient, or RestAssured. At the same time that you generate documentation for your API, you can also
@@ -177,7 +179,7 @@ methods to create request matchers, but you cannot use both approaches.
On the consumer side, you can make the `resource.json` generated earlier in this section
available on the classpath (by
xref:_project-features-stubrunner/stub-runner-publishing-stubs-as-jars.adoc[Publishing Stubs as JARs], for example). After that, you can create a stub that uses WireMock in a
xref:../project-features-stubrunner/stub-runner-publishing-stubs-as-jars.adoc[Publishing Stubs as JARs], for example). After that, you can create a stub that uses WireMock in a
number of different ways, including by using
`@AutoConfigureWireMock(stubs="classpath:resource.json")`, as described earlier in this
document.
@@ -203,7 +205,7 @@ Consider the following test:
====
[source,java]
----
include:../:{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippetTests.java[tags=contract_snippet]
include::{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wiremock/restdocs/ContractDslSnippetTests.java[tags=contract_snippet]
----
====
@@ -254,7 +256,7 @@ contract. The location of this file would be `index/dsl-contract.adoc`.
The method `SpringCloudContractRestDocs.dslContract()` takes an optional Map parameter that allows you to specify additional attributes in the template.
One of these attributes is the xref:_project-features-contract/dsl-http-top-level-elements.adoc[priority] field that you may specify as follows:
One of these attributes is the xref:project-features-contract/dsl-http-top-level-elements.adoc[priority] field that you may specify as follows:
[source,java,indent=0]
----
@@ -297,9 +299,9 @@ should be changed to:
Templates are resolved by looking for resources on the classpath. The following locations are checked in order:
* `org/springframework/restdocs/templates/${templateFormatId}/${name}.snippet`
* `org/springframework/restdocs/templates/${name}.snippet`
* `org/springframework/restdocs/templates/${templateFormatId}/default-${name}.snippet`
* `org/springframework/restdocs/templates/$\{templateFormatId}/$\{name}.snippet`
* `org/springframework/restdocs/templates/$\{name}.snippet`
* `org/springframework/restdocs/templates/$\{templateFormatId}/default-$\{name}.snippet`
Therefore in the example above you should place a file named custom-dsl-template.snippet in `src/test/resources/org/springframework/restdocs/templates/custom-dsl-template.snippet`

View File

@@ -0,0 +1,4 @@
[[flows]]
= Spring Cloud Contract Integrations
In these pages you will be able to learn about different Spring Cloud Contract integrations.

View File

@@ -1,6 +1,7 @@
[[features-messaging]]
= Messaging
include::partial$_attributes.adoc[]
Spring Cloud Contract lets you verify applications that use messaging as a
means of communication. All of the integrations shown in this document work with Spring,
@@ -12,9 +13,9 @@ but you can also create one of your own and use that.
The DSL for messaging looks a little bit different than the one that focuses on HTTP. The
following sections explain the differences:
* xref:_project-features-messaging.adoc#contract-dsl-output-triggered-method[Output Triggered by a Method]
* xref:_project-features-messaging.adoc#contract-dsl-consumer-producer[Consumer/Producer]
* xref:_project-features-messaging.adoc#contract-dsl-messaging-common[Common]
* xref:project-features-messaging.adoc#contract-dsl-output-triggered-method[Output Triggered by a Method]
* xref:project-features-messaging.adoc#contract-dsl-consumer-producer[Consumer/Producer]
* xref:project-features-messaging.adoc#contract-dsl-messaging-common[Common]
[[contract-dsl-output-triggered-method]]
=== Output Triggered by a Method
@@ -32,7 +33,7 @@ include::{tests_path}/samples-messaging-integration/src/test/groovy/com/example/
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
----
include::{verifier_core_path}/src/test/resources/yml/contract_message_method.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_message_method.yml[indent=0]
----
====
@@ -152,14 +153,14 @@ Consider the following contract:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl]
----
[source,yml,indent=0,subs="verbatim,attributes",role="secondary"]
.YAML
[source,yml,indent=0]
----
include::{verifier_core_path}/src/test/resources/yml/contract_message_scenario1.yml[indent=0]
include::{verifier_root_path}/src/test/resources/yml/contract_message_scenario1.yml[indent=0]
----
=====
@@ -169,13 +170,13 @@ For the preceding example, the following test would be created:
[source,java,indent=0,subs="verbatim,attributes",role="primary"]
.JUnit
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_junit_test]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_junit_test]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Spock
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_test]
include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_test]
----
====
@@ -208,10 +209,10 @@ or the other in your tests.
`StubTrigger` gives you the following options to trigger a message:
* xref:_project-features-messaging.adoc#features-messaging-trigger-label[Trigger by Label]
* xref:_project-features-messaging.adoc#features-messaging-trigger-group-artifact-ids[Trigger by Group and Artifact IDs]
* xref:_project-features-messaging.adoc#features-messaging-trigger-artifact-ids[Trigger by Artifact IDs]
* xref:_project-features-messaging.adoc#features-messaging-trigger-all-messages[Trigger All Messages]
* xref:project-features-messaging.adoc#features-messaging-trigger-label[Trigger by Label]
* xref:project-features-messaging.adoc#features-messaging-trigger-group-artifact-ids[Trigger by Group and Artifact IDs]
* xref:project-features-messaging.adoc#features-messaging-trigger-artifact-ids[Trigger by Artifact IDs]
* xref:project-features-messaging.adoc#features-messaging-trigger-all-messages[Trigger All Messages]
[[features-messaging-trigger-label]]
=== Trigger by Label

View File

@@ -1,6 +1,8 @@
[[features-stub-runner-boot]]
= Using the Stub Runner Boot Application
include::partial$_attributes.adoc[]
Spring Cloud Contract Stub Runner Boot is a Spring Boot application that exposes REST endpoints to
trigger the messaging labels and to access WireMock servers.
@@ -12,7 +14,7 @@ stubs even if they don't actually require it. Since this is a testing utility -
to be used in production environments.
IMPORTANT: It is expected that **only a trusted client** has access to the Stub Runner Boot server. You should not
run this application as a Fat Jar or a link:docker-project.html#docker-stubrunner[Docker Image] in untrusted locations.
run this application as a Fat Jar or a xref:../docker-project.adoc[Docker Image] in untrusted locations.
[[features-stub-runner-boot-server]]
== Stub Runner Server
@@ -28,7 +30,7 @@ compile "org.springframework.cloud:spring-cloud-starter-stub-runner"
Then annotate a class with `@EnableStubRunnerServer`, build a fat jar, and it is ready to work.
For the properties, see the xref:_project-features-stubrunner/stub-runner-junit.adoc#features-stub-runner-rule-spring[Stub Runner Spring] section.
For the properties, see the xref:../project-features-stubrunner/stub-runner-junit.adoc#features-stub-runner-rule-spring[Stub Runner Spring] section.
[[features-stub-runner-boot-how-fat-jar]]
== Stub Runner Server Fat Jar
@@ -74,8 +76,8 @@ the Stub Runner server. It is available at port `8750`.
Stub Runner Boot offers two endpoints:
* xref:_project-features-stubrunner/stub-runner-boot.adoc#features-stub-runner-boot-endpoints-http[HTTP]
* xref:_project-features-stubrunner/stub-runner-boot.adoc#features-stub-runner-boot-endpoints-messaging[Messaging]
* xref:../project-features-stubrunner/stub-runner-boot.adoc#features-stub-runner-boot-endpoints-http[HTTP]
* xref:../project-features-stubrunner/stub-runner-boot.adoc#features-stub-runner-boot-endpoints-messaging[Messaging]
[[features-stub-runner-boot-endpoints-http]]
=== HTTP
@@ -83,7 +85,7 @@ Stub Runner Boot offers two endpoints:
For HTTP, Stub Runner Boot makes the following endpoints available:
- GET `/stubs`: Returns a list of all running stubs in `ivy:integer` notation
- GET `/stubs/{ivy}`: Returns a port for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only)
- GET `/stubs/\{ivy}`: Returns a port for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only)
[[features-stub-runner-boot-endpoints-messaging]]
=== Messaging
@@ -91,8 +93,8 @@ For HTTP, Stub Runner Boot makes the following endpoints available:
For Messaging, Stub Runner Boot makes the following endpoints available:
- GET `/triggers`: Returns a list of all running labels in `ivy : [ label1, label2 ...]` notation
- POST `/triggers/{label}`: Runs a trigger with `label`
- POST `/triggers/{ivy}/{label}`: Runs a trigger with a `label` for the given `ivy` notation
- POST `/triggers/\{label}`: Runs a trigger with `label`
- POST `/triggers/\{ivy}/\{label}`: Runs a trigger with a `label` for the given `ivy` notation
(when calling the endpoint, `ivy` can also be `artifactId` only)
[[features-stub-runner-boot-endpoints-example]]
@@ -102,7 +104,7 @@ The following example shows typical usage of Stub Runner Boot:
[source,groovy,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/server/StubRunnerBootSpec.groovy[tags=boot_usage]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/server/StubRunnerBootSpec.groovy[tags=boot_usage]
----
[[features-stub-runner-boot-service-discovery]]
@@ -121,8 +123,8 @@ use a service discovery tool. Stub Runner Boot lets you solve this issue by star
required stubs and registering them in a service discovery tool.
Now assume that we want to start this application so that the stubs get automatically registered.
We can do so by running the application with `java -jar ${SYSTEM_PROPS} stub-runner-boot-eureka-example.jar`, where
`${SYSTEM_PROPS}`.
We can do so by running the application with `java -jar $\{SYSTEM_PROPS} stub-runner-boot-eureka-example.jar`, where
`$\{SYSTEM_PROPS}`.
That way, your deployed application can send requests to started WireMock servers through service
discovery. Most likely, points 1 through 3 could be set by default in `application.yml`, because they are not

View File

@@ -1,6 +1,8 @@
[[features-stub-runner-cloud]]
= Stub Runner Spring Cloud
include::partial$_attributes.adoc[]
Stub Runner can integrate with Spring Cloud.
For real life examples, see:

View File

@@ -1,10 +1,12 @@
[[features-stub-runner-common]]
= Common Properties
include::partial$_attributes.adoc[]
This section briefly describes common properties, including:
* xref:_project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-common-properties-junit-spring[Common Properties for JUnit and Spring]
* xref:_project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-stub-runner-stub-ids[Stub Runner Stubs IDs]
* xref:../project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-common-properties-junit-spring[Common Properties for JUnit and Spring]
* xref:../project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-stub-runner-stub-ids[Stub Runner Stubs IDs]
[[features-stub-runner-common-properties-junit-spring]]
== Common Properties for JUnit and Spring

View File

@@ -1,6 +1,8 @@
[[features-stub-runner-core]]
= Stub Runner Core
include::partial$_attributes.adoc[]
The stub runner core runs stubs for service collaborators. Treating stubs as contracts of
services lets you use stub-runner as an implementation of
https://martinfowler.com/articles/consumerDrivenContracts.html[Consumer-driven Contracts].
@@ -183,7 +185,7 @@ example shows how to do so:
====
[source,groovy,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=wireMockHttpServerStubConfigurer]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=wireMockHttpServerStubConfigurer]
----
====
@@ -192,7 +194,7 @@ You can then reuse it with the `@AutoConfigureStubRunner` annotation, as follows
====
[source,groovy,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=annotation]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=annotation]
----
====
@@ -203,9 +205,9 @@ Whenever an HTTPS port is found, it takes precedence over the HTTP port.
This section describes how to run stubs. It contains the following topics:
* xref:_project-features-stubrunner/stub-runner-core.adoc#features-stub-runner-http-stubs[HTTP Stubs]
* xref:_project-features-stubrunner/stub-runner-core.adoc#features-stub-runner-viewing[Viewing Registered Mappings]
* xref:_project-features-stubrunner/stub-runner-core.adoc#features-stub-runner-messaging[Messaging Stubs]
* xref:../project-features-stubrunner/stub-runner-core.adoc#features-stub-runner-http-stubs[HTTP Stubs]
* xref:../project-features-stubrunner/stub-runner-core.adoc#features-stub-runner-viewing[Viewing Registered Mappings]
* xref:../project-features-stubrunner/stub-runner-core.adoc#features-stub-runner-messaging[Messaging Stubs]
[[features-stub-runner-http-stubs]]
=== HTTP Stubs

View File

@@ -1,6 +1,8 @@
[[features-stub-runner-fail-on-no-stubs]]
= Fail On No Stubs
include::partial$_attributes.adoc[]
By default, Stub Runner will fail if no stubs are found. In order to change that behavior, set the `failOnNoStubs` property to `false` in the annotation or call the `withFailOnNoStubs(false)` method on a JUnit Rule or Extension. The following example shows how to do so:
====

View File

@@ -1,9 +1,11 @@
[[features-stub-runner-generate-stubs-at-runtime]]
= Generating Stubs at Runtime
include::partial$_attributes.adoc[]
As a consumer, you might not want to wait for the producer to finish its implementation and then publish their stubs. A solution to this problem can be generation of stubs at runtime.
As a producer, when a contract is defined, you are required to make the generated tests pass in order for the stubs to be published. There are cases where you would like to unblock the consumers so that they can fetch the stubs before your tests actually pass. In this case, you should set such contracts as in-progress. You can read more about this under the xref:_project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[Contracts in Progress] section. That way, your tests are not generated, but the stubs are generated.
As a producer, when a contract is defined, you are required to make the generated tests pass in order for the stubs to be published. There are cases where you would like to unblock the consumers so that they can fetch the stubs before your tests actually pass. In this case, you should set such contracts as in-progress. You can read more about this under the xref:project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[Contracts in Progress] section. That way, your tests are not generated, but the stubs are generated.
As a consumer, you can toggle a switch to generate stubs at runtime. Stub Runner ignores all the existing stub mappings and generates new ones for all the contract definitions. Another option is to pass the `stubrunner.generate-stubs` system property. The following example shows such a setup:

View File

@@ -1,13 +1,15 @@
[[features-stub-runner-junit]]
= Stub Runner JUnit Rule and Stub Runner JUnit5 Extension
include::partial$_attributes.adoc[]
Stub Runner comes with a JUnit rule that lets you can download and run stubs for a given
group and artifact ID, as the following example shows:
====
[source,java,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleJUnitTest.java[tags=classrule]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleJUnitTest.java[tags=classrule]
----
====
@@ -33,7 +35,7 @@ you find the started stubs, as the following example shows:
====
[source,groovy,indent=0]
----
include:../:{stubrunner_core_path}/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java[lines=16..-1]
include::{stubrunner_core_path}/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java[lines=16..-1]
----
====
@@ -43,23 +45,23 @@ The following examples provide more detail about using Stub Runner:
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Spock
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleSpec.groovy[tags=classrule]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleSpec.groovy[tags=classrule]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Junit 4
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleJUnitTest.java[tags=test]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleJUnitTest.java[tags=test]
----
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.Junit 5
----
include:../:{stubrunner_core_path}/src/test/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerJUnit5ExtensionTests.java[tags=extension]
include::{stubrunner_core_path}/src/test/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerJUnit5ExtensionTests.java[tags=extension]
----
====
See the xref:_project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-common-properties-junit-spring[Common Properties for JUnit and Spring] for more information on
See the xref:../project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-common-properties-junit-spring[Common Properties for JUnit and Spring] for more information on
how to apply global configuration of Stub Runner.
IMPORTANT: To use the JUnit rule or JUnit 5 extension together with messaging, you have to provide an implementation of the
@@ -89,7 +91,7 @@ and then pass the port for the last downloaded stub. The following example shows
====
[source,java,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port]
----
====
@@ -98,7 +100,7 @@ For the preceding example, the following test is valid:
====
[source,java,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=test_with_port]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=test_with_port]
----
====
@@ -116,7 +118,7 @@ its methods, as follows:
====
[source,groovy,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test]
----
====
@@ -125,7 +127,7 @@ Doing so depends on the following configuration file:
====
[source,yml,indent=0]
----
include:../:{stubrunner_core_path}/src/test/resources/application-test.yml[tags=test]
include::{stubrunner_core_path}/src/test/resources/application-test.yml[tags=test]
----
====
@@ -135,7 +137,7 @@ The following example achieves the same result by setting values on the annotati
====
[source,groovy,indent=0]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/consul/StubRunnerSpringCloudConsulAutoConfigurationSpec.groovy[tags=autoconfigure]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/consul/StubRunnerSpringCloudConsulAutoConfigurationSpec.groovy[tags=autoconfigure]
----
====

View File

@@ -0,0 +1,12 @@
[[features-stub-runner-publishing-stubs-as-jars]]
= Publishing Stubs as JARs
include::partial$_attributes.adoc[]
The easiest approach to publishing stubs as jars is to centralize the way stubs are kept.
For example, you can keep them as jars in a Maven repository.
TIP: For both Maven and Gradle, the setup comes ready to work. However, you can customize
it if you want to.
Check these URL for {samples_url}/producer_with_restdocs/pom.xml[Maven] and {samples_url}/producer_with_restdocs/pom.xml[Gradle] samples.

View File

@@ -2,6 +2,8 @@
= Snapshot Versions
:page-section-summary-toc: 1
include::partial$_attributes.adoc[]
You can add the additional snapshot repository to your build file to use snapshot
versions, which are automatically uploaded after every successful build, as follows:
@@ -9,13 +11,13 @@ versions, which are automatically uploaded after every successful build, as foll
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
include:../:{standalone_samples_path}/http-server/pom.xml[tags=repos,indent=0]
include::{standalone_samples_path}/http-server/pom.xml[tags=repos,indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle (`settings.xml`)
----
include:../:{standalone_samples_path}/http-server/settings.gradle[tags=repos,indent=0]
include::{standalone_samples_path}/http-server/settings.gradle[tags=repos,indent=0]
----
====

View File

@@ -1,6 +1,8 @@
[[features-stub-runner-stubs-per-consumer]]
= Consumer-Driven Contracts: Stubs Per Consumer
include::partial$_attributes.adoc[]
There are cases in which two consumers of the same endpoint want to have two different responses.
TIP: This approach also lets you immediately know which consumer uses which part of your API.
@@ -70,7 +72,7 @@ Alternatively, you can set the test as follows:
====
[source,groovy]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerStubsPerConsumerSpec.groovy[tags=test]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerStubsPerConsumerSpec.groovy[tags=test]
...
}
----
@@ -84,7 +86,7 @@ You can also set the consumer name explicitly, as follows:
====
[source,groovy]
----
include:../:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerStubsPerConsumerWithConsumerNameSpec.groovy[tags=test]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerStubsPerConsumerWithConsumerNameSpec.groovy[tags=test]
...
}
----

View File

@@ -1,6 +1,8 @@
[[features-stub-runner-stubs-protocol]]
= Fetching Stubs or Contract Definitions From A Location
include::partial$_attributes.adoc[]
Instead of picking the stubs or contract definitions from
Artifactory, Nexus, or Git, you can point to
a location on a drive or the classpath. Doing so can be especially useful in a multi-module project, where one module wants

View File

@@ -1,6 +1,7 @@
[[features-wiremock]]
= Spring Cloud Contract WireMock
include::partial$_attributes.adoc[]
The Spring Cloud Contract WireMock modules let you use https://github.com/tomakehurst/wiremock[WireMock] in a
Spring Boot application. For more detail, check out the
@@ -11,15 +12,7 @@ the default with `spring-boot-starter-web`), you can add
`spring-cloud-starter-contract-stub-runner` to your classpath and add `@AutoConfigureWireMock`
to use Wiremock in your tests. Wiremock runs as a stub server, and you
can register stub behavior by using a Java API or by using static JSON declarations as part of
your test. The following code shows an example:
====
[source,java,indent=0]
----
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsTests.java[tags=wiremock_test1]
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsTests.java[tags=wiremock_test2]
----
====
your test.
To start the stub server on a different port, use (for example),
`@AutoConfigureWireMock(port=9999)`. For a random port, use a value of `0`. The stub
@@ -61,7 +54,7 @@ public class WiremockImportApplicationTests {
NOTE: Actually, WireMock always loads mappings from `src/test/resources/mappings` *as
well as* the custom locations in the `stubs` attribute. To change this behavior, you can
also specify a file root, as described in the xref:_project-features-wiremock.adoc#features-wiremock-using-files[next section of this document].
also specify a file root, as described in the xref:project-features-wiremock.adoc#features-wiremock-using-files[next section of this document].
NOTE: Also, the mappings in the `stubs` location are not considered part of Wiremock's "default mappings" and calls
to `com.github.tomakehurst.wiremock.client.WireMock.resetToDefaultMappings` during a test do not result in the mappings
@@ -106,15 +99,7 @@ effect on the stubs loaded explicitly from the `stubs` attribute.
For a more conventional WireMock experience, you can use JUnit `@Rules` to start and stop
the server. To do so, use the `WireMockSpring` convenience class to obtain an `Options`
instance, as the following example shows:
====
[source,java,indent=0]
----
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsClassRuleTests.java[tags=wiremock_test1]
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsClassRuleTests.java[tags=wiremock_test2]
----
====
instance, as the following {doc_samples_url}[example] shows:
The `@ClassRule` means that the server shuts down after all the methods in this class
have been run.
@@ -177,14 +162,7 @@ property to `false`.
== WireMock and Spring MVC Mocks
Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into
a Spring `MockRestServiceServer`. The following code shows an example:
====
[source,java,indent=0]
----
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java[tags=wiremock_test]
----
====
a Spring `MockRestServiceServer`. The following {doc_samples_url}[project] shows that.
The `baseUrl` value is prepended to all mock calls, and the `stubs()` method takes a stub
path resource pattern as an argument. In the preceding example, the stub defined at

View File

@@ -1,6 +1,8 @@
[[features]]
= Spring Cloud Contract Features
include::partial$_attributes.adoc[]
This section dives into the details of {project-full-name}. Here you can learn about the key
features that you may want to use and customize. If you have not already done so, you
might want to read the "xref:getting-started.adoc[Getting Started]" and

View File

@@ -1,18 +0,0 @@
[[spring-cloud-contract-reference-documentation]]
= Spring Cloud Contract Reference Documentation
:page-section-summary-toc: 1
Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant
:docinfo: shared
The reference documentation consists of the following sections:
[horizontal]
<<legal.adoc#legal-information,Legal>> :: Legal information.
<<documentation-overview.adoc#contract-documentation,Documentation Overview>> :: About the Documentation, Getting Help, First Steps, and more.
xref:getting-started.adoc[Getting Started] :: Introducing {project-full-name}, Developing Your First {project-full-name}-based Application
xref:using.adoc[Using {project-full-name}] :: {project-full-name} usage examples and workflows.
xref:project-features.adoc[{project-full-name} Features] :: Contract DSL, Messaging, Spring Cloud Contract Stub Runner, and Spring Cloud Contract WireMock.
xref:project-features.adoc#features-build-tools[Build Tools] :: Maven Plugin, Gradle Plugin, and Docker.
xref:howto.adoc["`How-to`" Guides] :: Stubs versioning, Debugging, and more.
<<appendix.adoc#appendix,Appendices>> :: Properties, Metadata, Configuration, Dependencies, and more.

View File

@@ -1,6 +1,8 @@
[[using]]
= Using Spring Cloud Contract
include::partial$_attributes.adoc[]
This section goes into more detail about how you should use {project-full-name}. It covers topics
such as flows of how to work with {project-full-name}. We also
cover some {project-full-name} best practices.
@@ -19,7 +21,7 @@ You can check the xref:getting-started/first-application.adoc[Developing Your Fi
In this flow, we perform the provider contract testing (the producer has no knowledge of how consumers use their API). The stubs are uploaded to a separate repository (they are not uploaded to Artifactory or Nexus).
[[prerequisites]]
[[using-prerequisites]]
=== Prerequisites
Before testing provider contracts with stubs in git, you must provide a git repository
@@ -27,7 +29,6 @@ that contains all the stubs for each producer. For an example of such a project,
{samples_code}/contract_git[this samples ] or {samples_code}/contract_git[this sample].
As a result of pushing stubs there, the repository has the following structure:
====
[source,bash,indent=0]
----
$ tree .
@@ -40,7 +41,6 @@ $ tree .
   └── contractC.groovy
----
====
You must also provide consumer code that has Spring Cloud Contract Stub Runner set up. For
an example of such a project, see {samples_code}/consumer[this sample] and search for a
@@ -65,9 +65,11 @@ In order to fetch the stubs from a git repository instead of Nexus or Artifactor
need to use the `git` protocol in the URL of the `repositoryRoot` property in Stub Runner.
The following example shows how to set it up:
====
[tabs]
======
Annotation::
+
[source,java,indent=0,subs="verbatim,attributes",role="primary"]
.Annotation
----
@AutoConfigureStubRunner(
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
@@ -75,8 +77,9 @@ stubsMode = StubRunnerProperties.StubsMode.REMOTE,
ids = "com.example:artifact-id:0.0.1")
----
JUnit 4 Rule::
+
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.JUnit 4 Rule
----
@Rule
public StubRunnerRule rule = new StubRunnerRule()
@@ -85,8 +88,9 @@ stubsMode = StubRunnerProperties.StubsMode.REMOTE,
.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
----
JUnit 5 Extension::
+
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.JUnit 5 Extension
----
@RegisterExtension
public StubRunnerExtension stubRunnerExtension = new StubRunnerExtension()
@@ -94,7 +98,7 @@ stubsMode = StubRunnerProperties.StubsMode.REMOTE,
.repoRoot("git://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
----
====
======
[[flows-provider-git-producer]]
=== Setting up the Producer
@@ -104,9 +108,11 @@ to use the `git` protocol in the URL of the plugin setup. Also you need to expli
the plugin to push the stubs at the end of the build process. The following examples show
how to do so in both Maven and Gradle:
====
[tabs]
======
Maven::
+
[source,xml,indent=0,role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -144,8 +150,9 @@ how to do so in both Maven and Gradle:
</plugin>
----
Gradle::
+
[source,groovy,indent=0,role="secondary"]
.Gradle
----
contracts {
// We want to pick contracts from a Git repository
@@ -171,7 +178,7 @@ the `publish` task is run
*/
publish.dependsOn("publishStubsToScm")
----
====
======
You can read more about setting up a git repository in the
xref:howto/how-to-use-git-as-storage.adoc[How To section] of the documentation.
@@ -239,13 +246,11 @@ The test fails due to no server being present.
For example, for a producer named `producer` and a consumer named `consumer`, the contracts would be stored under `src/main/resources/contracts/producer/consumer/`)
. Once the contracts are defined, installs the producer stubs to local storage, as the following example shows:
+
====
[source,bash,indent=0]
----
$ cd src/main/resource/contracts/producer
$ ./mvnw clean install
----
====
. Sets up Spring Cloud Contract (SCC) Stub Runner in the consumer tests, to:
* Fetch the producer stubs from local storage.
* Work in the stubs-per-consumer mode (this enables consumer driven contracts mode).
@@ -285,27 +290,25 @@ The producer:
. Takes over the pull request to the repository with contract definitions. You can do it
from the command line, as follows
+
====
[source,bash,indent=0]
----
$ git checkout -b the_branch_with_pull_request master
git pull https://github.com/user_id/project_name.git the_branch_with_pull_request
----
====
. Installs the contract definitions, as follows
+
====
[source,bash,indent=0]
----
$ ./mvnw clean install
----
====
. Sets up the plugin to fetch the contract definitions from a JAR instead of from
`src/test/resources/contracts`, as follows:
+
====
[tabs]
======
Maven::
+
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -325,8 +328,9 @@ $ ./mvnw clean install
</plugin>
----
Gradle::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
contracts {
// We want to use the JAR with contracts with the following coordinates
@@ -339,26 +343,28 @@ contracts {
// Additional configuration
}
----
====
======
. Runs the build to generate tests and stubs, as follows:
+
====
[tabs]
======
Maven::
+
[source,bash,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
./mvnw clean install
----
Gradle::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
./gradlew clean build
----
====
======
. Writes the missing implementation, to make the tests pass.
. Merges the pull request to the repository with contract definitions, as follows:
+
====
[source,bash,indent=0]
----
$ git commit -am "Finished the implementation to make the contract tests pass"
@@ -366,7 +372,6 @@ $ git checkout master
$ git merge --no-ff the_branch_with_pull_request
$ git push origin master
----
====
+
The CI system builds the project with the contract definitions and uploads the JAR with
the contract definitions to Nexus or Artifactory.
@@ -374,9 +379,11 @@ the contract definitions to Nexus or Artifactory.
. Sets up the plugin so that the contract definitions are no longer taken from the local
storage but from a remote location, as follows:
+
====
[tabs]
======
Maven::
+
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -396,8 +403,9 @@ storage but from a remote location, as follows:
</plugin>
----
Gradle::
+
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
contracts {
// We want to use the JAR with contracts with the following coordinates
@@ -410,7 +418,7 @@ contracts {
// Additional configuration
}
----
====
======
. Merges the producer code with the new implementation.
. The CI system:
** Builds the project.
@@ -475,9 +483,11 @@ You can read xref:getting-started/first-application.adoc[Developing Your First S
For the consumer side, you can use a JUnit rule. That way, you need not start a Spring context. The following listing shows such a rule (in JUnit4 and JUnit 5);
====
[tabs]
======
JUnit 4 Rule::
+
[source,java,indent=0,subs="verbatim,attributes",role="primary"]
.JUnit 4 Rule
----
@Rule
public StubRunnerRule rule = new StubRunnerRule()
@@ -486,8 +496,9 @@ For the consumer side, you can use a JUnit rule. That way, you need not start a
.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
----
JUnit 5 Extension::
+
[source,java,indent=0,subs="verbatim,attributes",role="secondary"]
.JUnit 5 Extension
----
@RegisterExtension
public StubRunnerExtension stubRunnerExtension = new StubRunnerExtension()
@@ -495,7 +506,7 @@ For the consumer side, you can use a JUnit rule. That way, you need not start a
.repoRoot("git://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
----
====
======
[[flows-provider-non-spring-producer]]
=== Setting up the Producer
@@ -509,7 +520,6 @@ non-Spring HTTP server.
Assume that we have the following application:
====
[source,java,indent=0]
----
package com.example.demo;
@@ -536,14 +546,15 @@ public class DemoApplication {
}
----
====
Given that application, we can set up the plugin to use the `EXPLICIT` mode (that is, to
send out requests to a real port), as follows:
====
[tabs]
======
Maven::
+
[source,xml,indent=0,role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
@@ -558,8 +569,9 @@ send out requests to a real port), as follows:
</plugin>
----
Gradle::
+
[source,groovy,indent=0,role="secondary"]
.Gradle
----
contracts {
// This will setup the EXPLICIT mode for the tests
@@ -567,11 +579,10 @@ contracts {
baseClassForTests = "com.example.demo.BaseClass"
}
----
====
======
The base class might resemble the following:
====
[source,java,indent=0]
----
import io.javalin.Javalin;
@@ -606,7 +617,6 @@ public class BaseClass {
}
}
----
====
With such a setup:
@@ -647,8 +657,8 @@ At a high level, the producer:
.. Start the application with mocked services on a given port.
+
If mocking is not possible, you can set up the infrastructure and define tests in a stateful way.
.. Run the Spring Cloud Contract Docker image and pass the port of a running application as an environment variable.
.. Run the Spring Cloud Contract Docker image and pass the port of a running application as an environment variable.
The SCC Docker image:
* Generates the tests from the attached volume.
* Runs the tests against the running application.
@@ -725,9 +735,11 @@ As a producer, we:
. Write RESTDocs tests of our API.
. Add Spring Cloud Contract Stub Runner starter to our build (`spring-cloud-starter-contract-stub-runner`), as follows:
+
====
[tabs]
======
Maven::
+
[source,xml,indent=0,role="primary"]
.Maven
----
<dependencies>
<dependency>
@@ -750,8 +762,9 @@ As a producer, we:
</dependencyManagement>
----
Gradle::
+
[source,groovy,indent=0,role="secondary"]
.Gradle
----
dependencies {
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-stub-runner'
@@ -763,12 +776,14 @@ dependencyManagement {
}
}
----
====
======
. We set up the build tool to package our stubs, as follows:
+
====
[tabs]
======
Maven::
+
[source,xml,indent=0,role="primary"]
.Maven
----
<!-- pom.xml -->
<plugins>
@@ -816,8 +831,9 @@ dependencyManagement {
</assembly>
----
Gradle::
+
[source,groovy,indent=0,role="secondary"]
.Gradle
----
task stubsJar(type: Jar) {
classifier = "stubs"
@@ -830,7 +846,7 @@ task stubsJar(type: Jar) {
stubsJar.dependsOn(test)
bootJar.dependsOn(stubsJar)
----
====
======
Now, when we run the tests, stubs are automatically published and packaged.

View File

@@ -2,13 +2,9 @@
= YML Schema
:page-section-summary-toc: 1
Below you can find a JSON schema definition of a YAML contract.
====
[source,json,indent=0]
----
// TODO: reenable
//include::{project-root}/docs/target/contract_schema.json[indent=0]
include::partial$contract_schema.json[indent=0]
----
====

View File

@@ -0,0 +1,23 @@
:sc-ext: java
:project-full-name: Spring Cloud Contract
// project-specific attributes
:converters_path: example$tools-src/spring-cloud-contract-converters
:verifier_root_path: example$verifier-src
:contract_spec_path: example$specs-src/spring-cloud-contract-spec-java
:contract_spec_tests_path: example$specs-src/spring-cloud-contract-spec
:contract_kotlin_spec_path: example$specs-src/spring-cloud-contract-spec-kotlin
:samples_path: example$samples-src
:stubrunner_core_path: example$stubrunner-src
:standalone_samples_path: example$samples-src/standalone/dsl
:standalone_messaging_samples_path: example$samples-src/standalone/dsl
:standalone_restdocs_path: example$samples-src/standalone/restdocs
:tests_path: example$tests-src
:tools_path: example$tools-src
:plugins_path: {tools_path}
:samples_branch: main
:samples_url: https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/{samples_branch}
:samples_code: https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}
:doc_samples: {samples_code}/wiremock-for-contract-docs
:doc_samples_url: {samples_url}/wiremock-for-contract-docs
:wiremock_tests: example$wiremock-src

View File

@@ -44,4 +44,4 @@
|wiremock.server.port-dynamic | `+++false+++` |
|wiremock.server.stubs | `+++[]+++` |
|===
|===

Some files were not shown because too many files have changed in this diff Show More