diff --git a/README.adoc b/README.adoc
index f14bd5a373..d9a4b94803 100644
--- a/README.adoc
+++ b/README.adoc
@@ -39,7 +39,7 @@ produced by Spring Cloud Contract Verifier.
* Messaging routes, if you're using a messaging service. We integrate with Spring
Integration, Spring Cloud Stream, Spring AMQP, and Apache Camel. You can also set your
own integrations.
-* Acceptance tests (in JUnit or Spock) are used to verify if server-side implementation
+* Acceptance tests (in JUnit 4, JUnit 5 or Spock) are used to verify if server-side implementation
of the API is compliant with the contract (__server tests__). A full test is generated by
Spring Cloud Contract Verifier.
@@ -401,8 +401,8 @@ mode for HTTP contracts. However, JAX-RX client and explicit HTTP invocations ca
used. (To do so, change the `testMode` property of the plugin to `JAX-RS` or `EXPLICIT`,
respectively.)
-Apart from the default JUnit, you can instead use Spock tests, by setting the plugin
-`testFramework` property to `Spock`.
+Apart from the default JUnit 4, you can instead use JUnit 5 or Spock tests, by setting the plugin
+`testFramework` property to either `JUNIT5` or `Spock`.
TIP: You can now also generate WireMock scenarios based on the contracts, by including an
order number followed by an underscore at the beginning of the contract file names.
diff --git a/docs/src/main/asciidoc/verifier_faq.adoc b/docs/src/main/asciidoc/verifier_faq.adoc
index aaa23793b6..504d44006e 100644
--- a/docs/src/main/asciidoc/verifier_faq.adoc
+++ b/docs/src/main/asciidoc/verifier_faq.adoc
@@ -344,84 +344,10 @@ contracts in the folder per topic.
===== For Maven Project
-To make it possible to work on the producer side we could do the following things (all via Maven plugins):
+To make it possible to work on the producer side we should specify an inclusion pattern for
+filtering common repository jar by messaging topics we are interested in. ```includedFiles``` property of ```Maven Spring Cloud Contract plugin```
+allows us to do that. Also ```contractsPath``` need to be specified since the default path would be the common repository ```groupid/artifactid```.
-- Add common repo dependency to your classpath:
-
-[source,xml,indent=0]
-----
-
- com.example
- common-repo
- ${common-repo.version}
-
-----
-
-- Download the JAR with the contracts and unpack the JAR to target:
-
-[source,xml,indent=0]
-----
-
- org.apache.maven.plugins
- maven-dependency-plugin
- 3.0.0
-
-
- unpack-dependencies
- process-resources
-
- unpack
-
-
-
-
- com.example
- common-repo
- jar
- false
- ${project.build.directory}/contracts
-
-
-
-
-
-
-----
-
-- Rip out all the folders we're not interested in:
-
-[source,xml,indent=0]
-----
-
- org.apache.maven.plugins
- maven-antrun-plugin
- 1.8
-
-
- process-resources
-
- run
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-----
-
-- Run the contract plugin by pointing to the contracts to the folder under target:
[source,xml,indent=0]
----
@@ -429,16 +355,30 @@ To make it possible to work on the producer side we could do the following thing
org.springframework.cloud
spring-cloud-contract-maven-plugin
${spring-cloud-contract.version}
- true
- com.example
+ REMOTE
+ http://link/to/your/nexus/or/artifactory/or/sth
+
+ com.example
+ common-repo-with-contracts
+ +
+
+ /
- .*intoxication.*
- com.example.intoxication.BeerIntoxicationBase
+ .*messaging.*
+ com.example.services.MessagingBase
+
+
+ .*rest.*
+ com.example.services.TestBase
- ${project.build.directory}/contracts
+
+ **/${project.artifactId}/**
+ **/${first-topic}/**
+ **/${second-topic}/**
+
----
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy
index 043002d9c7..1dbfad196b 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy
+++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy
@@ -58,7 +58,7 @@ class RecursiveFilesConverter {
void processFiles() {
ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir,
- properties.excludedFiles as Set, [] as Set, properties.includedContracts)
+ properties.excludedFiles as Set, [] as Set, [] as Set, properties.includedContracts)
ListMultimap contracts = scanner.findContracts()
if (log.isDebugEnabled()) {
log.debug("Found the following contracts $contracts")
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java
index 56ee9826c0..306bb604aa 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java
@@ -98,6 +98,12 @@ public class GenerateTestsMojo extends AbstractMojo {
@Parameter
private List excludedFiles;
+ /**
+ * Patterns that should be taken into account for processing
+ */
+ @Parameter(property = "includedFiles")
+ private List includedFiles;
+
/**
* Incubating feature. You can check the size of JSON arrays. If not turned on
* explicitly will be disabled.
@@ -279,6 +285,7 @@ public class GenerateTestsMojo extends AbstractMojo {
config.setStaticImports(this.staticImports);
config.setIgnoredFiles(this.ignoredFiles);
config.setExcludedFiles(this.excludedFiles);
+ config.setIncludedFiles(this.includedFiles);
config.setAssertJsonSize(this.assertJsonSize);
config.setPackageWithBaseClasses(this.packageWithBaseClasses);
if (this.baseClassMappings != null) {
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java
index 54beac401b..70fa7c69bc 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java
@@ -305,4 +305,19 @@ public class PluginUnitTest {
then(this.capture.toString()).contains("Skipping pushing stubs to scm since your");
}
+
+ @Test
+ public void shouldGenerateContractTestsForIncludedFilesPattern() throws Exception {
+ File basedir = this.resources.getBasedir("complex-common-repo-with-messaging");
+
+ this.maven.executeMojo(basedir, "generateTests", defaultPackageForTests(),
+ newParameter("contractsRepositoryUrl",
+ "file://" + PluginUnitTest.class.getClassLoader()
+ .getResource("m2repo/repository").getFile()
+ .replace("/", File.separator)));
+ assertFilesPresent(basedir,
+ "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/common_repo_with_inclusion/kafka_topics/coupon_sent/src/main/resources/contracts/rule_engine_daemon/MessagingTest.java");
+ assertFilesPresent(basedir,
+ "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/common_repo_with_inclusion/reward_rules/src/main/resources/contracts/reward_rules/rest/admin/V1Test.java");
+ }
}
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml
new file mode 100644
index 0000000000..6c71dbfd26
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/pom.xml
@@ -0,0 +1,61 @@
+
+
+
+ 4.0.0
+
+ com.example
+ social-service
+ 0.1.BUILD-SNAPSHOT
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-contract-maven-plugin
+ 2.0.0.BUILD-SNAPSHOT
+
+ REMOTE
+
+ com.example
+ services-contracts
+ +
+
+ /
+
+
+ .*messaging.*
+ com.example.services.TestBase
+
+
+ .*rest.*
+ com.example.services.TestBase
+
+
+
+ **/coupon-sent/**
+ **/reward-rules/**
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java
new file mode 100644
index 0000000000..0ad45b3dcf
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-common-repo-with-messaging/src/test/java/com/example/services/TestBase.java
@@ -0,0 +1,30 @@
+/**
+ *
+ * Copyright 2013-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.services;
+
+import io.restassured.module.mockmvc.RestAssuredMockMvc;
+
+import org.junit.Before;
+
+public class TestBase {
+
+ @Before
+ public void setup() {
+ RestAssuredMockMvc.standaloneSetup(new FraudDetectionController());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom
new file mode 100644
index 0000000000..1369bcaf20
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/contracts/1.0.4-SNAPSHOT/contracts-0.0.1-SNAPSHOT.pom
@@ -0,0 +1,25 @@
+
+
+
+
+ 4.0.0
+ com.example
+ contracts
+ 0.0.1-SNAPSHOT
+ pom
+
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml
new file mode 100644
index 0000000000..5b45432a6e
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/maven-metadata-local.xml
@@ -0,0 +1,24 @@
+
+
+ com.example
+ services-contracts
+ 1.0.4-SNAPSHOT
+
+
+ true
+
+ 20160916125313
+
+
+ jar
+ 1.0.4-SNAPSHOT
+ 20160916125313
+
+
+ pom
+ 1.0.4-SNAPSHOT
+ 20160916125313
+
+
+
+
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.jar b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.jar
new file mode 100644
index 0000000000..54c268d26c
Binary files /dev/null and b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.jar differ
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom
new file mode 100644
index 0000000000..a807f11aac
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/1.0.4-SNAPSHOT/services-contracts-1.0.4-SNAPSHOT.pom
@@ -0,0 +1,25 @@
+
+
+
+
+ 4.0.0
+ com.example
+ services-contracts
+ 1.0.4-SNAPSHOT
+ pom
+
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml
new file mode 100644
index 0000000000..278b59b02a
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/resources/m2repo/repository/com/example/services-contracts/maven-metadata.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ com.example
+ services-contracts
+ 1.0.4-SNAPSHOT
+
+
+ 1.0.4-SNAPSHOT
+
+ 20160409062112
+
+
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy
index df4ef6d63e..caa431b732 100755
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy
@@ -77,6 +77,7 @@ class TestGenerator {
contractFileScanner = new ContractFileScanner(configProperties.contractsDslDir,
configProperties.excludedFiles as Set,
configProperties.ignoredFiles as Set,
+ configProperties.includedFiles as Set,
this.configProperties.includedContracts)
}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy
index 7093690e8f..60985f17ac 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy
@@ -60,6 +60,11 @@ class ContractVerifierConfigProperties {
*/
List excludedFiles = []
+ /**
+ * Patterns that should be taken into account for processing
+ */
+ List includedFiles = []
+
/**
* Patterns for which generated tests should be @Ignored
*/
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy
index be2c4383ed..34d7591a6a 100755
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy
@@ -52,12 +52,16 @@ class ContractFileScanner {
private final File baseDir
private final Set excludeMatchers
private final Set ignoreMatchers
+ private final Set includeMatchers
private final String includeMatcher
- ContractFileScanner(File baseDir, Set excluded, Set ignored, String includeMatcher = "") {
+ ContractFileScanner(File baseDir, Set excluded, Set ignored,
+ Set included = [],
+ String includeMatcher = "") {
this.baseDir = baseDir
this.excludeMatchers = processPatterns(excluded ?: [] as Set)
this.ignoreMatchers = processPatterns(ignored ?: [] as Set)
+ this.includeMatchers = processPatterns(included ?: [] as Set)
this.includeMatcher = includeMatcher
}
@@ -102,7 +106,8 @@ class ContractFileScanner {
boolean excluded = matchesPattern(file, excludeMatchers)
if (!excluded) {
boolean contractFile = isContractFile(file)
- boolean included = includeMatcher ? file.absolutePath.matches(includeMatcher) : true
+ boolean included = includeMatcher ? file.absolutePath.matches(includeMatcher) : true
+ included = includeMatchers ? matchesPattern(file, includeMatchers) : included
if (contractFile && included) {
addContractToTestGeneration(result, files, file, i, ContractVerifierDslConverter.convertAsCollection(baseDir, file))
} else if (!contractFile && included) {
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy
index 08937ae415..2f0e59df49 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy
@@ -34,7 +34,7 @@ class ContractFileScannerSpec extends Specification {
File baseDir = new File(this.getClass().getResource("/directory/with/stubs").toURI())
Set excluded = ["package/**"] as Set
Set ignored = ["other/different/**"] as Set
- ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored)
+ ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored, [] as Set)
when:
ListMultimap result = scanner.findContracts()
then:
@@ -52,7 +52,7 @@ class ContractFileScannerSpec extends Specification {
File baseDir = new File(this.getClass().getResource("/strange_[3.3.3]_directory").toURI())
Set excluded = ["foo/**"] as Set
Set ignored = ["bar/**"] as Set
- ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored)
+ ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored, [] as Set)
when:
ListMultimap result = scanner.findContracts()
then:
@@ -66,7 +66,7 @@ class ContractFileScannerSpec extends Specification {
def "should find contracts group in scenario"() {
given:
File baseDir = new File(this.getClass().getResource("/directory/with/scenario").toURI())
- ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set)
+ ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set, [] as Set)
when:
ListMultimap contracts = scanner.findContracts()
then:
@@ -80,7 +80,7 @@ class ContractFileScannerSpec extends Specification {
def "should find contract files with converters"() {
given:
File baseDir = new File(this.getClass().getResource("/directory/with/mixed").toURI())
- ContractFileScanner scanner = new ContractFileScanner(baseDir, null, null) {
+ ContractFileScanner scanner = new ContractFileScanner(baseDir, null, null, null) {
@Override
protected List converters() {
return [new ContractConverter() {
@@ -146,4 +146,22 @@ class ContractFileScannerSpec extends Specification {
result.keySet().size() == 1
result.entries().every { it.value.convertedContract }
}
+
+ def "should find contracts for include pattern"() {
+ given:
+ File baseDir = new File(this.getClass().getResource("/directory/with/common-messaging").toURI())
+ Set included = ["social-service/**","**/coupon-collected/**/*V1*"] as Set
+ ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set, included)
+ when:
+ ListMultimap result = scanner.findContracts()
+ then:
+ result.keySet().size() == 3
+ result.values().find { (it.path.fileName.toString() == 'couponCollectedEventV1.groovy') }.groupSize==2
+ result.values().find { (it.convertedContract.first().label == 'couponCollectedV1') }
+ result.values().findAll { (it.path.fileName.toString() == 'couponCollectedEventV2.groovy') }.isEmpty()
+ result.values().find { (it.path.fileName.toString() == 'shouldUpdateUserInfo.groovy') }.groupSize==1
+ result.values().find { (it.path.fileName.toString() == 'shouldReturnEmptyFriendsWhenGetFriends.groovy') }.groupSize==1
+ result.get(baseDir.toPath().resolve("coupon-sent")).size() == 0
+ result.get(baseDir.toPath().resolve("reward-rules")).size() == 0
+ }
}
diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy
new file mode 100644
index 0000000000..b61731fbcf
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV1.groovy
@@ -0,0 +1,27 @@
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+
+ description("""Should send a message in topic coupon_collected""")
+
+ label 'couponCollectedV1'
+
+ input {
+ triggeredBy('couponCollectedSm()')
+ }
+
+ outputMessage {
+ sentTo('coupon_collected')
+
+ body([
+ receiverSnId: value(consumer("receiver-sn-id"), producer(regex('([^\\W]|-)+'))),
+ sessionId: value(consumer(7928568413097907541), producer(regex('\\d+'))),
+ createdTs: value(consumer(1504688949158), producer(regex('\\d+'))),
+ couponToken: value(consumer("440006-6-1504688949139-xyuzzrx5"), producer(regex('([^\\W]|-)+')))
+ ])
+
+ headers {
+ messagingContentType(applicationJsonUtf8())
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy
new file mode 100644
index 0000000000..529f1c93f7
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-collected/src/main/resources/contracts/rule-engine-daemon/messaging/couponCollectedEventV2.groovy
@@ -0,0 +1,27 @@
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+
+ description("""Should send a message in topic coupon_collected""")
+
+ label 'couponCollectedSm'
+
+ input {
+ triggeredBy('couponCollectedSm()')
+ }
+
+ outputMessage {
+ sentTo('coupon_collected')
+
+ body([
+ receiverSnId: value(consumer("receiver-sn-id"), producer(regex('([^\\W]|-)+'))),
+ sessionId: value(consumer(7928568413097907541), producer(regex('\\d+'))),
+ createdTs: value(consumer(1504688949158), producer(regex('\\d+'))),
+ couponToken: value(consumer("440006-6-1504688949139-xyuzzrx5"), producer(regex('([^\\W]|-)+')))
+ ])
+
+ headers {
+ messagingContentType(applicationJsonUtf8())
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy
new file mode 100644
index 0000000000..24772ce212
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/kafka-topics/coupon-sent/src/main/resources/contracts/rule-engine-daemon/messaging/couponSentEventSm.groovy
@@ -0,0 +1,27 @@
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+
+ description("""Should send a message in topic coupon_sent""")
+
+ label 'couponSentSm'
+
+ input {
+ triggeredBy('couponSentSm()')
+ }
+
+ outputMessage {
+ sentTo('coupon_sent')
+
+ body([
+ senderUserId: value(consumer(123), producer(regex('\\d+'))),
+ sessionId: value(consumer(7928568413097907541), producer(regex('\\d+'))),
+ createdTs: value(consumer(1504688949158), producer(regex('\\d+'))),
+ couponToken: value(consumer("440006-6-1504688949139-xyuzzrx5"), producer(regex('([^\\W]|-)+')))
+ ])
+
+ headers {
+ messagingContentType(applicationJsonUtf8())
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy
new file mode 100644
index 0000000000..f70af82308
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/reward-rules/src/main/resources/contracts/reward_rules/rest/admin/v1/shouldReturnBetRanges.groovy
@@ -0,0 +1,38 @@
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+ description('Should return bet ranges array')
+ request {
+ method 'GET'
+ url('/admin/v1/spin/betRanges')
+ }
+
+ response {
+ status 200
+ body(
+ betRanges: [
+ [
+ betRangeId : 3,
+ fromBetPercent: -1
+ ],
+ [
+ betRangeId : 4,
+ fromBetPercent: 0
+ ],
+ [
+ betRangeId : 1,
+ fromBetPercent: 90
+ ],
+ [
+ betRangeId : 2,
+ fromBetPercent: 130
+ ]
+ ]
+ )
+
+ headers {
+ contentType(applicationJsonUtf8())
+ }
+ }
+}
+
diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy
new file mode 100644
index 0000000000..5c33f16f4f
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/coupons_new_backend/rest/shouldReturnEmptyFriendsWhenGetFriends.groovy
@@ -0,0 +1,30 @@
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+ description("""
+Should return empty array if user has no friends
+""")
+ request {
+ method 'GET'
+ urlPath('/SocialServer/social/getFriends')
+ url('/social/getFriends') {
+ queryParameters {
+ parameter 'snId': $(consumer(regex('([^\\W]|-)+')), producer('12345'))
+ parameter 'snType': $(consumer(regex('\\d+')), producer(2))
+ }
+ }
+ }
+
+ response {
+ status 200
+ body(
+ """
+ {"friends" : []}
+ """)
+
+ headers {
+ contentType(applicationJsonUtf8())
+ }
+ }
+}
+
diff --git a/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy
new file mode 100644
index 0000000000..411bbe2496
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/resources/directory/with/common-messaging/social-service/src/main/resources/contracts/facebook_client/rest/shouldUpdateUserInfo.groovy
@@ -0,0 +1,44 @@
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+ description("""
+User's information should be update if has appropriate age
+""")
+ request {
+ method 'POST'
+ url '/test/updateUserInfo'
+ body([
+ userId: 123,
+ age: 25,
+ firstName: "asd",
+ lastName: "asd"
+ ])
+ stubMatchers {
+ jsonPath('$.userId', byRegex("[1-9]{1}([0-9]{7})"))
+ jsonPath('$.age', byRegex("(1[89]|[2-9][0-9])"))
+ jsonPath('$.firstName', byRegex("[a-zA-Z]{2,20}"))
+ jsonPath('$.lastName', byRegex("[a-zA-Z]{2,20}"))
+ }
+ headers {
+ contentType(applicationJson())
+ }
+ }
+ response {
+ status 200
+ body([
+ userId: fromRequest().body("userId"),
+ age: fromRequest().body("age"),
+ firstName: fromRequest().body("firstName"),
+ lastName: fromRequest().body("lastName")
+ ])
+ testMatchers {
+ jsonPath('$.userId', byEquality())
+ jsonPath('$.age', byEquality())
+ jsonPath('$.firstName', byEquality())
+ jsonPath('$.lastName', byEquality())
+ }
+ headers {
+ contentType(applicationJson())
+ }
+ }
+}
\ No newline at end of file