471 lines
55 KiB
HTML
471 lines
55 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>95. Using the Pluggable Architecture</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud.html" title="Spring Cloud"><link rel="up" href="multi__spring_cloud_contract.html" title="Part XIII. Spring Cloud Contract"><link rel="prev" href="multi__customization.html" title="94. Customization"><link rel="next" href="multi__spring_cloud_contract_wiremock.html" title="96. Spring Cloud Contract WireMock"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">95. Using the Pluggable Architecture</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__customization.html">Prev</a> </td><th width="60%" align="center">Part XIII. Spring Cloud Contract</th><td width="20%" align="right"> <a accesskey="n" href="multi__spring_cloud_contract_wiremock.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_using_the_pluggable_architecture" href="#_using_the_pluggable_architecture"></a>95. Using the Pluggable Architecture</h2></div></div></div><p>You may encounter cases where you have your contracts have been defined in other formats,
|
|
such as YAML, RAML or PACT. In those cases, you still want to benefit from the automatic
|
|
generation of tests and stubs. You can add your own implementation for generating both
|
|
tests and stubs. Also, you can customize the way tests are generated (for example, you
|
|
can generate tests for other languages) and the way stubs are generated (for example, you
|
|
can generate stubs for other HTTP server implementations).</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_custom_contract_converter" href="#_custom_contract_converter"></a>95.1 Custom Contract Converter</h2></div></div></div><p>The <code class="literal">ContractConverter</code> interface lets you register your own implementation of a contract
|
|
structure converter. The following code listing shows the <code class="literal">ContractConverter</code> interface:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> org.springframework.cloud.contract.spec
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Converter to be used to convert FROM {@link File} TO {@link Contract}
|
|
* and from {@link Contract} to {@code T}
|
|
*
|
|
* @param <T > - type to which we want to convert the contract
|
|
*
|
|
* @author Marcin Grzejszczak
|
|
* @since 1.1.0
|
|
*/</strong>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">interface</span> ContractConverter<T> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">extends</span> ContractStorer<T> {
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Should this file be accepted by the converter. Can use the file extension
|
|
* to check if the conversion is possible.
|
|
*
|
|
* @param file - file to be considered for conversion
|
|
* @return - {@code true} if the given implementation can convert the file
|
|
*/</strong>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">boolean</span> isAccepted(File file)
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Converts the given {@link File} to its {@link Contract} representation
|
|
*
|
|
* @param file - file to convert
|
|
* @return - {@link Contract} representation of the file
|
|
*/</strong>
|
|
Collection<Contract> convertFrom(File file)
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Converts the given {@link Contract} to a {@link T} representation
|
|
*
|
|
* @param contract - the parsed contract
|
|
* @return - {@link T} the type to which we do the conversion
|
|
*/</strong>
|
|
T convertTo(Collection<Contract> contract)
|
|
}</pre><p>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.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>Once you create your implementation, you must create a
|
|
<code class="literal">/META-INF/spring.factories</code> file in which you provide the fully qualified name of your
|
|
implementation.</p></td></tr></table></div><p>The following example shows a typical <code class="literal">spring.factories</code> file:</p><pre class="screen">org.springframework.cloud.contract.spec.ContractConverter=\
|
|
org.springframework.cloud.contract.verifier.converter.YamlContractConverter</pre><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="pact-converter" href="#pact-converter"></a>95.1.1 Pact Converter</h3></div></div></div><p>Spring Cloud Contract includes support for <a class="link" href="https://docs.pact.io/" target="_top">Pact</a> representation of
|
|
contracts up until v4. Instead of using the Groovy DSL, you can use Pact files. In this section, we
|
|
present how to add Pact support for your project. Note however that not all functionality is supported.
|
|
Starting with v3 you can combine multiple matcher 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 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 will be skipped and the ISO format will be used.</p><p>In order to properly support the Spring Cloud Contract way of doing messaging
|
|
with Pact you’ll have to provide some additional meta data entries. Below you can find a list of such entries:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">to define the destination to which a message gets sent, you have to
|
|
set a <code class="literal">metaData</code> entry in the Pact file, with key <code class="literal">sentTo</code> equal to the destination to which a message is to be sent. E.g. <code class="literal">"metaData": { "sentTo": "activemq:output" }</code></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_pact_contract" href="#_pact_contract"></a>95.1.2 Pact Contract</h3></div></div></div><p>Consider following example of a Pact contract, which is a file under the
|
|
<code class="literal">src/test/resources/contracts</code> folder.</p><pre class="programlisting">{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"provider"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"name"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Provider"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"consumer"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"name"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Consumer"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"interactions"</span>: [
|
|
{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"description"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">""</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"request"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"method"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"PUT"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"path"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/fraudcheck"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd.fraud.v1+json"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"clientId"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"1234567890"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"loanAmount"</span>: <span class="hl-number">99999</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"generators"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.clientId"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"type"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Regex"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-9]{10}"</span>
|
|
}
|
|
}
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchingRules"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"header"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchers"</span>: [
|
|
{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"match"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd\\.fraud\\.v1\\+json.*"</span>
|
|
}
|
|
],
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"combine"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AND"</span>
|
|
}
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.clientId"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchers"</span>: [
|
|
{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"match"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-9]{10}"</span>
|
|
}
|
|
],
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"combine"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AND"</span>
|
|
}
|
|
}
|
|
}
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"response"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span>: <span class="hl-number">200</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd.fraud.v1+json;charset=UTF-8"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"fraudCheckStatus"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"FRAUD"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"rejectionReason"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Amount too high"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchingRules"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"header"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchers"</span>: [
|
|
{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"match"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd\\.fraud\\.v1\\+json.*"</span>
|
|
}
|
|
],
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"combine"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AND"</span>
|
|
}
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.fraudCheckStatus"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchers"</span>: [
|
|
{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"match"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"regex"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"FRAUD"</span>
|
|
}
|
|
],
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"combine"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"AND"</span>
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"metadata"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"pact-specification"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"version"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"3.0.0"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"pact-jvm"</span>: {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"version"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"3.5.13"</span>
|
|
}
|
|
}
|
|
}</pre><p>The remainder of this section about using Pact refers to the preceding file.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_pact_for_producers" href="#_pact_for_producers"></a>95.1.3 Pact for Producers</h3></div></div></div><p>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.</p><p class="primary"><b>Maven. </b>
|
|
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugin></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-contract-maven-plugin<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${spring-cloud-contract.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><extensions></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></extensions></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><packageWithBaseClasses></span>com.example.fraud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></packageWithBaseClasses></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependencies></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-contract-pact<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${spring-cloud-contract.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependencies></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><p class="primary">
|
|
</p><p class="secondary"><b>Gradle. </b>
|
|
</p><pre class="programlisting">classpath <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"org.springframework.cloud:spring-cloud-contract-pact:${findProperty('verifierVersion') ?: verifierVersion}"</span></pre><p class="secondary">
|
|
</p><p>When you execute the build of your application, a test will be generated. The generated
|
|
test might be as follows:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Test</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> validate_shouldMarkClientAsFraud() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// given:</span>
|
|
MockMvcRequestSpecification request = given()
|
|
.header(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd.fraud.v1+json"</span>)
|
|
.body(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"{\"clientId\":\"1234567890\",\"loanAmount\":99999}"</span>);
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// when:</span>
|
|
ResponseOptions response = given().spec(request)
|
|
.put(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/fraudcheck"</span>);
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// then:</span>
|
|
assertThat(response.statusCode()).isEqualTo(<span class="hl-number">200</span>);
|
|
assertThat(response.header(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>)).matches(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd\\.fraud\\.v1\\+json.*"</span>);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// and:</span>
|
|
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
|
|
assertThatJson(parsedJson).field(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"['rejectionReason']"</span>).isEqualTo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Amount too high"</span>);
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// and:</span>
|
|
assertThat(parsedJson.read(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.fraudCheckStatus"</span>, String.<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span>)).matches(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"FRAUD"</span>);
|
|
}</pre><p>The corresponding generated stub might be as follows:</p><pre class="programlisting">{
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"id"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"996ae5ae-6834-4db6-8fac-358ca187ab62"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"uuid"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"996ae5ae-6834-4db6-8fac-358ca187ab62"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"request"</span> : {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"url"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/fraudcheck"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"method"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"PUT"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matches"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd\\.fraud\\.v1\\+json.*"</span>
|
|
}
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"bodyPatterns"</span> : [ {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.['loanAmount'] == 99999)]"</span>
|
|
}, {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.clientId =~ /([0-9]{10})/)]"</span>
|
|
} ]
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"response"</span> : {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span> : <span class="hl-number">200</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}"</span>,
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/vnd.fraud.v1+json;charset=UTF-8"</span>
|
|
},
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"transformers"</span> : [ <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"response-template"</span> ]
|
|
},
|
|
}</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_pact_for_consumers" href="#_pact_for_consumers"></a>95.1.4 Pact for Consumers</h3></div></div></div><p>On the producer 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.</p><p class="primary"><b>Maven. </b>
|
|
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-contract-pact<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><scope></span>test<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></scope></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre><p class="primary">
|
|
</p><p class="secondary"><b>Gradle. </b>
|
|
</p><pre class="programlisting">testCompile <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"org.springframework.cloud:spring-cloud-contract-pact"</span></pre><p class="secondary">
|
|
</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_the_custom_test_generator" href="#_using_the_custom_test_generator"></a>95.2 Using the Custom Test Generator</h2></div></div></div><p>If you want to generate tests for languages other than Java or you are not happy with the
|
|
way the verifier builds Java tests, you can register your own implementation.</p><p>The <code class="literal">SingleTestGenerator</code> interface lets you register your own implementation. The
|
|
following code listing shows the <code class="literal">SingleTestGenerator</code> interface:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> org.springframework.cloud.contract.verifier.builder
|
|
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.verifier.file.ContractMetadata
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Builds a single test.
|
|
*
|
|
* @since 1.1.0
|
|
*/</strong>
|
|
trait SingleTestGenerator {
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Creates contents of a single test class in which all test scenarios from
|
|
* the contract metadata should be placed.
|
|
*
|
|
* @param properties - properties passed to the plugin
|
|
* @param listOfFiles - list of parsed contracts with additional metadata
|
|
* @param className - the name of the generated test class
|
|
* @param classPackage - the name of the package in which the test class should be stored
|
|
* @param includedDirectoryRelativePath - relative path to the included directory
|
|
* @return contents of a single test class
|
|
* @deprecated use{@link SingleTestGenerator#buildClass(ContractVerifierConfigProperties, Collection, String, GeneratedClassData)}
|
|
*/</strong>
|
|
<em><span class="hl-annotation" style="color: gray">@Deprecated</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">abstract</span> String buildClass(ContractVerifierConfigProperties properties,
|
|
Collection<ContractMetadata> listOfFiles, String className, String classPackage, String includedDirectoryRelativePath)
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Creates contents of a single test class in which all test scenarios from
|
|
* the contract metadata should be placed.
|
|
*
|
|
* @param properties - properties passed to the plugin
|
|
* @param listOfFiles - list of parsed contracts with additional metadata
|
|
* @param generatedClassData - information about the generated class
|
|
* @param includedDirectoryRelativePath - relative path to the included directory
|
|
* @return contents of a single test class
|
|
*/</strong>
|
|
String buildClass(ContractVerifierConfigProperties properties,
|
|
Collection<ContractMetadata> listOfFiles, String includedDirectoryRelativePath, GeneratedClassData generatedClassData) {
|
|
String className = generatedClassData.className
|
|
String classPackage = generatedClassData.classPackage
|
|
String path = includedDirectoryRelativePath
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> buildClass(properties, listOfFiles, className, classPackage, path)
|
|
}
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Extension that should be appended to the generated test class. E.g. {@code .java} or {@code .php}
|
|
*
|
|
* @param properties - properties passed to the plugin
|
|
*/</strong>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">abstract</span> String fileExtension(ContractVerifierConfigProperties properties)
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> GeneratedClassData {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> String className
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> String classPackage
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> java.nio.file.Path testClassPath
|
|
|
|
GeneratedClassData(String className, String classPackage,
|
|
java.nio.file.Path testClassPath) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.className = className
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.classPackage = classPackage
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.testClassPath = testClassPath
|
|
}
|
|
}
|
|
}</pre><p>Again, you must provide a <code class="literal">spring.factories</code> file, such as the one shown in the following
|
|
example:</p><pre class="screen">org.springframework.cloud.contract.verifier.builder.SingleTestGenerator=/
|
|
com.example.MyGenerator</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_the_custom_stub_generator" href="#_using_the_custom_stub_generator"></a>95.3 Using the Custom Stub Generator</h2></div></div></div><p>If you want to generate stubs for stub servers other than WireMock, you can plug in your
|
|
own implementation of the <code class="literal">StubGenerator</code> interface. The following code listing shows the
|
|
<code class="literal">StubGenerator</code> interface:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> org.springframework.cloud.contract.verifier.converter
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> groovy.transform.CompileStatic
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.spec.Contract
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.verifier.file.ContractMetadata
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* Converts contracts into their stub representation.
|
|
*
|
|
* @since 1.1.0
|
|
*/</strong>
|
|
<em><span class="hl-annotation" style="color: gray">@CompileStatic</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">interface</span> StubGenerator {
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* @return {@code true} if the converter can handle the file to convert it into a stub.
|
|
*/</strong>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">boolean</span> canHandleFileName(String fileName)
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* @return the collection of converted contracts into stubs. One contract can
|
|
* result in multiple stubs.
|
|
*/</strong>
|
|
Map<Contract, String> convertContents(String rootName, ContractMetadata content)
|
|
|
|
<strong class="hl-tag" style="color: blue">/**
|
|
* @return the name of the converted stub file. If you have multiple contracts
|
|
* in a single file then a prefix will be added to the generated file. If you
|
|
* provide the {@link Contract#name} field then that field will override the
|
|
* generated file name.
|
|
*
|
|
* Example: name of file with 2 contracts is {@code foo.groovy}, it will be
|
|
* converted by the implementation to {@code foo.json}. The recursive file
|
|
* converter will create two files {@code 0_foo.json} and {@code 1_foo.json}
|
|
*/</strong>
|
|
String generateOutputFileNameForInput(String inputFileName)
|
|
}</pre><p>Again, you must provide a <code class="literal">spring.factories</code> file, such as the one shown in the following
|
|
example:</p><pre class="screen"># Stub converters
|
|
org.springframework.cloud.contract.verifier.converter.StubGenerator=\
|
|
org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter</pre><p>The default implementation is the WireMock stub generation.</p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>You can provide multiple stub generator implementations. For example, from a single
|
|
DSL, you can produce both WireMock stubs and Pact files.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_the_custom_stub_runner" href="#_using_the_custom_stub_runner"></a>95.4 Using the Custom Stub Runner</h2></div></div></div><p>If you decide to use a custom stub generation, you also need a custom way of running
|
|
stubs with your different stub provider.</p><p>Assume that you use <a class="link" href="https://github.com/dreamhead/moco" target="_top">Moco</a> to build your stubs and that
|
|
you have written a stub generator and placed your stubs in a JAR file.</p><p>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:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> org.springframework.cloud.contract.stubrunner.provider.moco
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> com.github.dreamhead.moco.bootstrap.arg.HttpArgs
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> com.github.dreamhead.moco.runner.JsonRunner
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> com.github.dreamhead.moco.runner.RunnerSetting
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> groovy.util.logging.Commons
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.stubrunner.HttpServerStub
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.util.SocketUtils
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Commons</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> MocoHttpServerStub <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> HttpServerStub {
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">boolean</span> started
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> JsonRunner runner
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">int</span> port
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">int</span> port() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">if</span> (!isRunning()) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> -<span class="hl-number">1</span>
|
|
}
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> port
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">boolean</span> isRunning() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> started
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
HttpServerStub start() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> start(SocketUtils.findAvailableTcpPort())
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
HttpServerStub start(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">int</span> port) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.port = port
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
HttpServerStub stop() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">if</span> (!isRunning()) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>
|
|
}
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.runner.stop()
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
HttpServerStub registerMappings(Collection<File> stubFiles) {
|
|
List<RunnerSetting> settings = stubFiles.findAll { it.name.endsWith(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"json"</span>) }
|
|
.collect {
|
|
log.info(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Trying to parse [${it.name}]"</span>)
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">try</span> {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> RunnerSetting.aRunnerSetting().withStream(it.newInputStream()).
|
|
build()
|
|
}
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">catch</span> (Exception e) {
|
|
log.warn(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Exception occurred while trying to parse file [${it.name}]"</span>, e)
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> null
|
|
}
|
|
}.findAll { it }
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.runner = JsonRunner.newJsonRunnerWithSetting(settings,
|
|
HttpArgs.httpArgs().withPort(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.port).build())
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.runner.run()
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.started = true
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
String registeredMappings() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">""</span>
|
|
}
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">boolean</span> isAccepted(File file) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> file.name.endsWith(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">".json"</span>)
|
|
}
|
|
}</pre><p>Then, you can register it in your <code class="literal">spring.factories</code> file, as shown in the following
|
|
example:</p><pre class="screen">org.springframework.cloud.contract.stubrunner.HttpServerStub=\
|
|
org.springframework.cloud.contract.stubrunner.provider.moco.MocoHttpServerStub</pre><p>Now you can run stubs with Moco.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>If you do not provide any implementation, then the default (WireMock)
|
|
implementation is used. If you provide more than one, the first one on the list is used.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_the_custom_stub_downloader" href="#_using_the_custom_stub_downloader"></a>95.5 Using the Custom Stub Downloader</h2></div></div></div><p>You can customize the way your stubs are downloaded by creating an implementation of the
|
|
<code class="literal">StubDownloaderBuilder</code> interface, as shown in the following example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> com.example;
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomStubDownloaderBuilder <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> StubDownloaderBuilder {
|
|
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> StubDownloader build(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> StubRunnerOptions stubRunnerOptions) {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> StubDownloader() {
|
|
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Map.Entry<StubConfiguration, File> downloadAndUnpackStubJar(
|
|
StubConfiguration config) {
|
|
File unpackedStubs = retrieveStubs();
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> AbstractMap.SimpleEntry<>(
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> StubConfiguration(config.getGroupId(), config.getArtifactId(), version,
|
|
config.getClassifier()), unpackedStubs);
|
|
}
|
|
|
|
File retrieveStubs() {
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// here goes your custom logic to provide a folder where all the stubs reside</span>
|
|
}
|
|
}</pre><p>Then you can register it in your <code class="literal">spring.factories</code> file, as shown in the following
|
|
example:</p><pre class="screen"># Example of a custom Stub Downloader Provider
|
|
org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder=\
|
|
com.example.CustomStubDownloaderBuilder</pre><p>Now you can pick a folder with the source of your stubs.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>If you do not provide any implementation, then the default is used (scan classpath).
|
|
If you provide the <code class="literal">stubsMode = StubRunnerProperties.StubsMode.LOCAL</code> or
|
|
<code class="literal">, stubsMode = StubRunnerProperties.StubsMode.REMOTE</code> then the Aether implementation will be used
|
|
If you provide more than one, then the first one on the list is used.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="scm-stub-downloader" href="#scm-stub-downloader"></a>95.6 Using the SCM Stub Downloader</h2></div></div></div><p>Whenever the <code class="literal">repositoryRoot</code> starts with a SCM protocol
|
|
(currently we support only <code class="literal">git://</code>), the stub downloader will try
|
|
to clone the repository and use it as a source of contracts
|
|
to generate tests or stubs.</p><p>Either via environment variables, system properties, properties set
|
|
inside the plugin or contracts repository configuration you can
|
|
tweak the downloader’s behaviour. Below you can find the list of
|
|
properties</p><div class="table"><a name="d0e28938" href="#d0e28938"></a><p class="title"><b>Table 95.1. SCM Stub Downloader properties</b></p><div class="table-contents"><table class="table" summary="SCM Stub Downloader properties" style="border-collapse: collapse;border-top: 1px solid ; border-bottom: 1px solid ; "><colgroup><col class="col_1"><col class="col_2"><col class="col_3"></colgroup><tbody><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Type of a property</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Name of the property</p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Description</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">git.branch</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.git.branch</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_GIT_BRANCH</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>master</p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Which branch to checkout</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">git.username</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.git.username</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_GIT_USERNAME</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"> </td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Git clone username</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">git.password</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.git.password</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_GIT_PASSWORD</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"> </td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Git clone password</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">git.no-of-attempts</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.git.no-of-attempts</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_GIT_NO_OF_ATTEMPTS</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>10</p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Number of attempts to push the commits to <code class="literal">origin</code></p></td></tr><tr><td style="border-right: 1px solid ; " align="left" valign="top"><p>* <code class="literal">git.wait-between-attempts</code> (Plugin prop)</p><p>* <code class="literal">stubrunner.properties.git.wait-between-attempts</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_GIT_WAIT_BETWEEN_ATTEMPTS</code> (env prop)</p></td><td style="border-right: 1px solid ; " align="left" valign="top"><p>1000</p></td><td style="" align="left" valign="top"><p>Number of millis to wait between attempts to push the commits to <code class="literal">origin</code></p></td></tr></tbody></table></div></div><br class="table-break"></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pact-stub-downloader" href="#pact-stub-downloader"></a>95.7 Using the Pact Stub Downloader</h2></div></div></div><p>Whenever the <code class="literal">repositoryRoot</code> starts with a Pact protocol
|
|
(starts with <code class="literal">pact://</code>), the stub downloader will try
|
|
to fetch the Pact contract definitions from the Pact Broker.
|
|
Whatever is set after <code class="literal">pact://</code> will be parsed as the Pact Broker URL.</p><p>Either via environment variables, system properties, properties set
|
|
inside the plugin or contracts repository configuration you can
|
|
tweak the downloader’s behaviour. Below you can find the list of
|
|
properties</p><div class="table"><a name="d0e29087" href="#d0e29087"></a><p class="title"><b>Table 95.2. SCM Stub Downloader properties</b></p><div class="table-contents"><table class="table" summary="SCM Stub Downloader properties" style="border-collapse: collapse;border-top: 1px solid ; border-bottom: 1px solid ; "><colgroup><col class="col_1"><col class="col_2"><col class="col_3"></colgroup><tbody><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Name of a property</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Default</p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Description</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.host</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.host</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_HOST</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Host from URL passed to <code class="literal">repositoryRoot</code></p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>What is the URL of Pact Broker</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.port</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.port</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_PORT</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Port from URL passed to <code class="literal">repositoryRoot</code></p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>What is the port of Pact Broker</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.protocol</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.protocol</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_PROTOCOL</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Protocol from URL passed to <code class="literal">repositoryRoot</code></p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>What is the protocol of Pact Broker</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.tags</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.tags</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_TAGS</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>Version of the stub, or <code class="literal">latest</code> if version is <code class="literal">+</code></p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>What tags should be used to fetch the stub</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.auth.scheme</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.auth.scheme</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_SCHEME</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p><code class="literal">Basic</code></p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>What kind of authentication should be used to connect to the Pact Broker</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.auth.username</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.auth.username</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_USERNAME</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>The username passed to <code class="literal">contractsRepositoryUsername</code> (maven) or <code class="literal">contractRepository.username</code> (gradle)</p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Username used to connect to the Pact Broker</p></td></tr><tr><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.auth.password</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.auth.password</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_AUTH_PASSWORD</code> (env prop)</p></td><td style="border-right: 1px solid ; border-bottom: 1px solid ; " align="left" valign="top"><p>The password passed to <code class="literal">contractsRepositoryPassword</code> (maven) or <code class="literal">contractRepository.password</code> (gradle)</p></td><td style="border-bottom: 1px solid ; " align="left" valign="top"><p>Password used to connect to the Pact Broker</p></td></tr><tr><td style="border-right: 1px solid ; " align="left" valign="top"><p>* <code class="literal">pactbroker.provider-name-with-group-id</code> (plugin prop)</p><p>* <code class="literal">stubrunner.properties.pactbroker.provider-name-with-group-id</code> (system prop)</p><p>* <code class="literal">STUBRUNNER_PROPERTIES_PACTBROKER_PROVIDER_NAME_WITH_GROUP_ID</code> (env prop)</p></td><td style="border-right: 1px solid ; " align="left" valign="top"><p>false</p></td><td style="" align="left" valign="top"><p>When <code class="literal">true</code>, the provider name will be a combination of <code class="literal">groupId:artifactId</code>. If <code class="literal">false</code>, just <code class="literal">artifactId</code> is used</p></td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__customization.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="multi__spring_cloud_contract.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="multi__spring_cloud_contract_wiremock.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">94. Customization </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud.html">Home</a></td><td width="40%" align="right" valign="top"> 96. Spring Cloud Contract WireMock</td></tr></table></div></body></html> |