Pact Contract (#188)
with this change we're providing support for Pact based contracts. No longer do you have to set up your contracts using the Groovy DSL. In the same way as with the DSL you can use the Pact contracts to generate tests and the stubs on the producer side. fixes #96
This commit is contained in:
committed by
GitHub
parent
da6046f342
commit
22a5e44471
@@ -705,6 +705,114 @@ and the YAML implementation
|
||||
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverter.groovy[indent=0,lines=16..-1]
|
||||
----
|
||||
|
||||
===== Pact converter
|
||||
|
||||
Spring Cloud Contract comes with an out of the box support for https://docs.pact.io/[Pact] representation of contracts.
|
||||
In other words instead of using the Groovy DSL you can use Pact files. In this section
|
||||
we will present how to add such a support for your project.
|
||||
|
||||
====== Pact contract
|
||||
|
||||
We will be working on the following example of a Pact contract. We've placed this file under
|
||||
the `src/test/resources/contracts` folder.
|
||||
|
||||
[source,javascript,indent=0]
|
||||
----
|
||||
include::{standalone_pact_path}/pact-http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.json[indent=0]
|
||||
----
|
||||
|
||||
====== Pact for producers
|
||||
|
||||
On the producer side you have add to your plugin configuration two additional dependencies.
|
||||
One is the Spring Cloud Contract Pact support and the other represents the current
|
||||
Pact version that you're using.
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Maven
|
||||
----
|
||||
include::{standalone_pact_path}/pact-http-server/pom.xml[tags=pact_dependency,indent=0]
|
||||
----
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Gradle
|
||||
----
|
||||
include::{standalone_pact_path}/pact-http-server/build.gradle[tags=pact_dependency,indent=0]
|
||||
----
|
||||
|
||||
When you execute the build of your application a test, looking more or less like this, will be generated
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@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")).isEqualTo("application/vnd.fraud.v1+json;charset=UTF-8");
|
||||
// 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");
|
||||
}
|
||||
----
|
||||
|
||||
and the stub looking like this
|
||||
|
||||
[source,javascript,indent=0]
|
||||
----
|
||||
{
|
||||
"uuid" : "996ae5ae-6834-4db6-8fac-358ca187ab62",
|
||||
"request" : {
|
||||
"url" : "/fraudcheck",
|
||||
"method" : "PUT",
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"equalTo" : "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"
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
====== Pact for consumers
|
||||
|
||||
On the producer side you have add to your project dependencies two additional dependencies.
|
||||
One is the Spring Cloud Contract Pact support and the other represents the current
|
||||
Pact version that you're using.
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Maven
|
||||
----
|
||||
include::{standalone_pact_path}/pact-http-client/pom.xml[tags=pact_dependency,indent=0]
|
||||
----
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Gradle
|
||||
----
|
||||
include::{standalone_pact_path}/pact-http-client/build.gradle[tags=pact_dependency,indent=0]
|
||||
----
|
||||
|
||||
==== Custom test generator
|
||||
|
||||
If you want to generate tests for different languages than Java or you're
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner
|
||||
:standalone_samples_path: {samples_path}/standalone/dsl
|
||||
:standalone_messaging_samples_path: {samples_path}/standalone/messaging
|
||||
:standalone_pact_path: {samples_path}/standalone/pact
|
||||
:tests_path: {core_path}/tests
|
||||
:samples_url: https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master
|
||||
|
||||
|
||||
10
pom.xml
10
pom.xml
@@ -127,6 +127,16 @@
|
||||
<artifactId>hoverfly-junit</artifactId>
|
||||
<version>0.1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>au.com.dius</groupId>
|
||||
<artifactId>pact-jvm-model</artifactId>
|
||||
<version>2.4.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-dependencies</artifactId>
|
||||
|
||||
6
samples/standalone/pact/pact-http-client/.gitignore
vendored
Normal file
6
samples/standalone/pact/pact-http-client/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
target/
|
||||
|
||||
.gradle
|
||||
build/
|
||||
|
||||
1
samples/standalone/pact/pact-http-client/.mvn/jvm.config
Normal file
1
samples/standalone/pact/pact-http-client/.mvn/jvm.config
Normal file
@@ -0,0 +1 @@
|
||||
-Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true
|
||||
@@ -0,0 +1 @@
|
||||
-T2
|
||||
BIN
samples/standalone/pact/pact-http-client/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
samples/standalone/pact/pact-http-client/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
1
samples/standalone/pact/pact-http-client/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
samples/standalone/pact/pact-http-client/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1 @@
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
|
||||
26
samples/standalone/pact/pact-http-client/README.adoc
Normal file
26
samples/standalone/pact/pact-http-client/README.adoc
Normal file
@@ -0,0 +1,26 @@
|
||||
= Pact Http Client
|
||||
|
||||
== Prerequisites
|
||||
|
||||
First you have to publish to Maven Local the stubs of the *pact-http-server* module
|
||||
|
||||
== How to run it?
|
||||
|
||||
Run
|
||||
|
||||
[source=groovy]
|
||||
--------
|
||||
./gradlew clean build
|
||||
--------
|
||||
|
||||
or
|
||||
|
||||
--------
|
||||
./mvnw clean package
|
||||
--------
|
||||
|
||||
To
|
||||
|
||||
- build the app
|
||||
- use spring-cloud-contract-stub-runner-spring[Stub Runner Spring] to download the stub of `Pact Http Server`
|
||||
- run the tests against stubbed server
|
||||
68
samples/standalone/pact/pact-http-client/build.gradle
Normal file
68
samples/standalone/pact/pact-http-client/build.gradle
Normal file
@@ -0,0 +1,68 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url "http://repo.spring.io/snapshot" }
|
||||
maven { url "http://repo.spring.io/milestone" }
|
||||
maven { url "http://repo.spring.io/release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.0.BUILD-SNAPSHOT"
|
||||
}
|
||||
}
|
||||
|
||||
group = 'com.example'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url "http://repo.spring.io/snapshot" }
|
||||
maven { url "http://repo.spring.io/milestone" }
|
||||
maven { url "http://repo.spring.io/release" }
|
||||
}
|
||||
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'spring-boot'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$BOM_VERSION"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile("org.springframework.boot:spring-boot-starter-web")
|
||||
compile("org.springframework.boot:spring-boot-starter-actuator")
|
||||
|
||||
testCompile "org.springframework.cloud:spring-cloud-starter-contract-stub-runner"
|
||||
//tag::pact_dependency[]
|
||||
testCompile "org.springframework.cloud:spring-cloud-contract-spec-pact"
|
||||
testCompile 'au.com.dius:pact-jvm-model:2.4.18'
|
||||
//end::pact_dependency[]
|
||||
}
|
||||
|
||||
test {
|
||||
systemProperty 'spring.profiles.active', 'gradle'
|
||||
testLogging {
|
||||
exceptionFormat = 'full'
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.14'
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
doLast {
|
||||
project.rootProject.allprojects.each { subProject ->
|
||||
subProject.buildscript.configurations.each { configuration ->
|
||||
configuration.resolve()
|
||||
}
|
||||
subProject.configurations.each { configuration ->
|
||||
configuration.resolve()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.gradle.daemon=false
|
||||
BOM_VERSION=Dalston.BUILD-SNAPSHOT
|
||||
BIN
samples/standalone/pact/pact-http-client/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
samples/standalone/pact/pact-http-client/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
samples/standalone/pact/pact-http-client/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
samples/standalone/pact/pact-http-client/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Fri Aug 19 15:39:05 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
|
||||
164
samples/standalone/pact/pact-http-client/gradlew
vendored
Executable file
164
samples/standalone/pact/pact-http-client/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
samples/standalone/pact/pact-http-client/gradlew.bat
vendored
Normal file
90
samples/standalone/pact/pact-http-client/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
234
samples/standalone/pact/pact-http-client/mvnw
vendored
Executable file
234
samples/standalone/pact/pact-http-client/mvnw
vendored
Executable file
@@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
#
|
||||
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
|
||||
# for the new JDKs provided by Oracle.
|
||||
#
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
|
||||
#
|
||||
# Oracle JDKs
|
||||
#
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=`/usr/libexec/java_home`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Migwn, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
local basedir=$(pwd)
|
||||
local wdir=$(pwd)
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
wdir=$(cd "$wdir/.."; pwd)
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS
|
||||
|
||||
145
samples/standalone/pact/pact-http-client/mvnw.cmd
vendored
Normal file
145
samples/standalone/pact/pact-http-client/mvnw.cmd
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %*
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
|
||||
set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
217
samples/standalone/pact/pact-http-client/pom.xml
Normal file
217
samples/standalone/pact/pact-http-client/pom.xml
Normal file
@@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>pact-http-client</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>Spring Cloud Contract Verifier Http Client Sample with Pact</name>
|
||||
<description>Spring Cloud Contract Verifier Http Client Sample with Pact</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud-dependencies.version>Dalston.BUILD-SNAPSHOT</spring-cloud-dependencies.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- tag::pact_dependency[] -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-spec-pact</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>au.com.dius</groupId>
|
||||
<artifactId>pact-jvm-model</artifactId>
|
||||
<version>2.4.18</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- end::pact_dependency[] -->
|
||||
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud-dependencies.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>build</directory>
|
||||
</fileset>
|
||||
<fileset>
|
||||
<directory>target</directory>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>gradle</id>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<executable>./gradlew</executable>
|
||||
<arguments>
|
||||
<argument>clean</argument>
|
||||
<argument>build</argument>
|
||||
<argument>publishToMavenLocal</argument>
|
||||
<argument>-PverifierVersion=${spring-cloud-contract.version}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>windows</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>gradle</id>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<executable>gradlew.bat</executable>
|
||||
<arguments>
|
||||
<argument>clean</argument>
|
||||
<argument>build</argument>
|
||||
<argument>publishToMavenLocal</argument>
|
||||
<argument>-PverifierVersion=${spring-cloud-contract.version}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
1
samples/standalone/pact/pact-http-client/settings.gradle
Normal file
1
samples/standalone/pact/pact-http-client/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'pact-http-client-gradle'
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.example.loan;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.example.loan;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.example.loan.model.FraudCheckStatus;
|
||||
import com.example.loan.model.FraudServiceRequest;
|
||||
import com.example.loan.model.FraudServiceResponse;
|
||||
import com.example.loan.model.LoanApplication;
|
||||
import com.example.loan.model.LoanApplicationResult;
|
||||
import com.example.loan.model.LoanApplicationStatus;
|
||||
import com.example.loan.model.Response;
|
||||
|
||||
@Service
|
||||
public class LoanApplicationService {
|
||||
|
||||
private static final String FRAUD_SERVICE_JSON_VERSION_1 =
|
||||
"application/vnd.fraud.v1+json";
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
private int port = 6565;
|
||||
|
||||
@Autowired
|
||||
public LoanApplicationService(RestTemplateBuilder builder) {
|
||||
this.restTemplate = builder.build();
|
||||
}
|
||||
|
||||
public LoanApplicationResult loanApplication(LoanApplication loanApplication) {
|
||||
FraudServiceRequest request =
|
||||
new FraudServiceRequest(loanApplication);
|
||||
|
||||
FraudServiceResponse response =
|
||||
sendRequestToFraudDetectionService(request);
|
||||
|
||||
return buildResponseFromFraudResult(response);
|
||||
}
|
||||
|
||||
private FraudServiceResponse sendRequestToFraudDetectionService(
|
||||
FraudServiceRequest request) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1);
|
||||
|
||||
// tag::client_call_server[]
|
||||
ResponseEntity<FraudServiceResponse> response =
|
||||
restTemplate.exchange("http://localhost:" + port + "/fraudcheck", HttpMethod.PUT,
|
||||
new HttpEntity<>(request, httpHeaders),
|
||||
FraudServiceResponse.class);
|
||||
// end::client_call_server[]
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
private LoanApplicationResult buildResponseFromFraudResult(FraudServiceResponse response) {
|
||||
LoanApplicationStatus applicationStatus = null;
|
||||
if (FraudCheckStatus.OK == response.getFraudCheckStatus()) {
|
||||
applicationStatus = LoanApplicationStatus.LOAN_APPLIED;
|
||||
} else if (FraudCheckStatus.FRAUD == response.getFraudCheckStatus()) {
|
||||
applicationStatus = LoanApplicationStatus.LOAN_APPLICATION_REJECTED;
|
||||
}
|
||||
|
||||
return new LoanApplicationResult(applicationStatus, response.getRejectionReason());
|
||||
}
|
||||
|
||||
public int countAllFrauds() {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1);
|
||||
ResponseEntity<Response> response =
|
||||
restTemplate.exchange("http://localhost:" + port + "/frauds", HttpMethod.GET,
|
||||
new HttpEntity<>(httpHeaders),
|
||||
Response.class);
|
||||
return response.getBody().getCount();
|
||||
}
|
||||
|
||||
public int countDrunks() {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1);
|
||||
ResponseEntity<Response> response =
|
||||
restTemplate.exchange("http://localhost:" + port + "/drunks", HttpMethod.GET,
|
||||
new HttpEntity<>(httpHeaders),
|
||||
Response.class);
|
||||
return response.getBody().getCount();
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class Client {
|
||||
|
||||
private String pesel;
|
||||
|
||||
public Client() {
|
||||
}
|
||||
|
||||
public Client(String pesel) {
|
||||
this.pesel = pesel;
|
||||
}
|
||||
|
||||
public String getPesel() {
|
||||
return pesel;
|
||||
}
|
||||
|
||||
public void setPesel(String pesel) {
|
||||
this.pesel = pesel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public enum FraudCheckStatus {
|
||||
OK, FRAUD
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class FraudServiceRequest {
|
||||
|
||||
private String clientId;
|
||||
|
||||
private BigDecimal loanAmount;
|
||||
|
||||
public FraudServiceRequest() {
|
||||
}
|
||||
|
||||
public FraudServiceRequest(LoanApplication loanApplication) {
|
||||
this.clientId = loanApplication.getClient().getPesel();
|
||||
this.loanAmount = loanApplication.getAmount();
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public BigDecimal getLoanAmount() {
|
||||
return loanAmount;
|
||||
}
|
||||
|
||||
public void setLoanAmount(BigDecimal loanAmount) {
|
||||
this.loanAmount = loanAmount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class FraudServiceResponse {
|
||||
|
||||
private FraudCheckStatus fraudCheckStatus;
|
||||
|
||||
private String rejectionReason;
|
||||
|
||||
public FraudServiceResponse() {
|
||||
}
|
||||
|
||||
public FraudCheckStatus getFraudCheckStatus() {
|
||||
return fraudCheckStatus;
|
||||
}
|
||||
|
||||
public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) {
|
||||
this.fraudCheckStatus = fraudCheckStatus;
|
||||
}
|
||||
|
||||
public String getRejectionReason() {
|
||||
return rejectionReason;
|
||||
}
|
||||
|
||||
public void setRejectionReason(String rejectionReason) {
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class LoanApplication {
|
||||
|
||||
private Client client;
|
||||
|
||||
private BigDecimal amount;
|
||||
|
||||
private String loanApplicationId;
|
||||
|
||||
public LoanApplication() {
|
||||
}
|
||||
|
||||
public LoanApplication(Client client, double amount) {
|
||||
this.client = client;
|
||||
this.amount = BigDecimal.valueOf(amount);
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getLoanApplicationId() {
|
||||
return loanApplicationId;
|
||||
}
|
||||
|
||||
public void setLoanApplicationId(String loanApplicationId) {
|
||||
this.loanApplicationId = loanApplicationId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class LoanApplicationResult {
|
||||
|
||||
private LoanApplicationStatus loanApplicationStatus;
|
||||
|
||||
private String rejectionReason;
|
||||
|
||||
public LoanApplicationResult() {
|
||||
}
|
||||
|
||||
public LoanApplicationResult(LoanApplicationStatus loanApplicationStatus, String rejectionReason) {
|
||||
this.loanApplicationStatus = loanApplicationStatus;
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
|
||||
public LoanApplicationStatus getLoanApplicationStatus() {
|
||||
return loanApplicationStatus;
|
||||
}
|
||||
|
||||
public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) {
|
||||
this.loanApplicationStatus = loanApplicationStatus;
|
||||
}
|
||||
|
||||
public String getRejectionReason() {
|
||||
return rejectionReason;
|
||||
}
|
||||
|
||||
public void setRejectionReason(String rejectionReason) {
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public enum LoanApplicationStatus {
|
||||
LOAN_APPLIED, LOAN_APPLICATION_REJECTED
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class Response {
|
||||
private int count;
|
||||
|
||||
public Response(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public Response() {
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
server.port: 8090
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.example.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.example.loan.model.Client;
|
||||
import com.example.loan.model.LoanApplication;
|
||||
import com.example.loan.model.LoanApplicationResult;
|
||||
import com.example.loan.model.LoanApplicationStatus;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment=WebEnvironment.NONE)
|
||||
@AutoConfigureStubRunner(ids = {"com.example:pact-http-server:+:stubs"}, workOffline = true)
|
||||
@DirtiesContext
|
||||
public class LoanApplicationServiceTests {
|
||||
|
||||
@Autowired
|
||||
private LoanApplicationService service;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.service.setPort(this.environment.getProperty("stubrunner.runningstubs.pact-http-server.port", Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSuccessfullyApplyForLoan() {
|
||||
// given:
|
||||
LoanApplication application = new LoanApplication(new Client("1234567890"),
|
||||
123.123);
|
||||
// when:
|
||||
LoanApplicationResult loanApplication = service.loanApplication(application);
|
||||
// then:
|
||||
assertThat(loanApplication.getLoanApplicationStatus())
|
||||
.isEqualTo(LoanApplicationStatus.LOAN_APPLIED);
|
||||
assertThat(loanApplication.getRejectionReason()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeRejectedDueToAbnormalLoanAmount() {
|
||||
// given:
|
||||
LoanApplication application = new LoanApplication(new Client("1234567890"),
|
||||
99999);
|
||||
// when:
|
||||
LoanApplicationResult loanApplication = service.loanApplication(application);
|
||||
// then:
|
||||
assertThat(loanApplication.getLoanApplicationStatus())
|
||||
.isEqualTo(LoanApplicationStatus.LOAN_APPLICATION_REJECTED);
|
||||
assertThat(loanApplication.getRejectionReason()).isEqualTo("Amount too high");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSuccessfullyGetAllFrauds() {
|
||||
// when:
|
||||
int count = service.countAllFrauds();
|
||||
// then:
|
||||
assertThat(count).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSuccessfullyGetAllDrunks() {
|
||||
// when:
|
||||
int count = service.countDrunks();
|
||||
// then:
|
||||
assertThat(count).isEqualTo(100);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
stubrunner:
|
||||
work-offline: true
|
||||
stubs.ids: 'com.example:pact-http-server-gradle:+:stubs'
|
||||
@@ -0,0 +1,2 @@
|
||||
server:
|
||||
port: 0
|
||||
6
samples/standalone/pact/pact-http-server/.gitignore
vendored
Normal file
6
samples/standalone/pact/pact-http-server/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
target/
|
||||
|
||||
.gradle
|
||||
build/
|
||||
|
||||
1
samples/standalone/pact/pact-http-server/.mvn/jvm.config
Normal file
1
samples/standalone/pact/pact-http-server/.mvn/jvm.config
Normal file
@@ -0,0 +1 @@
|
||||
-Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true
|
||||
@@ -0,0 +1 @@
|
||||
-T2
|
||||
BIN
samples/standalone/pact/pact-http-server/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
samples/standalone/pact/pact-http-server/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
1
samples/standalone/pact/pact-http-server/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
samples/standalone/pact/pact-http-server/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1 @@
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
|
||||
20
samples/standalone/pact/pact-http-server/README.adoc
Normal file
20
samples/standalone/pact/pact-http-server/README.adoc
Normal file
@@ -0,0 +1,20 @@
|
||||
= Pact Http Server
|
||||
|
||||
Run
|
||||
|
||||
[source=groovy]
|
||||
--------
|
||||
./gradlew clean build publishToMavenLocal
|
||||
--------
|
||||
|
||||
or
|
||||
|
||||
--------
|
||||
./mvnw clean install
|
||||
--------
|
||||
|
||||
To
|
||||
|
||||
- build the app
|
||||
- generate and run Spring Cloud Contract Verifier tests
|
||||
- publish the fatJar and the stubs to Maven Local
|
||||
78
samples/standalone/pact/pact-http-server/build.gradle
Normal file
78
samples/standalone/pact/pact-http-server/build.gradle
Normal file
@@ -0,0 +1,78 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url "http://repo.spring.io/snapshot" }
|
||||
maven { url "http://repo.spring.io/milestone" }
|
||||
maven { url "http://repo.spring.io/release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.0.BUILD-SNAPSHOT"
|
||||
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${findProperty('verifierVersion') ?: verifierVersion}"
|
||||
//tag::pact_dependency[]
|
||||
classpath "org.springframework.cloud:spring-cloud-contract-spec-pact:${findProperty('verifierVersion') ?: verifierVersion}"
|
||||
classpath 'au.com.dius:pact-jvm-model:2.4.18'
|
||||
//end::pact_dependency[]
|
||||
}
|
||||
}
|
||||
|
||||
group = 'com.example'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url "http://repo.spring.io/snapshot" }
|
||||
maven { url "http://repo.spring.io/milestone" }
|
||||
maven { url "http://repo.spring.io/release" }
|
||||
}
|
||||
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'spring-boot'
|
||||
apply plugin: 'spring-cloud-contract'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$BOM_VERSION"
|
||||
}
|
||||
}
|
||||
|
||||
contracts {
|
||||
packageWithBaseClasses = 'com.example.fraud'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile("org.springframework.boot:spring-boot-starter-web")
|
||||
compile("org.springframework.boot:spring-boot-starter-actuator")
|
||||
|
||||
testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
|
||||
}
|
||||
|
||||
test {
|
||||
systemProperty 'spring.profiles.active', 'gradle'
|
||||
testLogging {
|
||||
exceptionFormat = 'full'
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.14'
|
||||
}
|
||||
|
||||
clean.doFirst {
|
||||
delete "~/.m2/repository/com/example/http-server-pact-gradle"
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
doLast {
|
||||
project.rootProject.allprojects.each { subProject ->
|
||||
subProject.buildscript.configurations.each { configuration ->
|
||||
configuration.resolve()
|
||||
}
|
||||
subProject.configurations.each { configuration ->
|
||||
configuration.resolve()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
org.gradle.daemon=false
|
||||
verifierVersion=1.1.0.BUILD-SNAPSHOT
|
||||
BOM_VERSION=Dalston.BUILD-SNAPSHOT
|
||||
BIN
samples/standalone/pact/pact-http-server/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
samples/standalone/pact/pact-http-server/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
samples/standalone/pact/pact-http-server/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
samples/standalone/pact/pact-http-server/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Fri Aug 19 15:38:58 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
|
||||
164
samples/standalone/pact/pact-http-server/gradlew
vendored
Executable file
164
samples/standalone/pact/pact-http-server/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
samples/standalone/pact/pact-http-server/gradlew.bat
vendored
Normal file
90
samples/standalone/pact/pact-http-server/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
234
samples/standalone/pact/pact-http-server/mvnw
vendored
Executable file
234
samples/standalone/pact/pact-http-server/mvnw
vendored
Executable file
@@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
#
|
||||
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
|
||||
# for the new JDKs provided by Oracle.
|
||||
#
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
|
||||
#
|
||||
# Oracle JDKs
|
||||
#
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=`/usr/libexec/java_home`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Migwn, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
local basedir=$(pwd)
|
||||
local wdir=$(pwd)
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
wdir=$(cd "$wdir/.."; pwd)
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS
|
||||
|
||||
145
samples/standalone/pact/pact-http-server/mvnw.cmd
vendored
Normal file
145
samples/standalone/pact/pact-http-server/mvnw.cmd
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %*
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
|
||||
set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
259
samples/standalone/pact/pact-http-server/pom.xml
Normal file
259
samples/standalone/pact/pact-http-server/pom.xml
Normal file
@@ -0,0 +1,259 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>pact-http-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>Spring Cloud Contract Verifier Http Server Sample with Pact</name>
|
||||
<description>Spring Cloud Contract Verifier Http Server Sample with Pact</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud-contract.version>1.1.0.BUILD-SNAPSHOT</spring-cloud-contract.version>
|
||||
<spring-cloud-dependencies.version>Dalston.BUILD-SNAPSHOT</spring-cloud-dependencies.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-contract-verifier</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud-dependencies.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<!-- tag::pact_dependency[] -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-spec-pact</artifactId>
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>au.com.dius</groupId>
|
||||
<artifactId>pact-jvm-model</artifactId>
|
||||
<version>2.4.18</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<!-- end::pact_dependency[] -->
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>build</directory>
|
||||
</fileset>
|
||||
<fileset>
|
||||
<directory>target</directory>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings
|
||||
only. It has no influence on the Maven build itself. -->
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<versionRange>[1.1.0.BUILD-SNAPSHOT,)</versionRange>
|
||||
<goals>
|
||||
<goal>convert</goal>
|
||||
<goal>generateTests</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<ignore></ignore>
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>gradle</id>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<executable>./gradlew</executable>
|
||||
<arguments>
|
||||
<argument>clean</argument>
|
||||
<argument>build</argument>
|
||||
<argument>publishToMavenLocal</argument>
|
||||
<argument>-PverifierVersion=${spring-cloud-contract.version}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>windows</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>gradle</id>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<executable>gradlew.bat</executable>
|
||||
<arguments>
|
||||
<argument>clean</argument>
|
||||
<argument>build</argument>
|
||||
<argument>publishToMavenLocal</argument>
|
||||
<argument>-PverifierVersion=${spring-cloud-contract.version}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
1
samples/standalone/pact/pact-http-server/settings.gradle
Normal file
1
samples/standalone/pact/pact-http-server/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'pact-http-server-gradle'
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.fraud;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.example.fraud;
|
||||
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.example.fraud.model.FraudCheck;
|
||||
import com.example.fraud.model.FraudCheckResult;
|
||||
import com.example.fraud.model.FraudCheckStatus;
|
||||
|
||||
@RestController
|
||||
public class FraudDetectionController {
|
||||
|
||||
private static final String FRAUD_SERVICE_JSON_VERSION_1 = "application/vnd.fraud.v1+json";
|
||||
private static final String NO_REASON = null;
|
||||
private static final String AMOUNT_TOO_HIGH = "Amount too high";
|
||||
private static final BigDecimal MAX_AMOUNT = new BigDecimal("5000");
|
||||
|
||||
@RequestMapping(
|
||||
value = "/fraudcheck",
|
||||
method = PUT,
|
||||
consumes = FRAUD_SERVICE_JSON_VERSION_1,
|
||||
produces = FRAUD_SERVICE_JSON_VERSION_1)
|
||||
public FraudCheckResult fraudCheck(@RequestBody FraudCheck fraudCheck) {
|
||||
if (amountGreaterThanThreshold(fraudCheck)) {
|
||||
return new FraudCheckResult(FraudCheckStatus.FRAUD, AMOUNT_TOO_HIGH);
|
||||
}
|
||||
return new FraudCheckResult(FraudCheckStatus.OK, NO_REASON);
|
||||
}
|
||||
|
||||
private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) {
|
||||
return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.example.fraud;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class FraudStatsController {
|
||||
|
||||
private static final String FRAUD_SERVICE_JSON_VERSION_1 = "application/vnd.fraud.v1+json";
|
||||
|
||||
private final StatsProvider statsProvider;
|
||||
|
||||
public FraudStatsController(StatsProvider statsProvider) {
|
||||
this.statsProvider = statsProvider;
|
||||
}
|
||||
|
||||
@GetMapping(
|
||||
value = "/frauds",
|
||||
produces = FRAUD_SERVICE_JSON_VERSION_1)
|
||||
public Response countAllFrauds() {
|
||||
return new Response(this.statsProvider.count(FraudType.ALL));
|
||||
}
|
||||
|
||||
@GetMapping(
|
||||
value = "/drunks",
|
||||
produces = FRAUD_SERVICE_JSON_VERSION_1)
|
||||
public Response countAllDrunks() {
|
||||
return new Response(this.statsProvider.count(FraudType.DRUNKS));
|
||||
}
|
||||
}
|
||||
|
||||
enum FraudType {
|
||||
DRUNKS, ALL
|
||||
}
|
||||
|
||||
interface StatsProvider {
|
||||
int count(FraudType fraudType);
|
||||
}
|
||||
|
||||
class Response {
|
||||
private int count;
|
||||
|
||||
public Response(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public Response() {
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.example.fraud.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class FraudCheck {
|
||||
|
||||
private String clientId;
|
||||
|
||||
private BigDecimal loanAmount;
|
||||
|
||||
public FraudCheck() {
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public BigDecimal getLoanAmount() {
|
||||
return loanAmount;
|
||||
}
|
||||
|
||||
public void setLoanAmount(BigDecimal loanAmount) {
|
||||
this.loanAmount = loanAmount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.example.fraud.model;
|
||||
|
||||
public class FraudCheckResult {
|
||||
|
||||
private FraudCheckStatus fraudCheckStatus;
|
||||
|
||||
private String rejectionReason;
|
||||
|
||||
public FraudCheckResult() {
|
||||
}
|
||||
|
||||
public FraudCheckResult(FraudCheckStatus fraudCheckStatus, String rejectionReason) {
|
||||
this.fraudCheckStatus = fraudCheckStatus;
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
|
||||
public FraudCheckStatus getFraudCheckStatus() {
|
||||
return fraudCheckStatus;
|
||||
}
|
||||
|
||||
public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) {
|
||||
this.fraudCheckStatus = fraudCheckStatus;
|
||||
}
|
||||
|
||||
public String getRejectionReason() {
|
||||
return rejectionReason;
|
||||
}
|
||||
|
||||
public void setRejectionReason(String rejectionReason) {
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.fraud.model;
|
||||
|
||||
public enum FraudCheckStatus {
|
||||
OK, FRAUD
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
server.port: 0
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.fraud;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
|
||||
|
||||
public class FraudBase {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
RestAssuredMockMvc.standaloneSetup(new FraudDetectionController(),
|
||||
new FraudStatsController(stubbedStatsProvider()));
|
||||
}
|
||||
|
||||
private StatsProvider stubbedStatsProvider() {
|
||||
return fraudType -> {
|
||||
switch (fraudType) {
|
||||
case DRUNKS:
|
||||
return 100;
|
||||
case ALL:
|
||||
return 200;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
public void assertThatRejectionReasonIsNull(Object rejectionReason) {
|
||||
assert rejectionReason == null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"path": "/fraudcheck",
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"clientId": "1234567890",
|
||||
"loanAmount": 99999
|
||||
},
|
||||
"matchingRules": {
|
||||
"$.body.clientId": {
|
||||
"match": "regex",
|
||||
"regex": "[0-9]{10}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"fraudCheckStatus": "FRAUD",
|
||||
"rejectionReason": "Amount too high"
|
||||
},
|
||||
"matchingRules": {
|
||||
"$.body.fraudCheckStatus": {
|
||||
"match": "regex",
|
||||
"regex": "FRAUD"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"path": "/fraudcheck",
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"clientId": "1234567890",
|
||||
"loanAmount": 123.123
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"fraudCheckStatus": "OK",
|
||||
"rejectionReason": null
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/drunks"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"count": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/frauds"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"count": 200
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
39
samples/standalone/pact/pom.xml
Normal file
39
samples/standalone/pact/pom.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-samples-standalone</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-contract-samples-pact</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Cloud Contract Standalone Pact Test Samples</name>
|
||||
<description>Spring Cloud Contract Standalone Test Samples used for end to end tests with Pact</description>
|
||||
|
||||
<properties>
|
||||
<spring-cloud-contract.version>1.1.0.BUILD-SNAPSHOT</spring-cloud-contract.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>pact-http-server</module>
|
||||
<module>pact-http-client</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -21,9 +21,11 @@
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>contracts</module>
|
||||
<module>restdocs</module>
|
||||
<module>dsl</module>
|
||||
<module>messaging</module>
|
||||
<module>pact</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
<artifactId>spring-cloud-contract-converters</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-spec-pact</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-stub-runner</artifactId>
|
||||
|
||||
@@ -17,11 +17,31 @@
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-nio</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-xml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dk.brics.automaton</groupId>
|
||||
<artifactId>automaton</artifactId>
|
||||
<version>1.11-8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.cloud.contract.spec.internal.Response
|
||||
*/
|
||||
@TypeChecked
|
||||
@EqualsAndHashCode
|
||||
@ToString(includeFields = true, includePackage = false, includeNames = true)
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
class Contract {
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ package org.springframework.cloud.contract.spec
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface ContractConverter<T> {
|
||||
interface ContractConverter<T> {
|
||||
|
||||
/**
|
||||
* Should this file be accepted by the converter. Can use the file extension
|
||||
|
||||
@@ -25,7 +25,7 @@ import groovy.transform.ToString
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ToString(includePackage = false, includeFields = true, includeNames = true, includeSuper = true)
|
||||
@ToString(includePackage = false, includeNames = true, includeSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@CompileStatic
|
||||
class Body extends DslProperty {
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Represents a property that will become an executable method in the
|
||||
@@ -27,6 +28,7 @@ import groovy.transform.EqualsAndHashCode
|
||||
*/
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
class ExecutionProperty {
|
||||
|
||||
private static final String PLACEHOLDER_VALUE = '\\$it'
|
||||
@@ -46,7 +48,7 @@ class ExecutionProperty {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String toString() {
|
||||
return executionCommand
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import groovy.transform.ToString
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ToString(includePackage = false, includeFields = true, includeNames = true)
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@CompileStatic
|
||||
class NamedProperty {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Represents a property that may or may not be there
|
||||
@@ -24,6 +25,7 @@ import groovy.transform.CompileStatic
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@CompileStatic
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
class OptionalProperty {
|
||||
final Object value
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ import static org.springframework.cloud.contract.spec.util.ValidateUtils.validat
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true, includeSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(includePackage = false, ignoreNulls = true, includeNames = true, includeSuper = true)
|
||||
@CompileStatic
|
||||
class QueryParameter extends DslProperty {
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true)
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false, ignoreNulls = true, includeNames = true)
|
||||
@TypeChecked
|
||||
class QueryParameters {
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.regex.Pattern
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TypeChecked
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false, includeFields = true)
|
||||
class Response extends Common {
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import static org.springframework.cloud.contract.spec.util.ValidateUtils.validat
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ToString(includePackage = false, includeFields = true, includeNames = true, includeSuper = true)
|
||||
@ToString(includePackage = false, includeNames = true, includeSuper = true)
|
||||
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||
@CompileStatic
|
||||
class Url extends DslProperty {
|
||||
|
||||
@@ -21,7 +21,8 @@ import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Represents a url path
|
||||
* Represents a url path. Syntactic sugar when working with
|
||||
* {@link QueryParameters}. It's logically equal to {@link Url}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,9 @@ class StubRepository {
|
||||
"Missing descriptor repository under path [" + repository + "]");
|
||||
}
|
||||
this.contractConverters = SpringFactoriesLoader.loadFactories(ContractConverter.class, null);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Found the following contract converters " + this.contractConverters);
|
||||
}
|
||||
this.httpServerStubs = httpServerStubs;
|
||||
this.path = repository;
|
||||
this.stubs = stubs();
|
||||
|
||||
@@ -25,10 +25,10 @@ import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatcher;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonPaths;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MethodBufferingJsonVerifiable;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
@@ -23,10 +23,10 @@ import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatcher;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonPaths;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MethodBufferingJsonVerifiable;
|
||||
import org.springframework.integration.core.MessageSelector;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
@@ -23,10 +23,10 @@ import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatcher;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonPaths;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MethodBufferingJsonVerifiable;
|
||||
import org.springframework.integration.core.MessageSelector;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
@@ -119,7 +119,9 @@ public class WireMockHttpServerStub implements HttpServerStub {
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Failed to register the stub mapping [" + mappingDescriptor + "]", e);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Failed to register the stub mapping [" + mappingDescriptor + "]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-contract-converters</module>
|
||||
<module>spring-cloud-contract-spec-pact</module>
|
||||
<module>spring-cloud-contract-maven-plugin</module>
|
||||
<module>spring-cloud-contract-gradle-plugin</module>
|
||||
</modules>
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.cloud.contract.verifier.config.ContractVerifierConfig
|
||||
import org.springframework.cloud.contract.verifier.file.ContractFileScanner
|
||||
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
||||
import org.springframework.cloud.contract.verifier.util.NamesUtil
|
||||
import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
@@ -64,8 +65,12 @@ class RecursiveFilesConverter {
|
||||
}
|
||||
contracts.asMap().entrySet().each { entry ->
|
||||
entry.value.each { ContractMetadata contract ->
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Will create a stub for contract [${contract}]")
|
||||
}
|
||||
File sourceFile = contract.path.toFile()
|
||||
StubGenerator stubGenerator = holder.converterForName(sourceFile.name);
|
||||
StubGenerator stubGenerator = contract.convertedContract ? holder.firstOrDefault(new DslToWireMockClientConverter()) :
|
||||
holder.converterForName(sourceFile.name)
|
||||
try {
|
||||
String path = sourceFile.path
|
||||
if (properties.isExcludeBuildFolders() && (matchesPath(path, "target") || matchesPath(path, "build"))) {
|
||||
@@ -78,7 +83,11 @@ class RecursiveFilesConverter {
|
||||
return
|
||||
}
|
||||
int contractsSize = contract.convertedContract.size()
|
||||
Map<Contract, String> convertedContent = stubGenerator.convertContents(entry.key.last().toString(), contract)
|
||||
def entryKey = entry.key
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Stub Generator [${stubGenerator}] will convert contents of [${entryKey}]")
|
||||
}
|
||||
Map<Contract, String> convertedContent = stubGenerator.convertContents(entryKey.last().toString(), contract)
|
||||
if (!convertedContent) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -25,4 +25,8 @@ class StubGeneratorProvider {
|
||||
StubGenerator converterForName(String fileName) {
|
||||
return this.converters.find { it.canHandleFileName(fileName) }
|
||||
}
|
||||
|
||||
StubGenerator firstOrDefault(StubGenerator defaultStubGenerator) {
|
||||
return this.converters.empty ? defaultStubGenerator : this.converters.first()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,6 +369,16 @@
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-spec-pact</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>au.com.dius</groupId>
|
||||
<artifactId>pact-jvm-model</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -16,20 +16,21 @@
|
||||
*/
|
||||
package org.springframework.cloud.contract.maven.verifier;
|
||||
|
||||
import static io.takari.maven.testing.TestMavenRuntime.newParameter;
|
||||
import static io.takari.maven.testing.TestResources.assertFilesNotPresent;
|
||||
import static io.takari.maven.testing.TestResources.assertFilesPresent;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import io.takari.maven.testing.TestMavenRuntime;
|
||||
import io.takari.maven.testing.TestResources;
|
||||
|
||||
import static io.takari.maven.testing.TestMavenRuntime.newParameter;
|
||||
import static io.takari.maven.testing.TestResources.assertFilesNotPresent;
|
||||
import static io.takari.maven.testing.TestResources.assertFilesPresent;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
public class PluginUnitTest {
|
||||
|
||||
@Rule
|
||||
@@ -256,4 +257,19 @@ public class PluginUnitTest {
|
||||
assertFilesPresent(basedir, "target/stubs/contracts/consumer1/Messaging.groovy");
|
||||
assertFilesPresent(basedir, "target/stubs/contracts/pom.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateContractTestsForPactAndMaintainIndents() throws Exception {
|
||||
File basedir = this.resources.getBasedir("pact");
|
||||
|
||||
this.maven.executeMojo(basedir, "generateTests");
|
||||
|
||||
assertFilesPresent(basedir,
|
||||
"target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
|
||||
File test = new File(basedir, "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
|
||||
String testContents = FileUtils.readFileToString(test);
|
||||
int countOccurrencesOf = StringUtils
|
||||
.countOccurrencesOf(testContents, "\t\tMockMvcRequestSpecification");
|
||||
then(countOccurrencesOf).isEqualTo(4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright 2013-2016 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.
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud.verifier.sample</groupId>
|
||||
<artifactId>sample-pact-project</artifactId>
|
||||
<version>0.1</version>
|
||||
|
||||
<properties>
|
||||
<spring.cloud.contract.version>1.1.0.BUILD-SNAPSHOT</spring.cloud.contract.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<baseClassForTests>com.example.FooBase</baseClassForTests>
|
||||
<baseClassMappings>
|
||||
<baseClassMapping>
|
||||
<contractPackageRegex>.*com.*</contractPackageRegex>
|
||||
<baseClassFQN>com.example.TestBase</baseClassFQN>
|
||||
</baseClassMapping>
|
||||
</baseClassMappings>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-spec-pact</artifactId>
|
||||
<version>${spring.cloud.contract.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>au.com.dius</groupId>
|
||||
<artifactId>pact-jvm-model</artifactId>
|
||||
<version>2.4.18</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"path": "/fraudcheck",
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"clientId": "1234567890",
|
||||
"loanAmount": 99999
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"fraudCheckStatus": "FRAUD",
|
||||
"rejectionReason": "Amount too high"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"path": "/fraudcheck",
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"clientId": "1234567890",
|
||||
"loanAmount": 123.123
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"fraudCheckStatus": "OK",
|
||||
"rejectionReason": null
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/drunks"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"count": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/frauds"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json;charset=UTF-8"
|
||||
},
|
||||
"body": {
|
||||
"count": 200
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-tools</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-contract-spec-pact</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Contract Spec Pact</name>
|
||||
<description>Spring Cloud Contract Spec Pact</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-verifier</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-nio</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>au.com.dius</groupId>
|
||||
<artifactId>pact-jvm-model</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>info.solidsoft.spock</groupId>
|
||||
<artifactId>spock-global-unroll</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>addSources</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,318 @@
|
||||
package org.springframework.cloud.contract.verifier.spec.pact
|
||||
|
||||
import au.com.dius.pact.model.BasePact
|
||||
import au.com.dius.pact.model.Consumer
|
||||
import au.com.dius.pact.model.Interaction
|
||||
import au.com.dius.pact.model.OptionalBody
|
||||
import au.com.dius.pact.model.Pact
|
||||
import au.com.dius.pact.model.PactReader
|
||||
import au.com.dius.pact.model.Provider
|
||||
import au.com.dius.pact.model.Request
|
||||
import au.com.dius.pact.model.RequestResponseInteraction
|
||||
import au.com.dius.pact.model.RequestResponsePact
|
||||
import au.com.dius.pact.model.Response
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.transform.CompileStatic
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.ContractConverter
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers
|
||||
import org.springframework.cloud.contract.spec.internal.DslProperty
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Headers
|
||||
import org.springframework.cloud.contract.spec.internal.MatchingType
|
||||
import org.springframework.cloud.contract.spec.internal.QueryParameters
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter
|
||||
|
||||
/**
|
||||
* Converter of JSON PACT file
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@CompileStatic
|
||||
class PactContractConverter implements ContractConverter<Pact> {
|
||||
|
||||
private static final String MATCH_KEY = "match"
|
||||
private static final String REGEX_KEY = "regex"
|
||||
private static final String MAX_KEY = "max"
|
||||
private static final String MIN_KEY = "min"
|
||||
|
||||
@Override
|
||||
boolean isAccepted(File file) {
|
||||
try {
|
||||
PactReader.loadPact(file)
|
||||
return true
|
||||
} catch (Exception e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<Contract> convertFrom(File file) {
|
||||
Pact pact = PactReader.loadPact(file)
|
||||
List<Interaction> interactions = pact.interactions
|
||||
return interactions.collect { Interaction interaction ->
|
||||
Contract.make {
|
||||
if (interaction instanceof RequestResponseInteraction) {
|
||||
RequestResponseInteraction requestResponseInteraction = (RequestResponseInteraction) interaction
|
||||
description("$requestResponseInteraction.description${providerState(interaction)}")
|
||||
request {
|
||||
method(requestResponseInteraction.request.method)
|
||||
if (requestResponseInteraction.request.query) {
|
||||
url(requestResponseInteraction.request.path) {
|
||||
queryParameters {
|
||||
requestResponseInteraction.request.query.each { String key, List<String> value ->
|
||||
value.each { String singleValue ->
|
||||
parameter(key, singleValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
url(requestResponseInteraction.request.path)
|
||||
}
|
||||
if (requestResponseInteraction.request.headers) {
|
||||
headers {
|
||||
requestResponseInteraction.request.headers.each { String key, String value ->
|
||||
header(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (requestResponseInteraction.request.body.state == OptionalBody.State.PRESENT) {
|
||||
def parsedBody = BasePact.parseBody(requestResponseInteraction.request)
|
||||
if (parsedBody instanceof Map) {
|
||||
body(parsedBody as Map)
|
||||
} else if (parsedBody instanceof List) {
|
||||
body(parsedBody as List)
|
||||
} else {
|
||||
body(parsedBody.toString())
|
||||
}
|
||||
}
|
||||
if (requestResponseInteraction.request?.matchingRules) {
|
||||
stubMatchers {
|
||||
requestResponseInteraction.request.matchingRules.each { String key, Map<String, Object> value ->
|
||||
String keyFromBody = toKeyStartingFromBody(key)
|
||||
if (value.containsKey(MATCH_KEY)) {
|
||||
MatchingType matchingType = MatchingType.valueOf((value.get(MATCH_KEY) as String).toUpperCase())
|
||||
switch (matchingType) {
|
||||
case MatchingType.EQUALITY:
|
||||
// equality is checked by default in the standard way
|
||||
break
|
||||
case MatchingType.DATE:
|
||||
jsonPath(keyFromBody, byDate())
|
||||
break
|
||||
case MatchingType.TIME:
|
||||
jsonPath(keyFromBody, byTime())
|
||||
break
|
||||
case MatchingType.TIMESTAMP:
|
||||
jsonPath(keyFromBody, byTimestamp())
|
||||
break
|
||||
case MatchingType.REGEX:
|
||||
jsonPath(keyFromBody, byRegex(value.get(REGEX_KEY) as String))
|
||||
break
|
||||
}
|
||||
} else if (value.containsKey(REGEX_KEY)) {
|
||||
jsonPath(keyFromBody, byRegex(value.get(REGEX_KEY) as String))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
response {
|
||||
status(requestResponseInteraction.response.status)
|
||||
if (requestResponseInteraction.response.body.state == OptionalBody.State.PRESENT) {
|
||||
def parsedBody = BasePact.parseBody(requestResponseInteraction.response)
|
||||
if (parsedBody instanceof Map) {
|
||||
body(parsedBody as Map)
|
||||
} else if (parsedBody instanceof List) {
|
||||
body(parsedBody as List)
|
||||
} else {
|
||||
body(parsedBody.toString())
|
||||
}
|
||||
}
|
||||
if (requestResponseInteraction.response?.matchingRules) {
|
||||
testMatchers {
|
||||
requestResponseInteraction.response.matchingRules.each { String key, Map<String, Object> value ->
|
||||
String keyFromBody = toKeyStartingFromBody(key)
|
||||
if (value.containsKey(MATCH_KEY)) {
|
||||
MatchingType matchingType = MatchingType.valueOf((value.get(MATCH_KEY) as String).toUpperCase())
|
||||
switch (matchingType) {
|
||||
case MatchingType.EQUALITY:
|
||||
// equality is checked by default in the standard way
|
||||
break
|
||||
case MatchingType.DATE:
|
||||
jsonPath(keyFromBody, byDate())
|
||||
break
|
||||
case MatchingType.TIME:
|
||||
jsonPath(keyFromBody, byTime())
|
||||
break
|
||||
case MatchingType.TIMESTAMP:
|
||||
jsonPath(keyFromBody, byTimestamp())
|
||||
break
|
||||
case MatchingType.REGEX:
|
||||
jsonPath(keyFromBody, byRegex(value.get(REGEX_KEY) as String))
|
||||
break
|
||||
case MatchingType.TYPE:
|
||||
jsonPath(keyFromBody, byType() {
|
||||
if (value.containsKey(MIN_KEY)) {
|
||||
minOccurrence(value.get(MIN_KEY) as Integer)
|
||||
}
|
||||
if (value.containsKey(MAX_KEY)) {
|
||||
maxOccurrence(value.get(MAX_KEY) as Integer)
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
} else if (value.containsKey(REGEX_KEY)) {
|
||||
jsonPath(keyFromBody, byRegex(value.get(REGEX_KEY) as String))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
requestResponseInteraction.response.headers?.each { String key, String value ->
|
||||
headers {
|
||||
header(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String providerState(Interaction interaction) {
|
||||
return interaction.providerState ? " ${interaction.providerState}" : ""
|
||||
}
|
||||
|
||||
protected String toKeyStartingFromBody(String key) {
|
||||
return key.replace('$.body', '$')
|
||||
}
|
||||
|
||||
@Override
|
||||
Pact convertTo(Collection<Contract> contract) {
|
||||
Provider provider = new Provider()
|
||||
provider.name = "Provider"
|
||||
Consumer consumer = new Consumer()
|
||||
consumer.name = "Consumer"
|
||||
List<RequestResponseInteraction> interactions = contract.find { it.request }.collect { Contract dsl ->
|
||||
RequestResponseInteraction interaction = new RequestResponseInteraction()
|
||||
interaction.description = dsl.description ?: ""
|
||||
Request request = new Request().with {
|
||||
method = dsl.request.method.serverValue.toString()
|
||||
path = url(dsl)
|
||||
QueryParameters params = queryParams(dsl)
|
||||
if (params) {
|
||||
query = params.parameters.collectEntries {
|
||||
String name = it.name
|
||||
String value = it.serverValue
|
||||
return [(name) : [value]]
|
||||
}
|
||||
}
|
||||
if (dsl.request.headers) {
|
||||
headers = headers(dsl.request.headers, { DslProperty property -> property.serverValue })
|
||||
}
|
||||
if (dsl.request.body) {
|
||||
assertInputContract(dsl.request.body.serverValue)
|
||||
def json = MapConverter.getTestSideValues(dsl.request.body.serverValue)
|
||||
String jsonBody = JsonOutput.toJson(json)
|
||||
body = new OptionalBody(OptionalBody.State.PRESENT, jsonBody)
|
||||
}
|
||||
if (dsl.request.matchers && dsl.request.matchers.hasMatchers()) {
|
||||
matchingRules = matchingRules(dsl.request.matchers)
|
||||
}
|
||||
return it
|
||||
}
|
||||
Response response = new Response().with {
|
||||
status = dsl.response.status.clientValue as Integer
|
||||
if (dsl.response.headers) {
|
||||
headers = headers(dsl.response.headers, { DslProperty property -> property.clientValue })
|
||||
}
|
||||
if (dsl.response.body) {
|
||||
assertInputContract(dsl.response.body.clientValue)
|
||||
def json = MapConverter.getStubSideValues(dsl.response.body.clientValue)
|
||||
String jsonBody = JsonOutput.toJson(json)
|
||||
body = new OptionalBody(OptionalBody.State.PRESENT, jsonBody)
|
||||
}
|
||||
if (dsl.response.matchers && dsl.response.matchers.hasMatchers()) {
|
||||
matchingRules = matchingRules(dsl.response.matchers)
|
||||
}
|
||||
return it
|
||||
}
|
||||
interaction.request = request
|
||||
interaction.response = response
|
||||
return interaction
|
||||
}
|
||||
return new RequestResponsePact(provider, consumer, interactions)
|
||||
}
|
||||
|
||||
protected void assertInputContract(parsedJson) {
|
||||
boolean hasExecutionProp = false
|
||||
MapConverter.transformValues(parsedJson, {
|
||||
if (it instanceof ExecutionProperty) {
|
||||
hasExecutionProp = true
|
||||
}
|
||||
return it
|
||||
})
|
||||
if (hasExecutionProp) {
|
||||
throw new UnsupportedOperationException("We can't convert a contract that has execution property")
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, String> headers(Headers headers, Closure closure) {
|
||||
return headers.entries.collectEntries {
|
||||
String name = it.name
|
||||
String value = closure(it)
|
||||
return [(name) : value]
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Map<String, Object>> matchingRules(BodyMatchers bodyMatchers) {
|
||||
return bodyMatchers.jsonPathMatchers().collectEntries {
|
||||
MatchingType matchingType = it.matchingType()
|
||||
String key = it.path()
|
||||
Object value = it.value()
|
||||
Integer minTypeOccurrence = it.minTypeOccurrence()
|
||||
Integer maxTypeOccurrence = it.maxTypeOccurrence()
|
||||
Map<String, Object> matchingRule = [:]
|
||||
switch (matchingType) {
|
||||
case MatchingType.EQUALITY:
|
||||
matchingRule << [(MATCH_KEY) : MatchingType.EQUALITY.toString().toLowerCase() as Object]
|
||||
break
|
||||
case MatchingType.TYPE:
|
||||
Map<String, Object> map = [(MATCH_KEY) : MatchingType.TYPE.toString().toLowerCase() as Object]
|
||||
if (minTypeOccurrence) map.put(MIN_KEY, minTypeOccurrence)
|
||||
if (maxTypeOccurrence) map.put(MAX_KEY, maxTypeOccurrence)
|
||||
matchingRule << map
|
||||
break
|
||||
case MatchingType.DATE:
|
||||
case MatchingType.TIME:
|
||||
case MatchingType.TIMESTAMP:
|
||||
case MatchingType.REGEX:
|
||||
matchingRule << [
|
||||
(MATCH_KEY) : MatchingType.REGEX.toString().toLowerCase() as Object,
|
||||
(REGEX_KEY) : value
|
||||
]
|
||||
break
|
||||
}
|
||||
return [(key) : matchingRule]
|
||||
}
|
||||
}
|
||||
|
||||
protected String url(Contract dsl) {
|
||||
if (dsl.request.urlPath) {
|
||||
return dsl.request.urlPath.serverValue.toString()
|
||||
} else if (dsl.request.url) {
|
||||
return dsl.request.url.serverValue.toString()
|
||||
}
|
||||
throw new IllegalStateException("No url provided")
|
||||
}
|
||||
|
||||
protected QueryParameters queryParams(Contract dsl) {
|
||||
if (dsl.request.urlPath) {
|
||||
return dsl.request.urlPath.queryParameters
|
||||
} else if (dsl.request.url) {
|
||||
return dsl.request.url.queryParameters
|
||||
}
|
||||
throw new IllegalStateException("No url provided")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.cloud.contract.spec.ContractConverter=\
|
||||
org.springframework.cloud.contract.verifier.spec.pact.PactContractConverter
|
||||
@@ -0,0 +1,290 @@
|
||||
package org.springframework.cloud.contract.verifier.spec.pact
|
||||
|
||||
import au.com.dius.pact.model.Pact
|
||||
import au.com.dius.pact.model.PactSpecVersion
|
||||
import groovy.json.JsonOutput
|
||||
import org.skyscreamer.jsonassert.JSONAssert
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
||||
import org.springframework.core.io.Resource
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Subject
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class PactContractConverterSpec extends Specification {
|
||||
|
||||
File pactJson = new File(PactContractConverterSpec.getResource("/pact/pact.json").toURI())
|
||||
@Subject PactContractConverter converter = new PactContractConverter()
|
||||
|
||||
def "should accept json files that are pact files"() {
|
||||
expect:
|
||||
converter.isAccepted(pactJson)
|
||||
}
|
||||
|
||||
def "should reject json files that are pact files"() {
|
||||
given:
|
||||
File invalidPact = new File(PactContractConverterSpec.getResource("/pact/invalid_pact.json").toURI())
|
||||
expect:
|
||||
converter.isAccepted(invalidPact)
|
||||
}
|
||||
|
||||
def "should convert from pact to contract"() {
|
||||
given:
|
||||
Contract expectedContract = Contract.make {
|
||||
description("a retrieve Mallory request a user with username 'username' and password 'password' exists")
|
||||
request {
|
||||
method(GET())
|
||||
url("/mallory") {
|
||||
queryParameters {
|
||||
parameter("name", "ron")
|
||||
parameter("status", "good")
|
||||
}
|
||||
}
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(id: "123", method: "create")
|
||||
stubMatchers {
|
||||
jsonPath('$.id', byRegex("[0-9]{3}"))
|
||||
}
|
||||
}
|
||||
response {
|
||||
status(200)
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body([[
|
||||
[email: "rddtGwwWMEhnkAPEmsyE",
|
||||
id: "eb0f8c17-c06a-479e-9204-14f7c95b63a6",
|
||||
userName: "AJQrokEGPAVdOHprQpKP"]
|
||||
]])
|
||||
testMatchers {
|
||||
jsonPath('$[0][*].email', byType())
|
||||
jsonPath('$[0][*].id', byRegex("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"))
|
||||
jsonPath('$[0]', byType() {
|
||||
maxOccurrence(5)
|
||||
})
|
||||
jsonPath('$[0][*].userName', byType())
|
||||
}
|
||||
}
|
||||
}
|
||||
when:
|
||||
Collection<Contract> contracts = converter.convertFrom(pactJson)
|
||||
then:
|
||||
contracts == [expectedContract]
|
||||
}
|
||||
|
||||
def "should convert from contract to pact"() {
|
||||
given:
|
||||
Collection<Contract> inputContracts = [
|
||||
Contract.make {
|
||||
description("a retrieve Mallory request")
|
||||
request {
|
||||
method(GET())
|
||||
url("/mallory") {
|
||||
queryParameters {
|
||||
parameter("name", "ron")
|
||||
parameter("status", "good")
|
||||
}
|
||||
}
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
id: 123,
|
||||
method: $(stub(regex("[0][1][2]"))),
|
||||
something: "foo"
|
||||
)
|
||||
stubMatchers {
|
||||
jsonPath('$.id', byRegex("[0-9]{3}"))
|
||||
jsonPath('$.something', byEquality())
|
||||
}
|
||||
}
|
||||
response {
|
||||
status(200)
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body([[
|
||||
[email: "rddtGwwWMEhnkAPEmsyE",
|
||||
id: "eb0f8c17-c06a-479e-9204-14f7c95b63a6",
|
||||
number: $(producer(regex("[0-9]{3}")), consumer(923)),
|
||||
something: "foo",
|
||||
userName: "AJQrokEGPAVdOHprQpKP"]
|
||||
]])
|
||||
testMatchers {
|
||||
jsonPath('$[0][*].email', byType())
|
||||
jsonPath('$[0][*].id', byRegex("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"))
|
||||
jsonPath('$[0]', byType() {
|
||||
minOccurrence(1)
|
||||
maxOccurrence(5)
|
||||
})
|
||||
jsonPath('$[0][*].userName', byType())
|
||||
jsonPath('$[0][*].something', byEquality())
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
String expectedJson = '''
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "a retrieve Mallory request",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "\\/mallory",
|
||||
"query": "name=ron&status=good",
|
||||
"headers": {
|
||||
"Content-Type": "application\\/json"
|
||||
},
|
||||
"body": {
|
||||
"id": 123,
|
||||
"method": "012",
|
||||
"something": "foo"
|
||||
},
|
||||
"matchingRules": {
|
||||
"$.id": {
|
||||
"match": "regex",
|
||||
"regex": "[0-9]{3}"
|
||||
},
|
||||
"$.something": {
|
||||
"match": "equality"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application\\/json"
|
||||
},
|
||||
"body": [
|
||||
[
|
||||
{
|
||||
"email": "rddtGwwWMEhnkAPEmsyE",
|
||||
"id": "eb0f8c17-c06a-479e-9204-14f7c95b63a6",
|
||||
"number": 923,
|
||||
"userName": "AJQrokEGPAVdOHprQpKP"
|
||||
}
|
||||
]
|
||||
],
|
||||
"matchingRules": {
|
||||
"$[0][*].email": {
|
||||
"match": "type"
|
||||
},
|
||||
"$[0][*].id": {
|
||||
"match": "regex",
|
||||
"regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
||||
},
|
||||
"$[0]": {
|
||||
"match": "type",
|
||||
"min": 1,
|
||||
"max": 5
|
||||
},
|
||||
"$[0][*].userName": {
|
||||
"match": "type"
|
||||
},
|
||||
"$[0][*].something": {
|
||||
"match": "equality"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
when:
|
||||
Pact pact = converter.convertTo(inputContracts)
|
||||
then:
|
||||
String actual = JsonOutput.toJson(pact.toMap(PactSpecVersion.V2))
|
||||
JSONAssert.assertEquals(expectedJson, actual, false)
|
||||
}
|
||||
|
||||
def "should fail to convert from contract to pact when contract has execution property in request"() {
|
||||
given:
|
||||
Collection<Contract> inputContracts = [
|
||||
Contract.make {
|
||||
request {
|
||||
method(GET())
|
||||
url("/mallory")
|
||||
body(
|
||||
id: $(c("foo"), p(execute("foo")))
|
||||
)
|
||||
}
|
||||
response {
|
||||
status(200)
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
when:
|
||||
converter.convertTo(inputContracts)
|
||||
then:
|
||||
def e = thrown(UnsupportedOperationException)
|
||||
e.message.contains("execution property")
|
||||
}
|
||||
|
||||
def "should fail to convert from contract to pact when contract has execution property in response"() {
|
||||
given:
|
||||
Collection<Contract> inputContracts = [
|
||||
Contract.make {
|
||||
request {
|
||||
method(GET())
|
||||
url("/mallory")
|
||||
}
|
||||
response {
|
||||
status(200)
|
||||
body(
|
||||
id: $(c(execute("foo")), p("foo"))
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
when:
|
||||
converter.convertTo(inputContracts)
|
||||
then:
|
||||
def e = thrown(UnsupportedOperationException)
|
||||
e.message.contains("execution property")
|
||||
}
|
||||
|
||||
def "should convert contracts from samples to pacts"() {
|
||||
given:
|
||||
Resource[] contractResources = new PathMatchingResourcePatternResolver().getResources("contracts/*.groovy")
|
||||
Resource[] pactResources = new PathMatchingResourcePatternResolver().getResources("contracts/*.json")
|
||||
Map<String, Collection<Contract>> contracts = contractResources.collectEntries { [(it.filename) : ContractVerifierDslConverter.convertAsCollection(it.file)] }
|
||||
Map<String, String> jsonPacts = pactResources.collectEntries { [(it.filename) : it.file.text] }
|
||||
when:
|
||||
Map<String, Pact> pacts = contracts.entrySet().collectEntries { [(it.key) : converter.convertTo(it.value)] }
|
||||
then:
|
||||
pacts.entrySet().each {
|
||||
String convertedPactAsText = JsonOutput.toJson(it.value.toMap(PactSpecVersion.V2))
|
||||
String pactFileName = it.key.replace("groovy", "json")
|
||||
println "File name [${it.key}]"
|
||||
JSONAssert.assertEquals(jsonPacts.get(pactFileName), convertedPactAsText, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// file creator
|
||||
/*
|
||||
pacts.entrySet().each {
|
||||
new File("target/${it.key.replace("groovy", "json")}").text = JsonOutput.toJson(it.value.toMap(PactSpecVersion.V2))
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,66 @@
|
||||
package contracts
|
||||
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request { // (1)
|
||||
method 'PUT' // (2)
|
||||
url '/fraudcheck' // (3)
|
||||
body([ // (4)
|
||||
clientId: $(c(regex('[0-9]{10}')), p("8532032713")),
|
||||
loanAmount: 99999
|
||||
])
|
||||
headers { // (5)
|
||||
contentType('application/vnd.fraud.v1+json')
|
||||
}
|
||||
}
|
||||
response { // (6)
|
||||
status 200 // (7)
|
||||
body([ // (8)
|
||||
fraudCheckStatus: "FRAUD",
|
||||
rejectionReason: "Amount too high"
|
||||
])
|
||||
headers { // (9)
|
||||
contentType('application/vnd.fraud.v1+json')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Since we don't want to force on the user to hardcode values of fields that are dynamic
|
||||
(timestamps, database ids etc.), one can parametrize those entries. If you wrap your field's
|
||||
value in a `$(...)` or `value(...)` and provide a dynamic value of a field then
|
||||
the concrete value will be generated for you. If you want to be really explicit about
|
||||
which side gets which value you can do that by using the `value(consumer(...), producer(...))` notation.
|
||||
That way what's present in the `consumer` section will end up in the produced stub. What's
|
||||
there in the `producer` will end up in the autogenerated test. If you provide only the
|
||||
regular expression side without the concrete value then Spring Cloud Contract will generate one for you.
|
||||
|
||||
From the Consumer perspective, when shooting a request in the integration test:
|
||||
|
||||
(1) - If the consumer sends a request
|
||||
(2) - With the "PUT" method
|
||||
(3) - to the URL "/fraudcheck"
|
||||
(4) - with the JSON body that
|
||||
* has a field `clientId` that matches a regular expression `[0-9]{10}`
|
||||
* has a field `loanAmount` that is equal to `99999`
|
||||
(5) - with header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
(6) - then the response will be sent with
|
||||
(7) - status equal `200`
|
||||
(8) - and JSON body equal to
|
||||
{ "fraudCheckStatus": "FRAUD", "rejectionReason": "Amount too high" }
|
||||
(9) - with header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
|
||||
From the Producer perspective, in the autogenerated producer-side test:
|
||||
|
||||
(1) - A request will be sent to the producer
|
||||
(2) - With the "PUT" method
|
||||
(3) - to the URL "/fraudcheck"
|
||||
(4) - with the JSON body that
|
||||
* has a field `clientId` that will have a generated value that matches a regular expression `[0-9]{10}`
|
||||
* has a field `loanAmount` that is equal to `99999`
|
||||
(5) - with header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
(6) - then the test will assert if the response has been sent with
|
||||
(7) - status equal `200`
|
||||
(8) - and JSON body equal to
|
||||
{ "fraudCheckStatus": "FRAUD", "rejectionReason": "Amount too high" }
|
||||
(9) - with header `Content-Type` matching `application/vnd.fraud.v1+json.*`
|
||||
*/
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"path": "/fraudcheck",
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"clientId": "8532032713",
|
||||
"loanAmount": 99999
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"fraudCheckStatus": "FRAUD",
|
||||
"rejectionReason": "Amount too high"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package contracts
|
||||
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
method 'PUT'
|
||||
url '/fraudcheck'
|
||||
body("""
|
||||
{
|
||||
"clientId":"${value(consumer(regex('[0-9]{10}')), producer('1234567890'))}",
|
||||
"loanAmount":123.123
|
||||
}
|
||||
"""
|
||||
)
|
||||
headers {
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
fraudCheckStatus: "OK",
|
||||
rejectionReason: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)')))
|
||||
)
|
||||
headers {
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"provider": {
|
||||
"name": "Provider"
|
||||
},
|
||||
"consumer": {
|
||||
"name": "Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "",
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"path": "/fraudcheck",
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"clientId": "1234567890",
|
||||
"loanAmount": 123.123
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/vnd.fraud.v1+json"
|
||||
},
|
||||
"body": {
|
||||
"fraudCheckStatus": "OK",
|
||||
"rejectionReason": null
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pact-specification": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pact-jvm": {
|
||||
"version": "2.4.18"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package contracts
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
|
||||
[
|
||||
Contract.make {
|
||||
request {
|
||||
name "should count all frauds"
|
||||
method GET()
|
||||
url '/frauds'
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
count: 200
|
||||
])
|
||||
headers {
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
}
|
||||
},
|
||||
Contract.make {
|
||||
request {
|
||||
method GET()
|
||||
url '/drunks'
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
count: 100
|
||||
])
|
||||
headers {
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user