Removing the Pact integration; fixes gh-1845

This commit is contained in:
Marcin Grzejszczak
2022-11-17 16:01:40 +01:00
parent cff332fc40
commit dc581e8934
66 changed files with 4 additions and 6689 deletions

View File

@@ -4,8 +4,6 @@ IMPORTANT: The following properties can be passed as a system property (for exam
|===
|Name | Default | Description
|`stubrunner.properties.pactbroker.provider-name-with-group-id` | `false` | When using the Pact Broker-based approach, you can automatically group ID to the provider name.
|`stubrunner.properties.git.branch` | | When using the SCM-based approach, you can customize the branch name to check out.
|`stubrunner.properties.git.commit-message` | Updating project [$project] with stubs | When using the SCM based approach, you can customize the commit message for created stubs. The `$project` text is replaced with the project name.
|`stubrunner.properties.git.no-of-attempts` | `10` | When using the-SCM based approach, you can customize the number of retries to push the stubs to Git.

View File

@@ -36,4 +36,3 @@
: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

@@ -14,5 +14,5 @@ The reference documentation consists of the following sections:
<<using.adoc#using,Using {project-full-name}>> :: {project-full-name} usage examples and workflows.
<<project-features.adoc#features,{project-full-name} Features>> :: Contract DSL, Messaging, Spring Cloud Contract Stub Runner, and Spring Cloud Contract WireMock.
<<project-features.adoc#features-build-tools,Build Tools>> :: Maven Plugin, Gradle Plugin, and Docker.
<<howto.adoc#howto,"`How-to`" Guides>> :: Stubs versioning, Pact integration, Debugging, and more.
<<howto.adoc#howto,"`How-to`" Guides>> :: Stubs versioning, Debugging, and more.
<<appendix.adoc#appendix,Appendices>> :: Properties, Metadata, Configuration, Dependencies, and more.

View File

@@ -96,7 +96,6 @@ Need more details about {project-full-name}'s core features?
<<project-features.adoc#features-jax-rs, JAX-RS>> |
<<project-features.adoc#features-context-paths, Context Paths>> |
<<project-features.adoc#features-rest-docs, RESTDocs>>
<<howto.adoc#how-to-generate-pact-from-scc, Pact>>
* *Modules:*
<<project-features.adoc#features-stub-runner, Stub Runner>> |
<<project-features.adoc#features-wiremock, WireMock>>

View File

@@ -112,7 +112,7 @@ buildscript {
dependencies {
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 Pact or Kotlin spec e.g.:
// here you can also pass additional dependencies such as Kotlin spec e.g.:
// classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:${verifier_version}"
}
}

View File

@@ -28,7 +28,6 @@ Spring Cloud Contract Verifier stand out on the market of Consumer Driven Contra
- Automatic generation of tests from the defined contract.
- Stub Runner functionality: The stubs are automatically downloaded at runtime from Nexus or Artifactory.
- Spring Cloud integration: No discovery service is needed for integration tests.
- Spring Cloud Contract integrates with Pact and provides easy hooks to extend its functionality.
- Ability to add support for any language & framework through Docker.
[[how-to-not-write-contracts-in-groovy]]
@@ -831,427 +830,6 @@ to find stub definitions and contracts. For example, for `com.example:foo:1.0.0`
* Stub servers are started and fed with mappings.
* Messaging definitions are read and used in the messaging tests.
[[how-to-use-pact-broker]]
== How Can I Use the Pact Broker?
When using https://pact.io/[Pact], you can use the https://github.com/pact-foundation/pact_broker[Pact Broker]
to store and share Pact definitions. Starting from Spring Cloud Contract
2.0.0, you can fetch Pact files from the Pact Broker to generate
tests and stubs.
IMPORTANT: Pact follows the consumer contract convention. That means
that the consumer creates the Pact definitions first and then
shares the files with the Producer. Those expectations are generated
from the Consumer's code and can break the Producer if the expectations
are not met.
[[how-to-use-pact-broker-pact]]
=== How to Work with Pact
Spring Cloud Contract includes support for the https://docs.pact.io/[Pact] representation of
contracts up until version 4. Instead of using the DSL, you can use Pact files. In this section, we
show how to add Pact support for your project. Note, however, that not all functionality is supported.
Starting with version 3, you can combine multiple matchers for the same element:
You can use matchers for the body, headers, request and path, and you can use value generators.
Spring Cloud Contract currently only supports multiple matchers that are combined by using the `AND` rule logic.
Next to that, the request and path matchers are skipped during the conversion.
When using a date, time, or datetime value generator with a given format,
the given format is skipped and the ISO format is used.
[[how-to-use-pact-broker-pact-converter]]
=== Pact Converter
In order to properly support the Spring Cloud Contract way of doing messaging
with Pact, you have to provide some additional metadata entries.
To define the destination to which a message gets sent, you have to
set a `metaData` entry in the Pact file with the `sentTo` key equal to the destination to
which a message is to be sent (for example, `"metaData": { "sentTo": "activemq:output" }`).
[[how-to-use-pact-broker-pact-contract]]
=== 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.
[[how-to-use-pact-broker-pact-for-producers]]
=== Pact for Producers
On the producer side, you must add two additional dependencies to your plugin
configuration. One is the Spring Cloud Contract Pact support, and the other represents
the current Pact version that you use. The following listing shows how to do so for both
Maven and Gradle:
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
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}/producer_pact/build.gradle[tags=pact_dependency,indent=0]
----
====
When you build your application, a test and stub is generated. The following
example shows a test and stub that came from this process:
====
[source,java,indent=0,subs="verbatim,attributes",role="primary"]
.test
----
@Test
public void validate_shouldMarkClientAsFraud() throws Exception {
// given:
MockMvcRequestSpecification request = given()
.header("Content-Type", "application/vnd.fraud.v1+json")
.body("{\"clientId\":\"1234567890\",\"loanAmount\":99999}");
// when:
ResponseOptions response = given().spec(request)
.put("/fraudcheck");
// then:
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.header("Content-Type")).matches("application/vnd\\.fraud\\.v1\\+json.*");
// and:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).field("['rejectionReason']").isEqualTo("Amount too high");
// and:
assertThat(parsedJson.read("$.fraudCheckStatus", String.class)).matches("FRAUD");
}
----
[source,json,indent=0,subs="verbatim,attributes",role="secondary"]
.stub
----
{
"id" : "996ae5ae-6834-4db6-8fac-358ca187ab62",
"uuid" : "996ae5ae-6834-4db6-8fac-358ca187ab62",
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"headers" : {
"Content-Type" : {
"matches" : "application/vnd\\.fraud\\.v1\\+json.*"
}
},
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.['loanAmount'] = 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId =~ /([0-9]{10})/)]"
} ]
},
"response" : {
"status" : 200,
"body" : "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json;charset=UTF-8"
},
"transformers" : [ "response-template" ]
},
}
----
====
[[how-to-use-pact-broker-pact-consumers]]
=== Pact for Consumers
On the consumer side, you must add two additional dependencies to your project
dependencies. One is the Spring Cloud Contract Pact support, and the other represents the
current Pact version that you use. The following listing shows how to do so for both
Maven and Gradle:
====
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
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}/consumer_pact_stubrunner/build.gradle[tags=pact_dependency,indent=0]
----
====
[[pact-stub-downloader]]
=== Communicating with the Pact Broker
Whenever the `repositoryRoot` property starts with a Pact protocol
(that is, starts with `pact://`), the stub downloader tries
to fetch the Pact contract definitions from the Pact Broker.
Whatever is set after `pact://` is parsed as the Pact Broker URL.
By setting environment variables, system properties, or properties set
inside the plugin or contracts repository configuration, you can
tweak the downloader's behavior. The following table describes the
properties:
.Pact Stub Downloader properties
|====
|Name of a property |Default | Description
|
* `pactbroker.host` (plugin prop)
* `stubrunner.properties.pactbroker.host` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_HOST` (env prop)
|Host from URL passed to `repositoryRoot`
|The URL of the Pact Broker.
|
* `pactbroker.port` (plugin prop)
* `stubrunner.properties.pactbroker.port` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_PORT` (env prop)
|Port from URL passed to `repositoryRoot`
|The port of Pact Broker.
|
* `pactbroker.protocol` (plugin prop)
* `stubrunner.properties.pactbroker.protocol` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_PROTOCOL` (env prop)
|Protocol from URL passed to `repositoryRoot`
|The protocol of Pact Broker.
|
* `pactbroker.tags` (plugin prop)
* `stubrunner.properties.pactbroker.tags` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_TAGS` (env prop)
|Version of the stub, or `latest` if version is `+`
|The tags that should be used to fetch the stub.
|
* `pactbroker.auth.scheme` (plugin prop)
* `stubrunner.properties.pactbroker.auth.scheme` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_SCHEME` (env prop)
|`Basic`
|The kind of authentication that should be used to connect to the Pact Broker.
|
* `pactbroker.auth.username` (plugin prop)
* `stubrunner.properties.pactbroker.auth.username` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_USERNAME` (env prop)
|The username passed to `contractsRepositoryUsername` (Maven) or `contractRepository.username` (Gradle)
|The username to use when connecting to the Pact Broker.
|
* `pactbroker.auth.password` (plugin prop)
* `stubrunner.properties.pactbroker.auth.password` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_PASSWORD` (env prop)
|The password passed to `contractsRepositoryPassword` (Maven) or `contractRepository.password` (Gradle)
|The password to use when connecting to the Pact Broker.
|
* `pactbroker.provider-name-with-group-id` (plugin prop)
* `stubrunner.properties.pactbroker.provider-name-with-group-id` (system prop)
* `STUBRUNNER_PROPERTIES_PACTBROKER_PROVIDER_NAME_WITH_GROUP_ID` (env prop)
|false
|When `true`, the provider name is a combination of `groupId:artifactId`. If `false`, only `artifactId` is used.
|====
[[how-to-pact-consumer]]
=== Flow: Consumer Contract Approach with Pact Broker on the Consumer Side
The consumer uses the Pact framework to generate Pact files. The
Pact files are sent to the Pact Broker. You can find an example of such a setup
https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/consumer_pact[here].
[[how-to-pact-producer]]
=== Flow: Consumer Contract Approach with Pact Broker on the Producer Side
For the producer to use the Pact files from the Pact Broker, we can reuse the
same mechanism we use for external contracts. We route Spring Cloud Contract
to use the Pact implementation with the URL that contains
the `pact://` protocol. You can pass the URL to the
Pact Broker. You can find an example of such a setup
https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/producer_pact[here].
The following listing shows the configuration details for both Maven and Gradle:
====
[source,xml,indent=0,role="primary"]
.Maven
----
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration>
<!-- Base class mappings etc. -->
<!-- We want to pick contracts from a Git repository -->
<contractsRepositoryUrl>pact://http://localhost:8085</contractsRepositoryUrl>
<!-- We reuse the contract dependency section to set up the path
to the folder that contains the contract definitions. In our case the
path will be /groupId/artifactId/version/contracts -->
<contractDependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<!-- When + is passed, a latest tag will be applied when fetching pacts -->
<version>+</version>
</contractDependency>
<!-- The contracts mode can't be classpath -->
<contractsMode>REMOTE</contractsMode>
</configuration>
<!-- Don't forget to add spring-cloud-contract-pact to the classpath! -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-pact</artifactId>
<version>${spring-cloud-contract.version}</version>
</dependency>
</dependencies>
</plugin>
----
[source,groovy,indent=0,role="secondary"]
.Gradle
----
buildscript {
repositories {
//...
}
dependencies {
// ...
// Don't forget to add spring-cloud-contract-pact to the classpath!
classpath "org.springframework.cloud:spring-cloud-contract-pact:${contractVersion}"
}
}
contracts {
// When + is passed, a latest tag will be applied when fetching pacts
contractDependency {
stringNotation = "${project.group}:${project.name}:+"
}
contractRepository {
repositoryUrl = "pact://http://localhost:8085"
}
// The mode can't be classpath
contractsMode = "REMOTE"
// Base class mappings etc.
}
----
====
With such a setup:
* Pact files are downloaded from the Pact Broker.
* Spring Cloud Contract converts the Pact files into tests and stubs.
* The JAR with the stubs gets automatically created, as usual.
[[how-to-pact-consumer-producer-contract]]
=== Flow: Producer Contract Approach with Pact on the Consumer Side
In the scenario where you do not want to do the consumer contract approach
(for every single consumer, define the expectations) but you prefer
to do producer contracts (the producer provides the contracts and
publishes stubs), you can use Spring Cloud Contract with the
Stub Runner option. You can find an example of such a setup
https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/consumer_pact_stubrunner[here].
Remember to add the Stub Runner and Spring Cloud Contract Pact modules
as test dependencies.
The following listing shows the configuration details for both Maven and Gradle:
====
[source,xml,indent=0,role="primary"]
.Maven
----
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Don't forget to add spring-cloud-contract-pact to the classpath! -->
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-pact</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
----
[source,groovy,indent=0,role="secondary"]
.Gradle
----
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
//...
testCompile("org.springframework.cloud:spring-cloud-starter-contract-stub-runner")
// Don't forget to add spring-cloud-contract-pact to the classpath!
testCompile("org.springframework.cloud:spring-cloud-contract-pact")
}
----
====
Next, you can pass the URL of the Pact Broker to `repositoryRoot`, prefixed
with the `pact://` protocol (for example, `pact://http://localhost:8085`), as the following
example shows:
====
[source,java,indent=0]
----
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureStubRunner(stubsMode = StubRunnerProperties.StubsMode.REMOTE,
ids = "com.example:beer-api-producer-pact",
repositoryRoot = "pact://http://localhost:8085")
public class BeerControllerTest {
//Inject the port of the running stub
@StubRunnerPort("beer-api-producer-pact") int producerPort;
//...
}
----
====
With such a setup:
* Pact files are downloaded from the Pact Broker.
* Spring Cloud Contract converts the Pact files into stub definitions.
* The stub servers are started and fed with stubs.
[[how-to-debug]]
== How Can I Debug the Request/Response Being Sent by the Generated Tests Client?

View File

@@ -14,5 +14,5 @@ The reference documentation consists of the following sections:
<<using.adoc#using,Using {project-full-name}>> :: {project-full-name} usage examples and workflows.
<<project-features.adoc#features,{project-full-name} Features>> :: Contract DSL, Messaging, Spring Cloud Contract Stub Runner, and Spring Cloud Contract WireMock.
<<project-features.adoc#features-build-tools,Build Tools>> :: Maven Plugin, Gradle Plugin, and Docker.
<<howto.adoc#howto,"`How-to`" Guides>> :: Stubs versioning, Pact integration, Debugging, and more.
<<howto.adoc#howto,"`How-to`" Guides>> :: Stubs versioning, Debugging, and more.
<<appendix.adoc#appendix,Appendices>> :: Properties, Metadata, Configuration, Dependencies, and more.