Merge branch '3.1.x'

This commit is contained in:
Marcin Grzejszczak
2022-07-01 14:21:56 +02:00
18 changed files with 127 additions and 238 deletions

View File

@@ -130,8 +130,7 @@
<executable>./build_adocs.sh</executable>
</configuration>
</execution>
<!-- TODO: Remove me -->
<!--<execution>
<execution>
<id>generate-adoc-resources</id>
<phase>process-classes</phase>
<goals>
@@ -143,7 +142,7 @@
<argument>${maven.multiModuleProjectDirectory}/docs</argument>
</arguments>
</configuration>
</execution>-->
</execution>
</executions>
</plugin>
<plugin>

View File

@@ -27,12 +27,13 @@
: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_pact_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}/
: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}
:standalone_pact_path: {samples_url}/

View File

@@ -1876,7 +1876,7 @@ The XPath expression to select the email address is
WARNING: Beware, as the unqualified expressions (`/customer/email/text()` or `*/[local-name()='customer' and namespace-uri()='http://demo.com/customer']/email/text()`)
result in `""`. Even the child elements have to be referenced with the `local-name` syntax.
====== General Namespaced Node Expression Syntax
===== General Namespaced Node Expression Syntax
- Node using qualified namespace:
```
/<node-name>

View File

@@ -16,7 +16,6 @@ You can add the additional snapshot repository to your build file to use snapsho
versions, which are automatically uploaded after every successful build, as follows:
====
////
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
@@ -24,11 +23,10 @@ include::{standalone_samples_path}/http-server/pom.xml[tags=repos,indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
.Gradle (`settings.xml`)
----
include::{standalone_samples_path}/http-server/build.gradle[tags=repos,indent=0]
include::{standalone_samples_path}/http-server/settings.gradle[tags=repos,indent=0]
----
////
====
[[features-stub-runner-publishing-stubs-as-jars]]
@@ -43,7 +41,6 @@ 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
----
@@ -56,15 +53,12 @@ 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]
----
////
====
[[features-stub-runner-core]]
@@ -250,23 +244,19 @@ example shows how to do so:
.WireMockHttpServerStubConfigurer implementation
====
////
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=wireMockHttpServerStubConfigurer]
----
////
====
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]
----
////
====
Whenever an HTTPS port is found, it takes precedence over the HTTP port.
@@ -382,12 +372,10 @@ Stub Runner comes with a JUnit rule that lets you can download and run stubs for
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]
----
////
====
A `StubRunnerExtension` is also available for JUnit 5. `StubRunnerRule` and
@@ -410,18 +398,15 @@ Since the `StubRunnerRule` and `StubRunnerExtension` implement the `StubFinder`,
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]
----
////
====
The following examples provide more detail about using Stub Runner:
====
////
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Spock
----
@@ -439,7 +424,6 @@ include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contra
----
include::{stubrunner_core_path}/src/test/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerJUnit5ExtensionTests.java[tags=extension]
----
////
====
See the <<features-stub-runner-common-properties-junit-spring>> for more information on
@@ -470,23 +454,19 @@ When using the `StubRunnerRule` or `StubRunnerExtension`, you can add a stub to
and then pass the port for the last downloaded stub. The following example shows how to do so:
====
////
[source,java,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port]
----
////
====
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]
----
////
====
[[features-stub-runner-rule-spring]]
@@ -501,35 +481,29 @@ If you want to find the URL of your stubbed dependency, you can autowire the `St
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]
----
////
====
Doing so depends on the following configuration file:
====
////
[source,yml,indent=0]
----
include::{stubrunner_core_path}/src/test/resources/application-test.yml[tags=test]
----
////
====
Instead of using the properties, you can also use the properties inside the `@AutoConfigureStubRunner`.
The following example achieves the same result by setting values on the annotation:
====
////
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy[tags=autoconfigure]
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/consul/StubRunnerSpringCloudConsulAutoConfigurationSpec.groovy[tags=autoconfigure]
----
////
====
Stub Runner Spring registers environment variables in the following manner
@@ -582,28 +556,6 @@ dependencies and we are telling your application, whenever you use `Feign`, to l
balanced `RestTemplate` or `DiscoveryClient` directly, to call those stubbed servers
instead of calling the real Service Discovery tool.
For example, the following test passes:
====
////
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy[tags=test]
----
////
====
Note that the preceding example requires the following configuration file:
====
////
[source,yml,indent=0]
----
include::{stubrunner_core_path}/src/test/resources/application.yml[tags=ids]
----
////
====
[[features-stub-runner-cloud-stubbing-profiles]]
===== Test Profiles and Service Discovery
@@ -649,9 +601,15 @@ by setting the following system properties or by setting the corresponding envir
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.
One of the use cases is to run some smoke (end-to-end) tests on a deployed application.
You can check out the https://github.com/spring-cloud/spring-cloud-pipelines[Spring Cloud Pipelines]
project for more information.
[[features-stub-runner-boot-security]]
==== Stub Runner Boot Security
The Stub Runner Boot application is not secured by design - securing it would require to add security to all
stubs even if they don't actually require it. Since this is a testing utility - the server is **not intended**
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.
[[features-stub-runner-boot-server]]
==== Stub Runner Server
@@ -739,12 +697,10 @@ For Messaging, Stub Runner Boot makes the following endpoints available:
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]
----
////
[[features-stub-runner-boot-service-discovery]]
==== Stub Runner Boot with Service Discovery
@@ -759,33 +715,11 @@ of testing scenarios.
The problem with this approach is that, if you use microservices, you most likely also
use a service discovery tool. Stub Runner Boot lets you solve this issue by starting the
required stubs and registering them in a service discovery tool. Consider the following example of
such a setup with Eureka (assume that Eureka is already running):
====
////
[source,java,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java[tags=stubrunnereureka]
----
////
====
We want to start a Stub Runner Boot server (`@EnableStubRunnerServer`), enable the Eureka client (`@EnableEurekaClient`),
and have the stub runner feature turned on (`@AutoConfigureStubRunner`).
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}` contains the following list of properties:
====
////
[source,bash,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java[tags=stubrunnereureka_args]
----
////
====
`${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
@@ -862,14 +796,12 @@ The `bar-consumer` consumer can either set the `spring.application.name` or the
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]
...
}
----
////
====
Then only the stubs registered under a path that contains `bar-consumer` in its name (that is, those from the
@@ -878,14 +810,12 @@ Then only the stubs registered under a path that contains `bar-consumer` in its
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]
...
}
----
////
====
Then only the stubs registered under a path that contains the `foo-consumer` in its name (that is, those from the

View File

@@ -16,8 +16,8 @@ your test. The following code shows an example:
====
[source,java,indent=0]
----
include::{doc_samples}/src/test/java/com/example/WiremockForDocsTests.java[tags=wiremock_test1]
include::{doc_samples}/src/test/java/com/example/WiremockForDocsTests.java[tags=wiremock_test2]
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]
----
====
@@ -111,8 +111,8 @@ instance, as the following example shows:
====
[source,java,indent=0]
----
include::{doc_samples}/src/test/java/com/example/WiremockForDocsClassRuleTests.java[tags=wiremock_test1]
include::{doc_samples}/src/test/java/com/example/WiremockForDocsClassRuleTests.java[tags=wiremock_test2]
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]
----
====
@@ -182,7 +182,7 @@ a Spring `MockRestServiceServer`. The following code shows an example:
====
[source,java,indent=0]
----
include::{doc_samples}/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java[tags=wiremock_test]
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java[tags=wiremock_test]
----
====

View File

@@ -389,6 +389,11 @@ This section describes how to use Docker on the consumer side to fetch and run s
We publish a `spring-cloud/spring-cloud-contract-stub-runner` Docker image
that starts the standalone version of Stub Runner.
[[docker-stubrunner-security]]
=== Security
Since the Spring Cloud Contract Stub Runner Docker Image uses the standalone version of Stub Runner the same security considerations need to be taken. You can read more about those link:project-features.html#features-stub-runner-boot-security[in this section of the documentation].
[[docker-stubrunner-env-vars]]
=== Environment Variables

View File

@@ -117,7 +117,6 @@ the `PUT` method. The following listing shows a contract to check whether a clie
be marked as a fraud in both Groovy and YAML:
====
////
[source,groovy,indent=0,role="primary"]
.groovy
----
@@ -131,7 +130,6 @@ include::{introduction_url}/samples/standalone/dsl/http-server/src/test/resource
----
include::{introduction_url}/samples/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
----
////
====
[[getting-started-three-second-tour]]
@@ -177,12 +175,10 @@ Then you can add the Spring Cloud Contract Verifier dependency and plugin to you
the following example shows:
====
////
[source,xml,indent=0]
----
include::{introduction_url}/samples/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
@@ -255,12 +251,10 @@ 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]
----
////
====
You can get the Producer-side stubs installed in your Maven repository in either of two
@@ -285,12 +279,10 @@ 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[]
----
////
====
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
@@ -340,12 +332,10 @@ To start working with `Spring Cloud Contract`, you can add the Spring Cloud Cont
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]
----
////
====
The following listing shows how to add the plugin, which should go in the build/plugins
@@ -757,12 +747,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]
----
////
====
You can get the Producer-side stubs installed in your Maven repository in either of two
@@ -786,12 +774,10 @@ pass the stub artifact IDs and artifact repository URL as `Spring Cloud Contract
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[]
----
////
====
Now you can annotate your test class with `@AutoConfigureStubRunner`. In the annotation,
@@ -868,7 +854,6 @@ If you use the SNAPSHOT, Milestone, or Release Candidate versions, you need to a
following section to your build:
====
////
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
@@ -882,7 +867,6 @@ include::{introduction_url}/samples/standalone/dsl/http-server/pom.xml[tags=repo
----
include::{introduction_url}/samples/standalone/dsl/http-server/build.gradle[tags=deps_repos,indent=0]
----
////
====
For simplicity, we use the following acronyms:
@@ -946,12 +930,10 @@ The following listing shows a test that we might use to check whether a loan amo
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]
----
////
====
Assume that you have written a test of your new feature. If a loan application for a big
@@ -966,12 +948,10 @@ client wants to borrow. You want to send it to the `/fraudcheck` URL by using th
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]
----
////
====
For simplicity, the port of the Fraud Detection service is set to `8080`, and the
@@ -1005,7 +985,6 @@ 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
----
@@ -1019,7 +998,6 @@ include::{introduction_url}/samples/standalone/dsl/http-server/src/test/resource
----
include::{introduction_url}/samples/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
@@ -1057,23 +1035,19 @@ We can add either a Maven or a Gradle plugin. In this example, we show how to ad
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]
----
////
====
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]
----
////
====
Since the plugin was added, you get the `Spring Cloud Contract Verifier` features, which,
@@ -1135,23 +1109,19 @@ 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]
----
////
====
. 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]
----
////
====
. Annotate your test class with `@AutoConfigureStubRunner`. In the annotation, provide the
@@ -1159,12 +1129,10 @@ include::{introduction_url}/samples/standalone/dsl/http-client/pom.xml[tags=stub
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]
----
////
====
. (Optional) Because you are playing with the collaborators offline, you
@@ -1237,14 +1205,12 @@ 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]
}
----
////
====
Then you can run the following commands:
@@ -1260,23 +1226,19 @@ $ 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]
----
////
====
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]
----
////
====
IMPORTANT: This example uses "`convention-based`" naming by setting the
@@ -1292,12 +1254,10 @@ start the server side `FraudDetectionController`. The following listing shows th
`FraudBase` class:
====
////
[source,java,indent=0]
----
include::{introduction_url}/samples/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:
@@ -1358,7 +1318,6 @@ Because you know the expected input and expected output, you can write the missi
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]
@@ -1366,7 +1325,6 @@ include::{introduction_url}/samples/standalone/dsl/http-server/src/main/java/com
include::{introduction_url}/samples/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
@@ -1440,12 +1398,10 @@ side are automatically downloaded from Nexus/Artifactory. You can set the value
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[]
----
////
====
That's it. You have finished the tutorial.

View File

@@ -174,13 +174,11 @@ You can add the additional snapshot repository to your `settings.gradle` to use
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]]
@@ -402,12 +400,10 @@ specification for all generated acceptance tests. In this class, you need to poi
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,
@@ -432,32 +428,13 @@ The convention is such that, if you have a contract in (for example)
Verifier assumes that there is a `BarBazBase` class under the `com.example.base` package.
In other words, the system takes the last two parts of the package, if they exist, and
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,groovy,indent=0]
----
include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy[tags=package_with_base_classes,indent=0]
----
////
====
=== By Mapping
You can manually map a regular expression of the contract's package to the fully qualified
name of the base class for the matched contract. You have to provide a list called
`baseClassMappings` that consists of `baseClassMapping` objects that take a
`contractPackageRegex` to `baseClassFQN` mapping. Consider the following example:
====
////
[source,groovy,indent=0]
----
include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy[tags=base_class_mappings,indent=0]
----
////
====
`contractPackageRegex` to `baseClassFQN` mapping.
Assume that you have contracts in the following directories:

View File

@@ -290,12 +290,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]
----
////
====
There are no dependencies other than the Spring Cloud Contract Maven Plugin.
@@ -305,24 +303,20 @@ 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]
----
////
====
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]
----
////
====
[[how-to-workflow]]
@@ -385,12 +379,10 @@ As a producer, you can alter the Spring Cloud Contract Verifier to provide the U
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]
----
////
====
With this setup, the JAR with a `groupid` of `com.example.standalone` and an `artifactid` of
@@ -778,7 +770,6 @@ contracts locally, with the producer, and only push the contracts and the stubs
The following listing shows the setup required to achieve this with Maven and Gradle:
====
////
[source,xml,indent=0,role="primary"]
.Maven
----
@@ -790,7 +781,6 @@ include::{samples_url}/producer_with_empty_git/pom.xml[tags=plugin,indent=0]
----
include::{samples_url}/producer_with_empty_git/build.gradle[tags=plugin,indent=0]
----
////
====
With such a setup:
@@ -882,16 +872,7 @@ set a `metaData` entry in the Pact file with the `sentTo` key equal to the desti
=== Pact Contract
Spring Cloud Contract can read the Pact JSON definition. You can place the file in the
`src/test/resources/contracts` folder. Remember to put the `spring-cloud-contract-pact` dependency to your classpath. The following example shows such a Pact contract:
====
////
[source,javascript,indent=0]
----
include::{standalone_pact_path}/http-server/src/test/resources/contracts/pact/shouldMarkClientAsFraud.json[indent=0]
----
////
====
`src/test/resources/contracts` folder. Remember to put the `spring-cloud-contract-pact` dependency to your classpath.
[[how-to-use-pact-broker-pact-for-producers]]
=== Pact for Producers
@@ -902,19 +883,17 @@ the current Pact version that you use. The following listing shows how to do so
Maven and Gradle:
====
////
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
include::{standalone_pact_path}/http-server/pom.xml[tags=pact_dependency,indent=0]
include::{standalone_pact_path}/producer_pact/pom.xml[tags=pact_dependency,indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
include::{standalone_pact_path}/http-server/build.gradle[tags=pact_dependency,indent=0]
include::{standalone_pact_path}/producer_pact/build.gradle[tags=pact_dependency,indent=0]
----
////
====
When you build your application, a test and stub is generated. The following
@@ -987,19 +966,17 @@ current Pact version that you use. The following listing shows how to do so for
Maven and Gradle:
====
////
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
include::{standalone_pact_path}/http-client/pom.xml[tags=pact_dependency,indent=0]
include::{standalone_pact_path}/consumer_pact_stubrunner/pom.xml[tags=pact_dependency,indent=0]
----
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
include::{standalone_pact_path}/http-client/build.gradle[tags=pact_dependency,indent=0]
include::{standalone_pact_path}/consumer_pact_stubrunner/build.gradle[tags=pact_dependency,indent=0]
----
////
====
[[pact-stub-downloader]]
@@ -1448,7 +1425,6 @@ you only need to make some minor changes to your setup if you are using MockMvc
To do so, include the following dependencies (if you have not already done so):
====
////
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.maven
----
@@ -1460,14 +1436,12 @@ include::{standalone_restdocs_path}/http-server/pom.xml[tags=dependencies,indent
----
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:
====
////
[source,java,indent=0,subs="verbatim,attributes",role="primary"]
.WebAppContext
----
@@ -1479,7 +1453,6 @@ include::{standalone_restdocs_path}/http-server/src/test/java/com/example/fraud/
----
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

@@ -25,23 +25,19 @@ You can also check the plugin's documentation link:../../spring-cloud-contract-m
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
@@ -141,12 +137,10 @@ To use Snapshot and Milestone versions, you have to add the following section to
`pom.xml`:
====
////
[source,xml,indent=0]
----
include::{standalone_samples_path}/http-server/pom.xml[tags=repos,indent=0]
----
////
====
[[maven-add-stubs]]
@@ -400,12 +394,10 @@ forms a class with a `Base` suffix. This rule takes precedence over `baseClassFo
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
@@ -416,12 +408,10 @@ name of the base class for the matched contract. You have to provide a list call
`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:
@@ -651,12 +641,10 @@ path where your base test classes are defined and the path were the generated co
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]
----
////
====
If you uphold the Spock convention of ending the test class names with `Spec`, you also need to adjust your Maven

View File

@@ -5,10 +5,8 @@ include::_attributes.adoc[]
Below you can find a JSON schema definition of a YAML contract.
====
////
[source,json,indent=0]
----
include::{project-root}/docs/target/contract_schema.json[indent=0]
----
////
====

View File

@@ -93,27 +93,33 @@ public class Main {
mapper.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
StringBuilder sb = new StringBuilder();
for (Class metadatum : metadata) {
SpringCloudContractMetadata newInstance = (SpringCloudContractMetadata) metadatum
.getDeclaredConstructors()[0].newInstance();
String description = newInstance.description();
String key = newInstance.key();
List<Class> additionalClasses = classesToLookAt(metadatum, newInstance);
// @formatter:off
sb
.append("[[metadata-").append(key).append("]]\n")
.append("##### Metadata `").append(key).append("`\n\n")
.append("* key: `").append(key).append("`").append("\n")
.append("* description:\n\n").append(description).append("\n\n")
.append("Example:\n\n")
.append("```yaml\n").append(mapper.writeValueAsString(newInstance)).append("\n```\n\n")
// To make the schema collapsable
.append("+++ <details><summary> +++\nClick here to expand the JSON schema:\n+++ </summary><div> +++\n")
.append("```json\n").append(generateJsonSchemaForClass(metadatum)).append("\n```\n")
.append("+++ </div></details> +++\n\n")
.append("If you are interested in learning more about the types and its properties, check out the following classes:\n\n")
.append(additionalClasses.stream().map(aClass -> "* `" + aClass.getName() + "`").collect(Collectors.joining("\n")))
.append("\n\n");
// @formatter:on
try {
SpringCloudContractMetadata newInstance = (SpringCloudContractMetadata) metadatum
.getDeclaredConstructor(null).newInstance();
String description = newInstance.description();
String key = newInstance.key();
List<Class> additionalClasses = classesToLookAt(metadatum, newInstance);
// @formatter:off
sb
.append("[[metadata-").append(key).append("]]\n")
.append("##### Metadata `").append(key).append("`\n\n")
.append("* key: `").append(key).append("`").append("\n")
.append("* description:\n\n").append(description).append("\n\n")
.append("Example:\n\n")
.append("```yaml\n").append(mapper.writeValueAsString(newInstance)).append("\n```\n\n")
// To make the schema collapsable
.append("+++ <details><summary> +++\nClick here to expand the JSON schema:\n+++ </summary><div> +++\n")
.append("```json\n").append(generateJsonSchemaForClass(metadatum)).append("\n```\n")
.append("+++ </div></details> +++\n\n")
.append("If you are interested in learning more about the types and its properties, check out the following classes:\n\n")
.append(additionalClasses.stream().map(aClass -> "* `" + aClass.getName() + "`").collect(Collectors.joining("\n")))
.append("\n\n");
// @formatter:on
}
catch (Exception exception) {
log.error("Exception occurred while trying to parse [" + metadatum + "]");
throw exception;
}
}
return sb;
}

View File

@@ -1,4 +1,4 @@
// tag:repos[]
// tag::repos[]
pluginManagement {
repositories {
mavenLocal()
@@ -7,7 +7,7 @@ pluginManagement {
maven { url "https://repo.spring.io/release" }
gradlePluginPortal()
}
// end:repos[]
// end::repos[]
plugins {
id "org.springframework.boot" version "${bootVersion}"
id "io.spring.dependency-management" version "1.0.10.RELEASE"

View File

@@ -49,11 +49,13 @@ import static org.mockito.Mockito.mock
"stubrunner.cloud.consul.enabled=true",
"stubrunner.cloud.zookeeper.enabled=false",
"debug=true"])
// tag::autoconfigure[]
@AutoConfigureStubRunner(ids = ["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
"org.springframework.cloud.contract.verifier.stubs:bootService"] ,
stubsMode = StubRunnerProperties.StubsMode.REMOTE ,
repositoryRoot = "classpath:m2repo/repository/" )
// end::autoconfigure[]
class StubRunnerSpringCloudConsulAutoConfigurationSpec extends Specification {
@Autowired

View File

@@ -1,4 +1,3 @@
/*
* Copyright 2013-2020 the original author or authors.
*
@@ -27,7 +26,6 @@ import org.springframework.cloud.contract.spec.internal.DslProperty;
import org.springframework.cloud.contract.spec.internal.Request;
import org.springframework.cloud.contract.verifier.util.ContractVerifierUtil;
// tag::class[]
class contract_multipart implements Supplier<Collection<Contract>> {
private static Map<String, DslProperty> namedProps(Request r) {

View File

@@ -1,4 +1,3 @@
/*
* Copyright 2013-2020 the original author or authors.
*
@@ -23,7 +22,6 @@ import java.util.function.Supplier;
import org.springframework.cloud.contract.spec.Contract;
import org.springframework.cloud.contract.verifier.util.ContractVerifierUtil;
// tag::class[]
class contract_rest implements Supplier<Collection<Contract>> {
@Override

View File

@@ -1,4 +1,3 @@
/*
* Copyright 2013-2020 the original author or authors.
*
@@ -22,7 +21,6 @@ import java.util.function.Supplier;
import org.springframework.cloud.contract.spec.Contract;
// tag::class[]
class contract_rest_from_file implements Supplier<Collection<Contract>> {
@Override

View File

@@ -31,6 +31,7 @@ import spock.util.concurrent.PollingConditions
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.stubrunner.StubFinder
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
import org.springframework.context.annotation.Bean
@@ -278,4 +279,63 @@ class KafkaStubRunnerSpec extends Specification {
return this.output
}
}
Contract dsl =
// tag::sample_dsl[]
Contract.make {
label 'return_book_1'
input {
triggeredBy('bookReturnedTriggered()')
}
outputMessage {
sentTo('output')
body('''{ "bookName" : "foo" }''')
headers {
header('BOOK-NAME', 'foo')
}
}
}
// end::sample_dsl[]
Contract dsl2 =
// tag::sample_dsl_2[]
Contract.make {
label 'return_book_2'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo'
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
// end::sample_dsl_2[]
Contract dsl3 =
// tag::sample_dsl_3[]
Contract.make {
label 'delete_book'
input {
messageFrom('delete')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
assertThat('bookWasDeleted()')
}
}
// end::sample_dsl_3[]
}