diff --git a/README.adoc b/README.adoc index 6cd679fc50..4bb695ffdc 100644 --- a/README.adoc +++ b/README.adoc @@ -541,7 +541,6 @@ to the following in the build logs: 2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}] ---- - ==== Defining the Contract As consumers of services, we need to define what exactly we want to achieve. We need to @@ -2007,6 +2006,7 @@ have Docker installed. Here you can find the Spring Cloud Contract folder structure ``` +├── config ├── docker ├── samples ├── scripts @@ -2020,6 +2020,7 @@ Here you can find the Spring Cloud Contract folder structure └── tests ``` + - `config` - folder contains setup for Spring Cloud Release Tools automated release process - `docker` - folder contains docker images - `samples` - folder contains test samples together with standalone ones used also to build documentation - `scripts` - contains scripts to build and test `Spring Cloud Contract` with Maven, Gradle and standalone projects @@ -2027,6 +2028,7 @@ Here you can find the Spring Cloud Contract folder structure - `spring-cloud-contract-starters` - contains Spring Cloud Contract Starters - `spring-cloud-contract-spec` - contains specification modules (contains concept of a Contract) - `spring-cloud-contract-stub-runner` - contains Stub Runner related modules + - `spring-cloud-contract-stub-runner-boot` - contains Stub Runner Boot app - `spring-cloud-contract-tools` - Gradle and Maven plugin for `Spring Cloud Contract Verifier` - `spring-cloud-contract-verifier` - core of the `Spring Cloud Contract Verifier` functionality - `spring-cloud-contract-wiremock` - all WireMock related functionality diff --git a/docker/spring-cloud-contract-docker/project/build.gradle b/docker/spring-cloud-contract-docker/project/build.gradle index e8b5aa99e2..12a7e0b935 100644 --- a/docker/spring-cloud-contract-docker/project/build.gradle +++ b/docker/spring-cloud-contract-docker/project/build.gradle @@ -74,7 +74,7 @@ contracts { delegate.classifier = getProp("EXTERNAL_CONTRACTS_CLASSIFIER") ?: "" delegate.version = getProp("EXTERNAL_CONTRACTS_VERSION") ?: "+" } - contractsWorkOffline = Boolean.parseBoolean(getProp("EXTERNAL_CONTRACTS_WORK_OFFLINE")) ?: false + contractsMode = Boolean.parseBoolean(getProp("EXTERNAL_CONTRACTS_WORK_OFFLINE")) ? "LOCAL" : "REMOTE" } else { logger.lifecycle("Will use contracts from the mounted [/contracts] folder") // tests - contracts in this repo @@ -124,7 +124,11 @@ boolean publishEnabled = Boolean.parseBoolean(publishArtifacts) publish.setEnabled(publishEnabled) gradle.taskGraph.whenReady { graph -> - graph.allTasks.findAll { it.name.startsWith("publish") }*.setEnabled(publishEnabled) + graph.allTasks.findAll { it.name.startsWith("publish") && "publishStubsToScm" != it.name }*.setEnabled(publishEnabled) +} + +if (Boolean.parseBoolean(getProp("PUBLISH_STUBS_TO_SCM"))) { + publish.dependsOn("publishStubsToScm") } String getProp(String propName) { diff --git a/docs/src/main/asciidoc/building.adoc b/docs/src/main/asciidoc/building.adoc index 0812d93248..9e1cf9ef79 100644 --- a/docs/src/main/asciidoc/building.adoc +++ b/docs/src/main/asciidoc/building.adoc @@ -13,6 +13,7 @@ have Docker installed. Here you can find the Spring Cloud Contract folder structure ``` +├── config ├── docker ├── samples ├── scripts @@ -26,6 +27,7 @@ Here you can find the Spring Cloud Contract folder structure └── tests ``` + - `config` - folder contains setup for Spring Cloud Release Tools automated release process - `docker` - folder contains docker images - `samples` - folder contains test samples together with standalone ones used also to build documentation - `scripts` - contains scripts to build and test `Spring Cloud Contract` with Maven, Gradle and standalone projects @@ -33,6 +35,7 @@ Here you can find the Spring Cloud Contract folder structure - `spring-cloud-contract-starters` - contains Spring Cloud Contract Starters - `spring-cloud-contract-spec` - contains specification modules (contains concept of a Contract) - `spring-cloud-contract-stub-runner` - contains Stub Runner related modules + - `spring-cloud-contract-stub-runner-boot` - contains Stub Runner Boot app - `spring-cloud-contract-tools` - Gradle and Maven plugin for `Spring Cloud Contract Verifier` - `spring-cloud-contract-verifier` - core of the `Spring Cloud Contract Verifier` functionality - `spring-cloud-contract-wiremock` - all WireMock related functionality diff --git a/docs/src/main/asciidoc/migrations.adoc b/docs/src/main/asciidoc/migrations.adoc index d6c77f812a..a93194bee9 100644 --- a/docs/src/main/asciidoc/migrations.adoc +++ b/docs/src/main/asciidoc/migrations.adoc @@ -4,6 +4,9 @@ == Migrations +TIP: For up to date migration guides please visit +the project's https://github.com/spring-cloud/spring-cloud-contract/wiki/[wiki page]. + This section covers migrating from one version of Spring Cloud Contract Verifier to the next version. It covers the following versions upgrade paths: diff --git a/docs/src/main/asciidoc/spring-cloud-contract.adoc b/docs/src/main/asciidoc/spring-cloud-contract.adoc index a2e6e46d23..a0b79b8813 100644 --- a/docs/src/main/asciidoc/spring-cloud-contract.adoc +++ b/docs/src/main/asciidoc/spring-cloud-contract.adoc @@ -5,12 +5,12 @@ :numbered: :icons: font :sectlinks: true -:branch: 1.2.x +:branch: master = Spring Cloud Contract _Documentation Authors: Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, -Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant +Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant_ {spring-cloud-version} diff --git a/docs/src/main/asciidoc/verifier_contract.adoc b/docs/src/main/asciidoc/verifier_contract.adoc index ecdc08b09c..ffd89aa5ab 100644 --- a/docs/src/main/asciidoc/verifier_contract.adoc +++ b/docs/src/main/asciidoc/verifier_contract.adoc @@ -1606,4 +1606,56 @@ Now you can pick a folder with the source of your stubs. IMPORTANT: If you do not provide any implementation, then the default is used (scan classpath). If you provide the `stubsMode = StubRunnerProperties.StubsMode.LOCAL` or `, stubsMode = StubRunnerProperties.StubsMode.REMOTE` then the Aether implementation will be used -If you provide more than one, then the first one on the list is used. \ No newline at end of file +If you provide more than one, then the first one on the list is used. + +[[scm-stub-downloader]] +=== Using the SCM Stub Downloader + +Whenever the `repositoryRoot` starts with a SCM protocol +(currently we support only `git://`), the stub downloader will try +to clone the repository and use it as a source of contracts +to generate tests or stubs. + +Either via environment variables, system properties, properties set +inside the plugin or contracts repository configuration you can +tweak the downloader's behaviour. Below you can find the list of +properties + +.SCM Stub Downloader properties +|=== +|Type of a property |Name of the property | Description +| +* `git.branch` (plugin prop) +* `stubrunner.properties.git.branch` (system prop) +* `STUBRUNNER_PROPERTIES_GIT_BRANCH` (env prop) +|master +|Which branch to checkout + +| +* `git.username` (plugin prop) +* `stubrunner.properties.git.username` (system prop) +* `STUBRUNNER_PROPERTIES_GIT_USERNAME` (env prop) +| +|Git clone username + +| +* `git.password` (plugin prop) +* `stubrunner.properties.git.password` (system prop) +* `STUBRUNNER_PROPERTIES_GIT_PASSWORD` (env prop) +| +|Git clone password + +| +* `git.no-of-attempts` (plugin prop) +* `stubrunner.properties.git.no-of-attempts` (system prop) +* `STUBRUNNER_PROPERTIES_GIT_NO_OF_ATTEMPTS` (env prop) +|10 +|Number of attempts to push the commits to `origin` + +| +* `git.wait-between-attempts` (Plugin prop) +* `stubrunner.properties.git.wait-between-attempts` (system prop) +* `STUBRUNNER_PROPERTIES_GIT_WAIT_BETWEEN_ATTEMPTS` (env prop) +|1000 +|Number of millis to wait between attempts to push the commits to `origin` +|=== diff --git a/docs/src/main/asciidoc/verifier_faq.adoc b/docs/src/main/asciidoc/verifier_faq.adoc index 85be0b1dfc..fd1a8d0143 100644 --- a/docs/src/main/asciidoc/verifier_faq.adoc +++ b/docs/src/main/asciidoc/verifier_faq.adoc @@ -1,10 +1,12 @@ :introduction_url: https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/{branch} +:samples_branch: 2.0.x +:samples_branch: 2.0.x == Spring Cloud Contract FAQ === Why use Spring Cloud Contract Verifier and not X ? -For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you're already creating +For the time being Spring Cloud Contract is a JVM based tool. So it could be your first pick when you're already creating software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are: @@ -14,6 +16,8 @@ Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Cont - Automatic generation of tests from the defined Contract - Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory - Spring Cloud integration - no discovery service is needed for integration tests +- Spring Cloud Contract integrates with Pact out of the box and provides easy hooks to extend its functionality +- Via Docker adds support for any language & framework used === I don't want to write a contract in Groovy! @@ -249,7 +253,7 @@ consumer will you break with your local changes. Let's assume that we have a producer with coordinates `com.example:server` and 3 consumers: `client1`, `client2`, `client3`. Then in the repository with common contracts you would have the following setup -(which you can checkout https://github.com/spring-cloud/spring-cloud-contract/tree/1.0.x/samples/standalone/contracts[here]: +(which you can checkout https://github.com/spring-cloud/spring-cloud-contract/tree/{branch}/samples/standalone/contracts[here]): [source,bash,indent=0] ---- @@ -501,8 +505,8 @@ task deleteUnwantedContracts(type: Delete) { include: "**/*", excludes: [ "**/${project.name}/**"", - **/${first-topic}/**", - **/${second-topic}/**]) + "**/${first-topic}/**", + "**/${second-topic}/**"]) } ---- @@ -515,20 +519,193 @@ deleteUnwantedContracts.dependsOn("unzipContracts") build.dependsOn("deleteUnwantedContracts") ---- -- Configure plugin by specifying the directory containing contracts using ```contractsDslDir``` property +- Configure plugin by specifying the directory containing contracts using `contractsDslDir` property [source,groovy,indent=0] ---- contracts { - contractsDslDir = new File("${buildDir}/unpackedContracts") } ---- -=== Can I have multiple base classes for tests? +=== Do I need a Binary Storage? Can't I use Git? -Yes! Check out the https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_different_base_classes_for_contracts[Different base classes for contracts] sections -of either Gradle or Maven plugins. +In the polyglot world, there are languages that don't use binary storages like +Artifactory or Nexus. Starting from Spring Cloud Contract version 2.0.0 we provide +mechanisms to store contracts and stubs in a SCM repository. Currently the +only supported SCM is Git. + +The repository would have to the following setup +(which you can checkout https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/{samples_branch}/contracts_git/[here]): + +[source,indent=0] +---- +. +└── META-INF + └── com.example + └── beer-api-producer-git + └── 0.0.1-SNAPSHOT + ├── contracts + │   └── beer-api-consumer + │   ├── messaging + │   │   ├── shouldSendAcceptedVerification.groovy + │   │   └── shouldSendRejectedVerification.groovy + │   └── rest + │   ├── shouldGrantABeerIfOldEnough.groovy + │   └── shouldRejectABeerIfTooYoung.groovy + └── mappings + └── beer-api-consumer + └── rest + ├── shouldGrantABeerIfOldEnough.json + └── shouldRejectABeerIfTooYoung.json +---- + +Under `META-INF` folder: + +* we group applications via `groupId` (e.g. `com.example`) +* then each application is represented via the `artifactId` (e.g. `beer-api-producer-git`) +* next, the version of the application. The version is mandatory! (e.g. `0.0.1-SNAPSHOT`) +* finally, there are two folders: +** `contracts` - the good practice is to store the contracts required by each +consumer in the folder with the consumer name (e.g. `beer-api-consumer`). That way you +can use the `stubs-per-consumer` feature. Further directory structure is arbitrary. +** `mappings` - in this folder the Maven / Gradle Spring Cloud Contract plugins will push +the stub server mappings. On the consumer side, Stub Runner will scan this folder +to start stub servers with stub definitions. The folder structure will be a copy +of the one created in the `contracts` subfolder. + +==== Protocol convention + +In order to control the type and location of the source of contracts (whether it's +a binary storage or an SCM repository), you can use the protocol in the URL of +the repository. Spring Cloud Contract iterates over registered protocol resolvers +and tries to fetch the contracts (via a plugin) or stubs (via Stub Runner). + +For the SCM functionality, currently, we support the Git repository. To use it, +in the property, where the repository URL needs to be placed you just have to prefix +the connection URL with `git://`. Here you can find a couple of examples: + +[source,indent=0] +---- +git://file:///foo/bar +git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git +git://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git +---- + +==== Producer + +For the producer, to use the SCM approach, we can reuse the +same mechanism we use for external contracts. We route Spring Cloud Contract +to use the SCM implementation via the URL that contains +the `git://` protocol. + +IMPORTANT: You have to manually add the `pushStubsToScm` +goal in Maven or execute (bind) the `pushStubsToScm` task in +Gradle. We don't push stubs to `origin` of your git +repository out of the box. + +.Maven +[source,xml,indent=0] +---- + + org.springframework.cloud + spring-cloud-contract-maven-plugin + ${spring-cloud-contract.version} + true + + + + + git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + + + + REMOTE + + + + package + + + pushStubsToScm + + + + +---- + +.Gradle +[source,gradle,indent=0] +---- +contracts { + // We want to pick contracts from a Git repository + contractDependency { + stringNotation = "${project.group}:${project.name}:${project.version}" + } + /* + We reuse the contract dependency section to set up the path + to the folder that contains the contract definitions. In our case the + path will be /groupId/artifactId/version/contracts + */ + contractRepository { + repositoryUrl = "git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git" + } + // The mode can't be classpath + contractsMode = "REMOTE" + // Base class mappings etc. +} + +/* +In this scenario we want to publish stubs to SCM whenever +the `publish` task is executed +*/ +publish.dependsOn("publishStubsToScm") +---- + +With such a setup: + +* Git project will be cloned to a temporary directory +* The SCM stub downloader will go to `META-INF/groupId/artifactId/version/contracts` folder +to find contracts. E.g. for `com.example:foo:1.0.0` the path would be +`META-INF/com.example/foo/1.0.0/contracts` +* Tests will be generated from the contracts +* Stubs will be created from the contracts +* Once the tests pass, the stubs will be committed in the cloned repository +* Finally, a push will be done to that repo's `origin` + +==== Consumer + +On the consumer side when passing the `repositoryRoot` parameter, +either from the `@AutoConfigureStubRunner` annotation, the +JUnit rule or properties, it's enough to pass the URL of the +SCM repository, prefixed with the protocol. For example + +[source,java,indent=0] +---- +@AutoConfigureStubRunner( + stubsMode="REMOTE", + repositoryRoot="git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git", + ids="com.example:bookstore:0.0.1.RELEASE" +) +---- + +With such a setup: + +* Git project will be cloned to a temporary directory +* The SCM stub downloader will go to `META-INF/groupId/artifactId/version/` folder +to find stub definitions and contracts. E.g. for `com.example:foo:1.0.0` the path would be +`META-INF/com.example/foo/1.0.0/` +* Stub servers will be started and fed with mappings +* Messaging definitions will be read and used in the messaging tests === How can I debug the request/response being sent by the generated tests client? @@ -558,11 +735,6 @@ You can use the `mappingsOutputFolder` property on `@AutoConfigureStubRunner` or to dump all mappings per artifact id. Also the port at which the given stub server was started will be attached. -==== Can I reference the request from the response? - -Yes! With version 1.1.0 we've added such a possibility. On the HTTP stub server side we're providing support -for this for WireMock. In case of other HTTP server stubs you'll have to implement the approach yourself. - ==== Can I reference text from file? Yes! With version 1.2.0 we've added such a possibility. It's enough to call `file(...)` method in the diff --git a/docs/src/main/asciidoc/verifier_introduction.adoc b/docs/src/main/asciidoc/verifier_introduction.adoc index 166e0fd844..ba81ef9acb 100644 --- a/docs/src/main/asciidoc/verifier_introduction.adoc +++ b/docs/src/main/asciidoc/verifier_introduction.adoc @@ -497,7 +497,6 @@ to the following in the build logs: 2016-07-19 14:22:27.737 INFO 41050 --- [ main] o.s.c.c.stubrunner.StubRunnerExecutor : All stubs are now running RunningStubs [namesAndPorts={com.example:http-server:0.0.1-SNAPSHOT:stubs=8080}] ---- - ==== Defining the Contract As consumers of services, we need to define what exactly we want to achieve. We need to diff --git a/docs/src/main/asciidoc/verifier_setup.adoc b/docs/src/main/asciidoc/verifier_setup.adoc index 54f642adbc..36fdb434c2 100644 --- a/docs/src/main/asciidoc/verifier_setup.adoc +++ b/docs/src/main/asciidoc/verifier_setup.adoc @@ -23,6 +23,7 @@ following sections: * <> * <> * <> +* <> * <> [[gradle-prerequisites]] @@ -246,6 +247,8 @@ from the Groovy DSL should be placed. By default its value is the Groovy DSL should be placed. * *targetFramework*: Specifies the target test framework to be used. Currently, Spock and JUnit are supported with JUnit being the default framework. +* *contractsProperties*: a map containing properties to be passed to Spring Cloud Contract +components. Those properties might be used by e.g. inbuilt or custom Stub Downloaders. The following properties are used when you want to specify the location of the JAR containing the contracts: @@ -334,6 +337,25 @@ To ensure that the provider side is compliant with defined contracts, you need t ./gradlew generateContractTests test ---- +[[gradle-pushing-stubs-to-scm]] +==== Pushing stubs to SCM + +If you're using the SCM repository to keep the contracts and +stubs, you might want to automate the step of pushing stubs to +the repository. To do that, it's enough to call the `pushStubsToScm` +task. Example: + +[source,bash,indent=0] +---- +$ ./gradlew pushStubsToScm +---- + +Under <> you can find all possible +configuration options that you can pass either via +the `contractsProperties` field e.g. `contracts { contractsProperties = [foo:"bar"] }`, +via `contractsProperties` method e.g. `contracts { contractsProperties([foo:"bar"]) }`, +a system property or an environment variable. + [[gradle-consumer]] ==== Spring Cloud Contract Verifier on the Consumer Side @@ -395,6 +417,7 @@ following sections: * <> * <> * <> +* <> * <> [[maven-add-plugin]] @@ -576,6 +599,8 @@ the matched contract. For example, if you have a contract under `.* -> com.example.base.BaseClass`, then the test class generated from these contracts extends `com.example.base.BaseClass`. This setting takes precedence over *packageWithBaseClasses* and *baseClassForTests*. +* *contractsProperties*: a map containing properties to be passed to Spring Cloud Contract +components. Those properties might be used by e.g. inbuilt or custom Stub Downloaders. If you want to download your contract definitions from a Maven repository, you can use the following options: @@ -766,6 +791,57 @@ For Groovy Spock code, use the following: To ensure that provider side is compliant with defined contracts, you need to invoke `mvn generateTest test`. +[[maven-pushing-stubs-to-scm]] +==== Pushing stubs to SCM + +If you're using the SCM repository to keep the contracts and +stubs, you might want to automate the step of pushing stubs to +the repository. To do that, it's enough to add the `pushStubsToScm` +goal. Example: + +[source,xml,indent=0] +---- + + org.springframework.cloud + spring-cloud-contract-maven-plugin + ${spring-cloud-contract.version} + true + + + + + git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + + + + REMOTE + + + + package + + + pushStubsToScm + + + + +---- + +Under <> you can find all possible +configuration options that you can pass either via +the `` map, a system property +or an environment variable. + [[maven-sts]] ==== Maven Plugin and STS diff --git a/pom.xml b/pom.xml index f8d44a55f2..dccf5b0ad0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,12 +24,22 @@ 2.17 + 0.0.9 2.0.0.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT Elmhurst.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT 2.0.0.BUILD-SNAPSHOT + 5.0.3 + 3.2.4 + 1.0-groovy-2.4 + 0.5.1 + 2.0.0.RELEASE + 0.2.2 + 1.1 + 4.0.6 + 4.6.0.201612231935-r @@ -60,32 +70,32 @@ net.sf.jopt-simple jopt-simple - 5.0.3 + ${jopt-simple.version} cglib cglib - 3.2.4 + ${cglib.version} org.spockframework spock-spring - 1.0-groovy-2.4 + ${spock-spring.version} org.spockframework spock-core - 1.0-groovy-2.4 + ${spock-spring.version} info.solidsoft.spock spock-global-unroll - 0.5.1 + ${spock-global-unroll.version} org.springframework.amqp spring-rabbit - 2.0.0.RC2 + ${spring-rabbit.version} org.mockito @@ -94,12 +104,12 @@ io.specto hoverfly-junit - 0.2.2 + ${hoverfly-junit.version} org.apache.commons commons-text - 1.1 + ${commons-text.version} au.com.dius @@ -109,8 +119,32 @@ com.github.jknack handlebars - 4.0.6 + ${handlebars.version} + + + + org.eclipse.jgit + org.eclipse.jgit + ${org.eclipse.jgit.version} + + + + com.jcraft + jsch.agentproxy.sshagent + ${jsch-agent.version} + + + com.jcraft + jsch.agentproxy.jsch + ${jsch-agent.version} + + + com.jcraft + jsch.agentproxy.usocket-jna + ${jsch-agent.version} + + org.springframework.cloud spring-cloud-contract-dependencies diff --git a/samples/standalone/messaging/stream-source/build.gradle b/samples/standalone/messaging/stream-source/build.gradle index c4a3608c97..0e2ced8d95 100644 --- a/samples/standalone/messaging/stream-source/build.gradle +++ b/samples/standalone/messaging/stream-source/build.gradle @@ -59,7 +59,7 @@ dependencies { testCompile "com.jayway.restassured:spring-mock-mvc:2.9.0" } -task stubsJar(type: Jar, dependsOn: "generateWireMockClientStubs") { +task stubsJar(type: Jar, dependsOn: "generateClientStubs") { baseName = "${project.name}" classifier = "stubs" from stubsOutputDirRoot diff --git a/spring-cloud-contract-stub-runner/pom.xml b/spring-cloud-contract-stub-runner/pom.xml index 9fb26c48b3..36c0f44aad 100644 --- a/spring-cloud-contract-stub-runner/pom.xml +++ b/spring-cloud-contract-stub-runner/pom.xml @@ -64,6 +64,25 @@ junit junit + + + org.eclipse.jgit + org.eclipse.jgit + + + + com.jcraft + jsch.agentproxy.sshagent + + + com.jcraft + jsch.agentproxy.jsch + + + com.jcraft + jsch.agentproxy.usocket-jna + + io.specto hoverfly-junit diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java index 55d6cf3aca..aa9245c334 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java @@ -23,7 +23,7 @@ import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.RepositoryPolicy; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; +import org.springframework.util.StringUtils; import shaded.org.apache.maven.repository.internal.MavenRepositorySystemUtils; import shaded.org.apache.maven.settings.Settings; import shaded.org.apache.maven.settings.building.DefaultSettingsBuilderFactory; diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java index 06df4643ec..366eb6986a 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java @@ -1,35 +1,27 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.stubrunner; import java.io.File; -import java.io.IOException; import java.net.URI; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.AbstractMap; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Queue; -import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; @@ -50,7 +42,6 @@ import org.springframework.cloud.contract.stubrunner.StubRunnerOptions.StubRunne import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; import org.springframework.util.StringUtils; -import static java.nio.file.Files.createTempDirectory; import static org.springframework.cloud.contract.stubrunner.AetherFactories.newRepositorySystem; import static org.springframework.cloud.contract.stubrunner.AetherFactories.newSession; import static org.springframework.cloud.contract.stubrunner.util.ZipCategory.unzipTo; @@ -60,13 +51,6 @@ import static org.springframework.cloud.contract.stubrunner.util.ZipCategory.unz */ public class AetherStubDownloader implements StubDownloader { - /** - * There are problems with removal of stubs unpacked to a temporary folder. - * That's why we're creating a bounded in-memory storage of unpacked files - * and later we register a shutdown hook to remove all these files. - */ - private static final Queue TEMP_FILES_LOG = new LinkedBlockingQueue<>(1000); - private static final Logger log = LoggerFactory.getLogger(AetherStubDownloader.class); private static final String TEMP_DIR_PREFIX = "contracts"; @@ -74,7 +58,8 @@ public class AetherStubDownloader implements StubDownloader { private static final String LATEST_ARTIFACT_VERSION = "(,]"; private static final String LATEST_VERSION_IN_IVY = "+"; private static final String STUBRUNNER_SNAPSHOT_CHECK_SKIP_SYSTEM_PROP = "stubrunner.snapshot-check-skip"; - private static final String STUBRUNNER_SNAPSHOT_CHECK_SKIP_ENV_VAR = "STUBRUNNER_SNAPSHOT_CHECK_SKIP"; + // Preloading class for the shutdown hook not to throw ClassNotFound + private static final Class CLAZZ = TemporaryFileStorage.class; private final List remoteRepos; private final RepositorySystem repositorySystem; @@ -95,9 +80,10 @@ public class AetherStubDownloader implements StubDownloader { log.info("Remote repos not passed but the switch to work offline was set. " + "Stubs will be used from your local Maven repository."); break; case REMOTE: - if (remoteReposMissing) + if (remoteReposMissing) { throw new IllegalStateException( "Remote repositories for stubs are not specified and work offline flag wasn't passed"); + } break; case CLASSPATH: throw new UnsupportedOperationException( @@ -140,7 +126,7 @@ public class AetherStubDownloader implements StubDownloader { if (stubRunnerOptions.stubRepositoryRoot == null) { return new ArrayList<>(); } - final String[] repos = stubRunnerOptions.stubRepositoryRoot.split(","); + final String[] repos = stubRunnerOptions.getStubRepositoryRootAsString().split(","); final List remoteRepos = new ArrayList<>(); for (int i = 0; i < repos.length; i++) { if(StringUtils.hasText(repos[i])) { @@ -165,7 +151,7 @@ public class AetherStubDownloader implements StubDownloader { private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier) { log.info("Resolved version is [" + resolvedVersion + "]"); - if (!StringUtils.hasText(resolvedVersion)) { + if (StringUtils.isEmpty(resolvedVersion)) { log.warn("Stub for group [" + stubsGroup + "] module [" + stubsModule + "] and classifier [" + classifier + "] not found in " + this.remoteRepos); @@ -204,20 +190,7 @@ public class AetherStubDownloader implements StubDownloader { } private boolean skipSnapshotCheck() { - // still checking the system / env props setting for backward compatibility - // when running this for plugins - String skipSnapCheckProp = System.getProperty(STUBRUNNER_SNAPSHOT_CHECK_SKIP_SYSTEM_PROP); - String skipSnapCheckEnv = getSkipSnapEnvProp(); - if (StringUtils.hasText(skipSnapCheckProp)) { - return Boolean.parseBoolean(skipSnapCheckProp); - } - return StringUtils.hasText(skipSnapCheckEnv) && Boolean - .parseBoolean(skipSnapCheckEnv); - } - - // Visible for testing - String getSkipSnapEnvProp() { - return System.getenv(STUBRUNNER_SNAPSHOT_CHECK_SKIP_ENV_VAR); + return StubRunnerPropertyUtils.isPropertySet(STUBRUNNER_SNAPSHOT_CHECK_SKIP_SYSTEM_PROP); } private boolean resolvedFromLocalRepo(ArtifactResult result) { @@ -230,7 +203,7 @@ public class AetherStubDownloader implements StubDownloader { private String getVersion(String stubsGroup, String stubsModule, String version, String classifier) { - if (!StringUtils.hasText(version) || LATEST_VERSION_IN_IVY.equals(version)) { + if (StringUtils.isEmpty(version) || LATEST_VERSION_IN_IVY.equals(version)) { log.info("Desired version is [" + version + "] - will try to resolve the latest version"); return resolveHighestArtifactVersion(stubsGroup, stubsModule, classifier, LATEST_ARTIFACT_VERSION); @@ -282,65 +255,16 @@ public class AetherStubDownloader implements StubDownloader { } private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped; - try { - tmpDirWhereStubsWillBeUnzipped = createTempDirectory(TEMP_DIR_PREFIX) - .toFile(); - } - catch (IOException e) { - throw new IllegalStateException("Cannot create tmp dir with prefix: [" + TEMP_DIR_PREFIX + "]", e); - } - tmpDirWhereStubsWillBeUnzipped.deleteOnExit(); + File tmpDirWhereStubsWillBeUnzipped = TemporaryFileStorage.unpackStubJarToATemporaryFolder(TEMP_DIR_PREFIX); log.info("Unpacking stub from JAR [URI: " + stubJarUri + "]"); unzipTo(new File(stubJarUri), tmpDirWhereStubsWillBeUnzipped); - TEMP_FILES_LOG.add(tmpDirWhereStubsWillBeUnzipped); + TemporaryFileStorage.add(tmpDirWhereStubsWillBeUnzipped); return tmpDirWhereStubsWillBeUnzipped; } private void registerShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { - cleanup(); - } - }); + Runtime.getRuntime().addShutdownHook(new Thread( + () -> TemporaryFileStorage.cleanup(AetherStubDownloader.this.deleteStubsAfterTest))); } - private void cleanup() { - if (!this.deleteStubsAfterTest) { - return; - } - try { - for (File file : TEMP_FILES_LOG) { - if (file.isDirectory()) { - Files.walkFileTree(file.toPath(), new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (log.isTraceEnabled()) { - log.trace("Removing unzipped file [" + file + "]"); - } - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - if (log.isTraceEnabled()) { - log.trace("Removing unzipped dir [" + dir + "]"); - } - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - } else { - Files.delete(file.toPath()); - } - } - } catch (NoClassDefFoundError | IOException e) { - // Added NoClassDefFoundError cause sometimes it's visible in the builds - // this error is completely harmless - if (log.isTraceEnabled()) { - log.trace("Failed to remove temporary file", e); - } - } - } } \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ClasspathStubProvider.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ClasspathStubProvider.java index c288d66e9e..2d8b1baf57 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ClasspathStubProvider.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ClasspathStubProvider.java @@ -18,7 +18,6 @@ import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @@ -168,9 +167,9 @@ public class ClasspathStubProvider implements StubDownloaderBuilder { private List repoRoot(StubRunnerOptions stubRunnerOptions, StubConfiguration configuration) { - if (StringUtils.hasText(stubRunnerOptions.getStubRepositoryRoot())) { + if (stubRunnerOptions.getStubRepositoryRoot() != null) { return Collections - .singletonList(new RepoRoot(stubRunnerOptions.getStubRepositoryRoot())); + .singletonList(new RepoRoot(stubRunnerOptions.getStubRepositoryRootAsString())); } else { String path = "/**/" + configuration.getGroupId() + "/" + configuration.getArtifactId(); diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/CompositeStubDownloaderBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/CompositeStubDownloaderBuilder.java index 5d19b0ab0d..076b6c5309 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/CompositeStubDownloaderBuilder.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/CompositeStubDownloaderBuilder.java @@ -1,8 +1,25 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.stubrunner; import java.io.File; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -38,6 +55,12 @@ class CompositeStubDownloader implements StubDownloader { StubRunnerOptions stubRunnerOptions) { this.builders = builders; this.stubRunnerOptions = stubRunnerOptions; + if (log.isDebugEnabled()) { + log.debug("Registered following stub downloaders " + this.builders + .stream() + .map(b -> b.getClass().getName()) + .collect(Collectors.toList())); + } } @Override public Map.Entry downloadAndUnpackStubJar( @@ -47,10 +70,20 @@ class CompositeStubDownloader implements StubDownloader { if (downloader == null) { continue; } + if (log.isDebugEnabled()) { + log.debug("Found a matching stub downloader [" + downloader.getClass().getName() + "]"); + } Map.Entry entry = downloader .downloadAndUnpackStubJar(stubConfiguration); if (entry != null) { + if (log.isDebugEnabled()) { + log.debug("Found a matching entry [" + entry + "] by stub downloader [" + downloader.getClass().getName() + "]"); + } return entry; + } else { + log.warn("Stub Downloader [" + downloader.getClass().getName() + "] " + + "failed to find an entry for [" + stubConfiguration.toColonSeparatedDependencyNotation() + "]. " + + "Will proceed to the next one"); } } return null; diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java index 539c7e5c6e..6f34f9fec6 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java @@ -1,14 +1,30 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.stubrunner; +import java.io.File; +import java.lang.invoke.MethodHandles; +import java.util.Map; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties; import org.springframework.util.StringUtils; -import java.io.File; -import java.lang.invoke.MethodHandles; -import java.util.Map; - /** * Downloads a JAR with contracts and sets up the plugin configuration with proper * inclusion patterns @@ -26,15 +42,18 @@ public class ContractDownloader { private final String contractsPath; private final String projectGroupId; private final String projectArtifactId; + private final String projectVersion; public ContractDownloader(StubDownloader stubDownloader, StubConfiguration contractsJarStubConfiguration, - String contractsPath, String projectGroupId, String projectArtifactId) { + String contractsPath, String projectGroupId, String projectArtifactId, + String projectVersion) { this.stubDownloader = stubDownloader; this.contractsJarStubConfiguration = contractsJarStubConfiguration; this.contractsPath = contractsPath; this.projectGroupId = projectGroupId; this.projectArtifactId = projectArtifactId; + this.projectVersion = projectVersion; } /** @@ -60,9 +79,16 @@ public class ContractDownloader { log.info("Will pick a pattern from the contractPath property"); includedAntPattern = wrapWithAntPattern(contractsPath()); } else { - pattern = groupArtifactToPattern(contractsDirectory); log.info("Will pick a pattern from group id and artifact id"); - includedAntPattern = wrapWithAntPattern(slashSeparatedGroupId() + "/" + this.projectArtifactId); + if (hasGavInPath(contractsDirectory)) { + contractsDirectory = contractsSubDirIfPresent(contractsDirectory); + // we're already under proper folder (for the given version) + pattern = fileToPattern(contractsDirectory); + includedAntPattern = "**/"; + } else { + pattern = groupArtifactToPattern(contractsDirectory); + includedAntPattern = wrapWithAntPattern(slashSeparatedGroupId() + "/" + this.projectArtifactId); + } } log.info("Pattern to pick contracts equals [" + pattern + "]"); log.info("Ant Pattern to pick files equals [" + includedAntPattern + "]"); @@ -71,6 +97,36 @@ public class ContractDownloader { return config; } + private File contractsSubDirIfPresent(File contractsDirectory) { + File contracts = new File(contractsDirectory, "contracts"); + if (contracts.exists()) { + if (log.isDebugEnabled()) { + log.debug("Contracts folder found [" + contracts + "]"); + } + contractsDirectory = contracts; + } + return contractsDirectory; + } + + private boolean hasGavInPath(File file) { + return hasVersionInPath(file) && hasSeparatedGroupInPath(file, File.separator) + || hasSeparatedGroupInPath(file, "."); + } + + private boolean hasVersionInPath(File file) { + return file.getAbsolutePath() + .contains(this.projectVersion); + } + + private boolean hasSeparatedGroupInPath(File file, String separator) { + return file.getAbsolutePath() + .contains(groupAndArtifact(separator)); + } + + private String groupAndArtifact(String separator) { + return this.projectGroupId + separator + this.projectArtifactId; + } + private String patternFromProperty(File contractsDirectory) { return ("^" + contractsDirectory.getAbsolutePath() + "(" + File.separator + ")?" + ".*" + @@ -114,6 +170,12 @@ public class ContractDownloader { ".*$").replace("\\", "\\\\"); } + private String fileToPattern(File contractsDirectory) { + return ("^" + + contractsDirectory.getAbsolutePath() + + ".*$").replace("\\", "\\\\"); + } + private String slashSeparatedGroupId() { return this.projectGroupId.replace(".", File.separator); } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractProjectUpdater.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractProjectUpdater.java new file mode 100644 index 0000000000..6c27dbafac --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractProjectUpdater.java @@ -0,0 +1,183 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; + +/** + * Updates the project containing contracts. + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +public class ContractProjectUpdater { + + private static final Logger log = LoggerFactory.getLogger(ContractProjectUpdater.class); + private static final int DEFAULT_ATTEMPTS_NO = 10; + private static final long DEFAULT_WAIT_BETWEEN_ATTEMPTS = 1000; + // TODO: Add this to the documentation + private static final String DEFAULT_COMMIT_MESSAGE = "Updating project [$project] with stubs"; + private static final String GIT_ATTEMPTS_NO_PROP = "git.no-of-attempts"; + private static final String GIT_WAIT_BETWEEN_ATTEMPTS = "git.wait-between-attempts"; + private static final String GIT_COMMIT_MESSAGE = "git.commit-message"; + + private final StubRunnerOptions stubRunnerOptions; + private final GitContractsRepo gitContractsRepo; + + public ContractProjectUpdater(StubRunnerOptions stubRunnerOptions) { + this.stubRunnerOptions = stubRunnerOptions; + this.gitContractsRepo = new GitContractsRepo(stubRunnerOptions); + } + + /** + * Merges the folder with stubs with the project containing contracts + * @param projectName + * @param rootStubsFolder + */ + public void updateContractProject(String projectName, Path rootStubsFolder) { + File clonedRepo = this.gitContractsRepo + .clonedRepo(this.stubRunnerOptions.stubRepositoryRoot); + copyStubs(projectName, rootStubsFolder, clonedRepo); + GitRepo gitRepo = new GitRepo(clonedRepo); + String msg = StubRunnerPropertyUtils.getProperty(this.stubRunnerOptions.getProperties(), + GIT_COMMIT_MESSAGE); + GitRepo.CommitResult commit = gitRepo + .commit(clonedRepo, commitMessage(projectName, msg)); + if (commit == GitRepo.CommitResult.EMPTY) { + log.info("There were no changes to commit. Won't push the changes"); + return; + } + String attempts = StubRunnerPropertyUtils.getProperty(this.stubRunnerOptions.getProperties(), + GIT_ATTEMPTS_NO_PROP); + int intAttempts = StringUtils.hasText(attempts) ? Integer.parseInt(attempts) : DEFAULT_ATTEMPTS_NO; + String wait = StubRunnerPropertyUtils.getProperty(this.stubRunnerOptions.getProperties(), + GIT_WAIT_BETWEEN_ATTEMPTS); + long longWait = StringUtils.hasText(wait) ? Long.parseLong(wait) : DEFAULT_WAIT_BETWEEN_ATTEMPTS; + tryToPushCurrentBranch(clonedRepo, gitRepo, intAttempts, longWait); + } + + private void tryToPushCurrentBranch(File clonedRepo, GitRepo gitRepo, int intAttempts, + long longWait) { + int currentAttempt = 0; + while(currentAttempt < intAttempts) { + log.info("Trying to push changes, attempt " + (currentAttempt + 1) + "/" + intAttempts); + gitRepo.pull(clonedRepo); + log.info("Successfully pulled changes from remote for project with contract and stubs"); + try { + gitRepo.pushCurrentBranch(clonedRepo); + log.info("Successfully pushed changes with current stubs"); + break; + } catch (IllegalStateException e) { + // empty + log.error("Exception occurred while trying to push the changes", e); + currentAttempt++; + if (currentAttempt == intAttempts) { + throw new IllegalStateException("Failed to push changes to the project with contracts and stubs. Exceeded number of retries [" + intAttempts + "]"); + } + try { + Thread.sleep(longWait); + } + catch (InterruptedException e1) { + throw new IllegalStateException(e1); + } + } + } + } + + private String commitMessage(String projectName, String msg) { + return StringUtils.hasText(msg) ? + replaceProject(projectName, msg) : + replaceProject(projectName, DEFAULT_COMMIT_MESSAGE); + } + + private String replaceProject(String projectName, String msg) { + return msg.replace("$project", projectName); + } + + private void copyStubs(String projectName, Path rootStubsFolder, File clonedRepo) { + try { + if (log.isDebugEnabled()) { + log.debug("Copying stubs from [" + rootStubsFolder.toString() + "] to the cloned repo [" + clonedRepo.getAbsolutePath() + "] for project [" + projectName + "]"); + } + Files.walkFileTree(rootStubsFolder, + new DirectoryCopyingVisitor(rootStubsFolder, clonedRepo.toPath())); + if (log.isDebugEnabled()) { + log.debug("Successfully copied stubs to the cloned repo for project [" + projectName + "]"); + } + } + catch (IOException e) { + throw new IllegalStateException(e); + } + } +} + +class DirectoryCopyingVisitor extends SimpleFileVisitor { + + private static final Log log = LogFactory.getLog(DirectoryCopyingVisitor.class); + private final Path from; + private final Path to; + + DirectoryCopyingVisitor(Path from, Path to) { + this.from = from; + this.to = to; + if (log.isDebugEnabled()) { + log.debug("Will copy from [" + from.toString() + "] to [" + to.toString() + "]"); + } + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + Path relativePath = this.from.relativize(dir); + if (".git".equals(relativePath.toString())) { + return FileVisitResult.SKIP_SUBTREE; + } + Path targetPath = this.to.resolve(relativePath); + if (!Files.exists(targetPath)) { + if (log.isDebugEnabled()) { + log.debug("Created a folder [" + targetPath.toString() + "]"); + } + Files.createDirectory(targetPath); + } else { + if (log.isDebugEnabled()) { + log.debug("Folder [" + targetPath.toString() + "] already exists"); + } + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Path relativePath = this.to.resolve(this.from.relativize(file)); + Files.copy(file, relativePath, StandardCopyOption.REPLACE_EXISTING); + if (log.isDebugEnabled()) { + log.debug("Copied file from [" + file.toString() + "] to [" + relativePath.toString() + "]"); + } + return FileVisitResult.CONTINUE; + } +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java new file mode 100644 index 0000000000..d90aaa71ed --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/GitRepo.java @@ -0,0 +1,392 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import com.jcraft.jsch.IdentityRepository; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.jcraft.jsch.agentproxy.AgentProxyException; +import com.jcraft.jsch.agentproxy.Connector; +import com.jcraft.jsch.agentproxy.RemoteIdentityRepository; +import com.jcraft.jsch.agentproxy.USocketFactory; +import com.jcraft.jsch.agentproxy.connector.SSHAgentConnector; +import com.jcraft.jsch.agentproxy.usocket.JNAUSocketFactory; +import org.eclipse.jgit.api.CheckoutCommand; +import org.eclipse.jgit.api.CloneCommand; +import org.eclipse.jgit.api.CreateBranchCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.ListBranchCommand; +import org.eclipse.jgit.api.PullCommand; +import org.eclipse.jgit.api.PushCommand; +import org.eclipse.jgit.api.ResetCommand; +import org.eclipse.jgit.api.TransportConfigCallback; +import org.eclipse.jgit.api.errors.EmtpyCommitException; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.transport.CredentialsProvider; +import org.eclipse.jgit.transport.JschConfigSessionFactory; +import org.eclipse.jgit.transport.OpenSshConfig; +import org.eclipse.jgit.transport.SshTransport; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ResourceUtils; + +/** + * Abstraction over a Git repo. Can cloned repo from a given location + * and check its branch. + * + * taken from: https://github.com/spring-cloud/spring-cloud-release-tools + * + * @author Marcin Grzejszczak + */ +class GitRepo { + + private static final Logger log = LoggerFactory.getLogger(GitRepo.class); + + private final JGitFactory gitFactory; + + private final File basedir; + + GitRepo(File basedir, GitStubDownloaderProperties properties) { + this.basedir = basedir; + this.gitFactory = new JGitFactory(properties); + } + + // for tests + GitRepo(File basedir) { + this.basedir = basedir; + this.gitFactory = new JGitFactory(); + } + + // for tests + GitRepo(File basedir, JGitFactory factory) { + this.basedir = basedir; + this.gitFactory = factory; + } + + /** + * Clones the project + * @param projectUri - URI of the project + * @return file where the project was cloned + */ + File cloneProject(URI projectUri) { + try { + log.info("Cloning repo from [{}] to [{}]", projectUri, this.basedir); + Git git = cloneToBasedir(projectUri, this.basedir); + if (git != null) { + git.close(); + } + File clonedRepo = git.getRepository().getWorkTree(); + log.info("Cloned repo to [{}]", clonedRepo); + return clonedRepo; + } + catch (Exception e) { + throw new IllegalStateException("Exception occurred while cloning repo", e); + } + } + + /** + * Checks out a branch for a project + * @param project - a Git project + * @param branch - branch to check out + */ + void checkout(File project, String branch) { + try { + String currentBranch = currentBranch(project); + if (currentBranch.equals(branch)) { + log.info("Won't check out the same branch. Skipping"); + return; + } + log.info("Checking out branch [{}]", branch); + checkoutBranch(project, branch); + log.info("Successfully checked out the branch [{}]", branch); + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + + /** + * Pulls changes for the project + * @param project - a Git project + */ + void pull(File project) { + try { + try (Git git = this.gitFactory.open(project)) { + PullCommand command = this.gitFactory.pull(git); + command.setRebase(true).call(); + } + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } + + /** + * Performs a commit + * @param project - a Git project + * @param message - commit message + */ + CommitResult commit(File project, String message) { + try(Git git = this.gitFactory.open(file(project))) { + git.add().addFilepattern(".").call(); + git.commit().setAllowEmpty(false).setMessage(message).call(); + log.info("Commited successfully with message [" + message + "]"); + return CommitResult.SUCCESSFUL; + } catch (EmtpyCommitException e) { + log.info("There were no changes detected. Will not commit an empty commit"); + return CommitResult.EMPTY; + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + void reset(File project) { + try(Git git = this.gitFactory.open(file(project))) { + git.reset().setMode(ResetCommand.ResetType.HARD).call(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + enum CommitResult { + SUCCESSFUL, EMPTY + } + + /** + * Pushes the commits od current branch + * @param project - Git project + */ + void pushCurrentBranch(File project) { + try(Git git = this.gitFactory.open(file(project))) { + this.gitFactory.push(git).call(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + private File file(File project) throws FileNotFoundException { + return ResourceUtils.getFile(project.toURI()).getAbsoluteFile(); + } + + private Git cloneToBasedir(URI projectUrl, File destinationFolder) { + String url = projectUrl.toString(); + String projectGitUrl = url.endsWith(".git") ? url : url + ".git"; + if (log.isDebugEnabled()) { + log.debug("Project git url [" + projectGitUrl + "]"); + } + CloneCommand command = this.gitFactory.getCloneCommandByCloneRepository() + .setURI(projectGitUrl).setDirectory(destinationFolder); + try { + Git git = command.call(); + if (git.getRepository().getRemoteNames().isEmpty()) { + log.info("No remote added. Will add remote of the cloned project"); + git.remoteSetUrl().setUri(new URIish(projectGitUrl)); + git.remoteSetUrl().setName("origin"); + git.remoteSetUrl().setPush(true); + } + return git; + } + catch (GitAPIException | URISyntaxException e) { + deleteBaseDirIfExists(); + throw new IllegalStateException(e); + } + } + + private Ref checkoutBranch(File projectDir, String branch) + throws GitAPIException { + Git git = this.gitFactory.open(projectDir); + CheckoutCommand command = git.checkout().setName(branch); + try { + if (shouldTrack(git, branch)) { + trackBranch(command, branch); + } + return command.call(); + } + catch (GitAPIException e) { + deleteBaseDirIfExists(); + throw e; + } finally { + git.close(); + } + } + + private String currentBranch(File projectDir) { + Git git = this.gitFactory.open(projectDir); + try { + return git.getRepository().getBranch(); + } + catch (IOException e) { + throw new IllegalStateException(e); + } + finally { + git.close(); + } + } + + private boolean shouldTrack(Git git, String label) throws GitAPIException { + return isBranch(git, label) && !isLocalBranch(git, label); + } + + private void trackBranch(CheckoutCommand checkout, String label) { + checkout.setCreateBranch(true).setName(label) + .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK) + .setStartPoint("origin/" + label); + } + + private boolean isBranch(Git git, String label) throws GitAPIException { + return containsBranch(git, label, ListBranchCommand.ListMode.ALL); + } + + private boolean isLocalBranch(Git git, String label) throws GitAPIException { + return containsBranch(git, label, null); + } + + private boolean containsBranch(Git git, String label, ListBranchCommand.ListMode listMode) + throws GitAPIException { + ListBranchCommand command = git.branchList(); + if (listMode != null) { + command.setListMode(listMode); + } + List branches = command.call(); + for (Ref ref : branches) { + if (ref.getName().endsWith("/" + label)) { + return true; + } + } + return false; + } + + private void deleteBaseDirIfExists() { + if (this.basedir.exists()) { + try { + FileUtils.delete(this.basedir, FileUtils.RECURSIVE); + } + catch (IOException e) { + throw new IllegalStateException("Failed to initialize base directory", e); + } + } + } + + /** + * Wraps the static method calls to {@link Git} and + * {@link CloneCommand} allowing for easier unit testing. + */ + static class JGitFactory { + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final JschConfigSessionFactory factory = new JschConfigSessionFactory() { + + @Override protected void configure(OpenSshConfig.Host host, Session session) { + } + + @Override + protected JSch createDefaultJSch(FS fs) throws JSchException { + Connector connector = null; + try { + if(SSHAgentConnector.isConnectorAvailable()){ + USocketFactory usf = new JNAUSocketFactory(); + connector = new SSHAgentConnector(usf); + } + log.info("Successfully connected to an agent"); + } catch (AgentProxyException e) { + log.error("Exception occurred while trying to connect to agent. Will create" + + "the default JSch connection", e); + return super.createDefaultJSch(fs); + } + final JSch jsch = super.createDefaultJSch(fs); + if (connector != null) { + JSch.setConfig("PreferredAuthentications", "publickey,password"); + IdentityRepository identityRepository = new RemoteIdentityRepository(connector); + jsch.setIdentityRepository(identityRepository); + } + return jsch; + } + }; + + private final CredentialsProvider provider; + + JGitFactory(GitStubDownloaderProperties properties) { + if (org.springframework.util.StringUtils.hasText(properties.username)) { + log.info("Passed username and password - will set a custom credentials provider"); + this.provider = credentialsProvider(properties); + } else { + if (log.isDebugEnabled()) { + log.debug("No custom credentials provider will be set"); + } + this.provider = null; + } + } + + CredentialsProvider credentialsProvider(GitStubDownloaderProperties properties) { + return new UsernamePasswordCredentialsProvider( + properties.username, + properties.password); + } + + // for tests + JGitFactory() { + this.provider = null; + } + + private final TransportConfigCallback callback = transport -> { + if (transport instanceof SshTransport) { + SshTransport sshTransport = (SshTransport) transport; + sshTransport.setSshSessionFactory(this.factory); + } + }; + + CloneCommand getCloneCommandByCloneRepository() { + return Git.cloneRepository() + .setCredentialsProvider(this.provider) + .setTransportConfigCallback(this.callback); + } + + PushCommand push(Git git) { + return git.push() + .setCredentialsProvider(this.provider) + .setTransportConfigCallback(this.callback); + } + + PullCommand pull(Git git) { + return git.pull() + .setCredentialsProvider(this.provider) + .setTransportConfigCallback(this.callback); + } + + Git open(File file) { + try { + return Git.open(file); + } + catch (IOException e) { + throw new IllegalStateException(e); + } + } + } +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ResourceResolver.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ResourceResolver.java new file mode 100644 index 0000000000..1fa1a29da5 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ResourceResolver.java @@ -0,0 +1,69 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ProtocolResolver; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.SpringFactoriesLoader; + +/** + * Uses {@code META-INF/spring.factories} to read {@link ProtocolResolver} list + * that gets added to {@link DefaultResourceLoader}. Each implementor of a new + * {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder}, if + * one uses a new protocol, should register their own {@link ProtocolResolver} so + * that Stub Runner can convert a {@link String} version of a URI to a {@link Resource}. + * + * IMPORTANT! Internal tool. Do not use. + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +public class ResourceResolver { + + private static final Log log = LogFactory.getLog(ResourceResolver.class); + private static final List RESOLVERS = new ArrayList<>(); + private static final DefaultResourceLoader LOADER = new DefaultResourceLoader(); + + static { + RESOLVERS.addAll( + SpringFactoriesLoader.loadFactories(StubDownloaderBuilder.class, null) + ); + RESOLVERS.addAll(new StubDownloaderBuilderProvider().defaultStubDownloaderBuilders()); + for (ProtocolResolver resolver : RESOLVERS) { + LOADER.addProtocolResolver(resolver); + } + } + + /** + * @param url - string url + * @return corresponding {@link Resource} + */ + public static Resource resource(String url) { + try { + return LOADER.getResource(url); + } catch (Exception e) { + log.error("Exception occurred while trying to read the resource [" + url + "]", e); + return null; + } + } +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java new file mode 100644 index 0000000000..3bb82cf4cc --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ScmStubDownloaderBuilder.java @@ -0,0 +1,272 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.AbstractMap; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; +import org.springframework.core.io.AbstractResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.StringUtils; + +/** + * Builds a {@link StubDownloader} to work with contracts and stubs from a SCM + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +public final class ScmStubDownloaderBuilder implements StubDownloaderBuilder { + + private static final List ACCEPTABLE_PROTOCOLS = Collections + .singletonList("git"); + + /** + * Does any of the accepted protocols matches the URL of the repository + * @param url - of the repository + */ + public static boolean isProtocolAccepted(String url) { + return ACCEPTABLE_PROTOCOLS.stream().anyMatch(url::startsWith); + } + + @Override public StubDownloader build(StubRunnerOptions stubRunnerOptions) { + if (stubRunnerOptions.getStubsMode() == StubRunnerProperties.StubsMode.CLASSPATH || + stubRunnerOptions.getStubRepositoryRoot() == null) { + return null; + } + Resource resource = stubRunnerOptions.getStubRepositoryRoot(); + if (!(resource instanceof GitResource)) { + return null; + } + return new GitStubDownloader(stubRunnerOptions); + } + + @Override public Resource resolve(String location, ResourceLoader resourceLoader) { + if (StringUtils.isEmpty(location) || !isProtocolAccepted(location)) { + return null; + } + return new GitResource(location); + } +} + + +/** + * Primitive version of a Git {@link Resource} + */ +class GitResource extends AbstractResource { + + private final String rawLocation; + + GitResource(String location) { + this.rawLocation = location; + } + + @Override public String getDescription() { + return this.rawLocation; + } + + @Override public InputStream getInputStream() throws IOException { + return null; + } + + @Override public URI getURI() throws IOException { + return URI.create(this.rawLocation); + } +} + +class GitContractsRepo { + + private static final Log log = LogFactory.getLog(GitContractsRepo.class); + + private static final String TEMP_DIR_PREFIX = "git-contracts"; + static final Map CACHED_LOCATIONS = new ConcurrentHashMap<>(); + + private final StubRunnerOptions options; + + GitContractsRepo(StubRunnerOptions options) { + this.options = options; + } + + File clonedRepo(Resource repo) { + File file = CACHED_LOCATIONS.get(repo); + GitStubDownloaderProperties properties = new GitStubDownloaderProperties(repo, this.options); + if (file == null) { + File tmpDirWhereStubsWillBeUnzipped = TemporaryFileStorage.unpackStubJarToATemporaryFolder(TEMP_DIR_PREFIX); + GitRepo gitRepo = new GitRepo(tmpDirWhereStubsWillBeUnzipped, properties); + file = gitRepo.cloneProject(properties.url); + gitRepo.checkout(file, properties.branch); + CACHED_LOCATIONS.put(repo, file); + if (log.isDebugEnabled()) { + log.debug("The project hasn't already been cloned. Cloned it to [" + file + "]"); + } + } else { + if (log.isDebugEnabled()) { + log.debug("The project has already been cloned to [" + file + "]. Will reset any changes."); + } + new GitRepo(file, properties).reset(file); + } + return file; + } +} + +class GitStubDownloader implements StubDownloader { + private static final Log log = LogFactory.getLog(GitStubDownloader.class); + + // Preloading class for the shutdown hook not to throw ClassNotFound + private static final Class CLAZZ = TemporaryFileStorage.class; + + private final StubRunnerOptions stubRunnerOptions; + private final boolean deleteStubsAfterTest; + private final GitContractsRepo gitContractsRepo; + + GitStubDownloader(StubRunnerOptions stubRunnerOptions) { + this.stubRunnerOptions = stubRunnerOptions; + this.deleteStubsAfterTest = this.stubRunnerOptions.isDeleteStubsAfterTest(); + this.gitContractsRepo = new GitContractsRepo(stubRunnerOptions); + registerShutdownHook(); + } + + @Override public Map.Entry downloadAndUnpackStubJar( + StubConfiguration stubConfiguration) { + if (StringUtils.isEmpty(stubConfiguration.version) || "+".equals(stubConfiguration.version)) { + throw new IllegalStateException("Concrete version wasn't passed for [" + stubConfiguration.toColonSeparatedDependencyNotation() + "]"); + } + try { + if (log.isDebugEnabled()) { + log.debug("Trying to find a contract for [" + stubConfiguration.toColonSeparatedDependencyNotation() + "]"); + } + Resource repo = this.stubRunnerOptions.getStubRepositoryRoot(); + File clonedRepo = this.gitContractsRepo.clonedRepo(repo); + FileWalker walker = new FileWalker(stubConfiguration); + Files.walkFileTree(clonedRepo.toPath(), walker); + if (walker.foundFile != null) { + return new AbstractMap.SimpleEntry<>(stubConfiguration, walker.foundFile.toFile()); + } + } + catch (IOException e) { + throw new IllegalStateException(e); + } + if (log.isDebugEnabled()) { + log.debug("No matching contracts were found in the repo for [" + stubConfiguration.toColonSeparatedDependencyNotation() + "]. Returning null"); + } + return null; + } + + private void registerShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread( + () -> TemporaryFileStorage.cleanup(GitStubDownloader.this.deleteStubsAfterTest))); + } +} + +class GitStubDownloaderProperties { + private static final Log log = LogFactory.getLog(GitStubDownloaderProperties.class); + + private static final String GIT_BRANCH_PROPERTY = "git.branch"; + private static final String GIT_USERNAME_PROPERTY = "git.username"; + private static final String GIT_PASSWORD_PROPERTY = "git.password"; + + final URI url; + final String username; + final String password; + final String branch; + + GitStubDownloaderProperties(Resource repo, StubRunnerOptions options) { + String repoUrl; + Map args = options.getProperties(); + try { + repoUrl = schemeSpecificPart(repo.getURI()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + // if we had git://https://... we want the part starting from https + // if we had git://git@... we want the full address again + // if the URL starts with git@... and ends with .git, we want to remove it + String modifiedRepo = repoUrl.startsWith("git@") ? modifyUrlForGitRepo(repoUrl) : repoUrl; + this.url = URI.create(modifiedRepo); + String username = StubRunnerPropertyUtils.getProperty(args, GIT_USERNAME_PROPERTY); + this.username = StringUtils.hasText(username) ? username : options.getUsername(); + String password = StubRunnerPropertyUtils.getProperty(args, GIT_PASSWORD_PROPERTY); + this.password = StringUtils.hasText(password) ? password : options.getPassword(); + String branch = StubRunnerPropertyUtils.getProperty(args, GIT_BRANCH_PROPERTY); + this.branch = StringUtils.hasText(branch) ? branch : "master"; + if (log.isDebugEnabled()) { + log.debug("Repo url is [" + repoUrl + "], modified url string " + + "is [" + modifiedRepo + "] URL is [" + this.url + "] and " + + "branch is [" + this.branch + "]"); + } + } + + private String schemeSpecificPart(URI uri) { + String part = uri.getSchemeSpecificPart(); + if (StringUtils.isEmpty(part)) { + return part; + } + return part.startsWith("//") ? part.substring(2) : part; + } + + private String modifyUrlForGitRepo(String gitRepo) { + return "git:" + gitRepo; + } +} + +class FileWalker extends SimpleFileVisitor { + + private final PathMatcher matcherWithDot; + private final PathMatcher matcherWithoutDot; + Path foundFile; + + FileWalker(StubConfiguration stubConfiguration) { + this.matcherWithDot = FileSystems.getDefault() + .getPathMatcher("glob:" + matcherGlob(stubConfiguration, ".")); + this.matcherWithoutDot = FileSystems.getDefault() + .getPathMatcher("glob:" + matcherGlob(stubConfiguration, "/")); + } + + private String matcherGlob(StubConfiguration stubConfiguration, String groupArtifactSeparator) { + return "**" + stubConfiguration.groupId + groupArtifactSeparator + + stubConfiguration.artifactId + "/" + + stubConfiguration.version; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + throws IOException { + if (this.matcherWithDot.matches(dir.toAbsolutePath()) || + this.matcherWithoutDot.matches(dir.toAbsolutePath())) { + this.foundFile = dir; + return FileVisitResult.TERMINATE; + } + return FileVisitResult.CONTINUE; + } +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilder.java index 65937dedd6..ea9e72cc8f 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilder.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilder.java @@ -16,6 +16,10 @@ package org.springframework.cloud.contract.stubrunner; +import org.springframework.core.io.ProtocolResolver; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + /** * Builder for a {@link StubDownloader}. Can't allow direct usage * of {@link StubDownloader} cause in order to register instances @@ -23,13 +27,20 @@ package org.springframework.cloud.contract.stubrunner; * one needs a default constructor whereas the {@link StubDownloader} * instances need to be constructed from stub related options. * + * Since {@code 2.0.0} extends {@link ProtocolResolver}. Implementations have + * to tell Spring how to parse the repository root String into a resource. + * * @author Marcin Grzejszczak * @since 1.1.0 */ -public interface StubDownloaderBuilder { +public interface StubDownloaderBuilder extends ProtocolResolver { /** * @return {@link StubDownloader} instance of {@code null} if current parameters don't allow building the instance */ StubDownloader build(StubRunnerOptions stubRunnerOptions); + + @Override default Resource resolve(String location, ResourceLoader resourceLoader) { + return null; + } } \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilderProvider.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilderProvider.java index 2d98479775..646db2f403 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilderProvider.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloaderBuilderProvider.java @@ -44,6 +44,7 @@ public class StubDownloaderBuilderProvider { List defaultStubDownloaderBuilders() { return Arrays - .asList(new ClasspathStubProvider(), new AetherStubDownloaderBuilder()); + .asList(new ScmStubDownloaderBuilder(), new ClasspathStubProvider(), + new AetherStubDownloaderBuilder()); } } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRepository.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRepository.java index 360aadb561..fcb87ab830 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRepository.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRepository.java @@ -1,17 +1,17 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.stubrunner; @@ -59,16 +59,16 @@ 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); + if (log.isTraceEnabled()) { + log.trace("Found the following contract converters " + this.contractConverters); } this.httpServerStubs = httpServerStubs; this.path = repository; this.options = options; this.stubs = stubs(); this.contracts = contracts(); - if (log.isDebugEnabled()) { - log.debug("Found the following contracts " + this.contracts); + if (log.isTraceEnabled()) { + log.trace("Found the following contracts " + this.contracts); } } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java index 6c55765656..e6024b8238 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java @@ -1,26 +1,34 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.stubrunner; +import java.io.FileNotFoundException; +import java.io.IOException; import java.util.Collection; +import java.util.HashMap; import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; +import org.springframework.core.io.Resource; +import org.springframework.util.StringUtils; /** * Technical options related to running StubRunner @@ -31,6 +39,8 @@ import org.springframework.cloud.contract.stubrunner.util.StringUtils; */ public class StubRunnerOptions { + private static final Log log = LogFactory.getLog(StubRunnerOptions.class); + /** * min port value of the WireMock instance for the given collaborator */ @@ -44,7 +54,7 @@ public class StubRunnerOptions { /** * root URL from where the JAR with stub mappings will be downloaded */ - final String stubRepositoryRoot; + final Resource stubRepositoryRoot; /** * stub definition classifier @@ -103,13 +113,19 @@ public class StubRunnerOptions { */ private boolean deleteStubsAfterTest; + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + private Map properties = new HashMap<>(); + + StubRunnerOptions(Integer minPortValue, Integer maxPortValue, - String stubRepositoryRoot, StubRunnerProperties.StubsMode stubsMode, String stubsClassifier, + Resource stubRepositoryRoot, StubRunnerProperties.StubsMode stubsMode, String stubsClassifier, Collection dependencies, Map stubIdsToPortMapping, String username, String password, final StubRunnerProxyOptions stubRunnerProxyOptions, boolean stubsPerConsumer, String consumerName, String mappingsOutputFolder, boolean snapshotCheckSkip, - boolean deleteStubsAfterTest) { + boolean deleteStubsAfterTest, Map properties) { this.minPortValue = minPortValue; this.maxPortValue = maxPortValue; this.stubRepositoryRoot = stubRepositoryRoot; @@ -125,6 +141,7 @@ public class StubRunnerOptions { this.mappingsOutputFolder = mappingsOutputFolder; this.snapshotCheckSkip = snapshotCheckSkip; this.deleteStubsAfterTest = deleteStubsAfterTest; + this.properties = properties; } public Integer port(StubConfiguration stubConfiguration) { @@ -140,7 +157,8 @@ public class StubRunnerOptions { StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder() .withMinPort(Integer.valueOf(System.getProperty("stubrunner.port.range.min", "10000"))) .withMaxPort(Integer.valueOf(System.getProperty("stubrunner.port.range.max", "15000"))) - .withStubRepositoryRoot(System.getProperty("stubrunner.repository.root", "")) + .withStubRepositoryRoot(ResourceResolver + .resource(System.getProperty("stubrunner.repository.root", ""))) .withStubsMode(System.getProperty("stubrunner.stubs-mode", "LOCAL")) .withStubsClassifier(System.getProperty("stubrunner.classifier", "stubs")) .withStubs(System.getProperty("stubrunner.ids", "")) @@ -150,7 +168,8 @@ public class StubRunnerOptions { .withConsumerName(System.getProperty("stubrunner.consumer-name")) .withMappingsOutputFolder(System.getProperty("stubrunner.mappings-output-folder")) .withSnapshotCheckSkip(Boolean.parseBoolean(System.getProperty("stubrunner.snapshot-check-skip", "false"))) - .withDeleteStubsAfterTest(Boolean.parseBoolean(System.getProperty("stubrunner.delete-stubs-after-test", "true"))); + .withDeleteStubsAfterTest(Boolean.parseBoolean(System.getProperty("stubrunner.delete-stubs-after-test", "true"))) + .withProperties(stubRunnerProps()); String proxyHost = System.getProperty("stubrunner.proxy.host"); if (proxyHost != null) { builder.withProxy(proxyHost, Integer.parseInt(System.getProperty("stubrunner.proxy.port"))); @@ -158,6 +177,19 @@ public class StubRunnerOptions { return builder.build(); } + private static Map stubRunnerProps() { + Map map = new HashMap<>(); + Properties properties = System.getProperties(); + Set propertyNames = properties.stringPropertyNames(); + propertyNames + .stream() + // stubrunner.properties.foo.bar=baz + .filter(s -> s.toLowerCase().startsWith("stubrunner.properties")) + // foo.bar=baz + .forEach(s -> map.put(s.substring("stubrunner.properties".length() + 1), System.getProperty(s))); + return map; + } + public Integer getMinPortValue() { return this.minPortValue; } @@ -174,10 +206,25 @@ public class StubRunnerOptions { return this.stubIdsToPortMapping; } - public String getStubRepositoryRoot() { + public Resource getStubRepositoryRoot() { return this.stubRepositoryRoot; } + public String getStubRepositoryRootAsString() { + try { + return this.stubRepositoryRoot.getURI().toString(); + } + catch (FileNotFoundException f) { + if (log.isDebugEnabled()) { + log.debug("File not found", f); + } + return ""; + } + catch (IOException e) { + throw new IllegalStateException(e); + } + } + public StubRunnerProperties.StubsMode getStubsMode() { return this.stubsMode; } @@ -246,6 +293,14 @@ public class StubRunnerOptions { this.deleteStubsAfterTest = deleteStubsAfterTest; } + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + public static class StubRunnerProxyOptions { private final String proxyHost; diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java index 86c6a4e54c..8c03973b01 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java @@ -1,17 +1,17 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.stubrunner; @@ -19,6 +19,7 @@ package org.springframework.cloud.contract.stubrunner; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -26,6 +27,7 @@ import java.util.Map; import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; import org.springframework.cloud.contract.stubrunner.util.StubsParser; +import org.springframework.core.io.Resource; import org.springframework.util.StringUtils; public class StubRunnerOptionsBuilder { @@ -37,7 +39,7 @@ public class StubRunnerOptionsBuilder { private Integer minPortValue = 10000; private Integer maxPortValue = 15000; - private String stubRepositoryRoot; + private Resource stubRepositoryRoot; private String stubsClassifier = "stubs"; private String username; private String password; @@ -48,6 +50,7 @@ public class StubRunnerOptionsBuilder { private StubRunnerProperties.StubsMode stubsMode; private boolean snapshotCheckSkip = false; private boolean deleteStubsAfterTest = true; + private Map properties = new HashMap<>(); public StubRunnerOptionsBuilder() { } @@ -84,11 +87,18 @@ public class StubRunnerOptionsBuilder { return this; } - public StubRunnerOptionsBuilder withStubRepositoryRoot(String stubRepositoryRoot) { + public StubRunnerOptionsBuilder withStubRepositoryRoot(Resource stubRepositoryRoot) { this.stubRepositoryRoot = stubRepositoryRoot; return this; } + public StubRunnerOptionsBuilder withStubRepositoryRoot(String stubRepositoryRoot) { + if (StringUtils.hasText(stubRepositoryRoot)) { + this.stubRepositoryRoot = ResourceResolver.resource(stubRepositoryRoot); + } + return this; + } + public StubRunnerOptionsBuilder withStubsMode(StubRunnerProperties.StubsMode stubsMode) { this.stubsMode = stubsMode; return this; @@ -128,6 +138,7 @@ public class StubRunnerOptionsBuilder { options.stubIdsToPortMapping : new LinkedHashMap(); this.snapshotCheckSkip = options.isSnapshotCheckSkip(); this.deleteStubsAfterTest = options.isDeleteStubsAfterTest(); + this.properties = options.getProperties(); return this; } @@ -146,11 +157,16 @@ public class StubRunnerOptionsBuilder { return this; } + public StubRunnerOptionsBuilder withProperties(Map properties) { + this.properties = properties; + return this; + } + public StubRunnerOptions build() { return new StubRunnerOptions(this.minPortValue, this.maxPortValue, this.stubRepositoryRoot, this.stubsMode, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping, this.username, this.password, this.stubRunnerProxyOptions, this.stubsPerConsumer, this.consumerName, - this.mappingsOutputFolder, this.snapshotCheckSkip, this.deleteStubsAfterTest); + this.mappingsOutputFolder, this.snapshotCheckSkip, this.deleteStubsAfterTest, this.properties); } private Collection buildDependencies() { diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerPropertyUtils.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerPropertyUtils.java new file mode 100644 index 0000000000..c06f20f5e6 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerPropertyUtils.java @@ -0,0 +1,78 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.util.StringUtils; + +/** + * Reads property from system prop and from env var + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +class StubRunnerPropertyUtils { + + private static final String STUBRUNNER_PROPERTIES = "stubrunner.properties"; + + static PropertyFetcher FETCHER = new PropertyFetcher(); + + /** + * For Env vars takes the prop name, converts dots to underscores and applies + * upper case + */ + static boolean isPropertySet(String propName) { + String value = getProperty(new HashMap<>(), propName); + return StringUtils.hasText(value) && Boolean.parseBoolean(value); + } + + /** + * Tries to pick a value from options, for Env vars takes the prop name, converts + * dots to underscores and applies upper case + */ + static String getProperty(Map options, String propName) { + if (options != null && options.containsKey(propName)) { + return options.get(propName); + } + String directTry = doGetProp(propName); + if (StringUtils.hasText(directTry)) { + return directTry; + } + return doGetProp(STUBRUNNER_PROPERTIES + "." + propName); + } + + private static String doGetProp(String stubRunnerProp) { + String systemProp = FETCHER.systemProp(stubRunnerProp); + if (StringUtils.hasText(systemProp)) { + return systemProp; + } + String convertedEnvProp = stubRunnerProp.replaceAll("\\.", "_") + .replaceAll("-", "_").toUpperCase(); + return FETCHER.envVar(convertedEnvProp); + } +} + +class PropertyFetcher { + String systemProp(String prop) { + return System.getProperty(prop); + } + String envVar(String prop) { + return System.getenv(prop); + } +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/TemporaryFileStorage.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/TemporaryFileStorage.java new file mode 100644 index 0000000000..d5ec0d7efa --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/TemporaryFileStorage.java @@ -0,0 +1,110 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import static java.nio.file.Files.createTempDirectory; + +/** + * Stores all generated temporary folders with stubs + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +class TemporaryFileStorage { + + private static final Log log = LogFactory.getLog(TemporaryFileStorage.class); + + /** + * There are problems with removal of stubs unpacked to a temporary folder. + * That's why we're creating a bounded in-memory storage of unpacked files + * and later we register a shutdown hook to remove all these files. + */ + private static final Queue TEMP_FILES_LOG = new LinkedBlockingQueue<>(1000); + + static void add(File file) { + TEMP_FILES_LOG.add(file); + } + + static Queue files() { + return TEMP_FILES_LOG; + } + + static void cleanup(boolean deleteStubsAfterTest) { + if (!deleteStubsAfterTest) { + log.info("Will not clear temporary files due to switch"); + return; + } + try { + for (File file : TemporaryFileStorage.files()) { + if (file.isDirectory()) { + Files.walkFileTree(file.toPath(), new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws + IOException { + if (log.isTraceEnabled()) { + log.trace("Removing file [" + file + "]"); + } + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (log.isTraceEnabled()) { + log.trace("Removing dir [" + dir + "]"); + } + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } else { + Files.delete(file.toPath()); + } + } + } catch (NoClassDefFoundError | IOException e) { + // Added NoClassDefFoundError cause sometimes it's visible in the builds + // this error is completely harmless + if (log.isTraceEnabled()) { + log.trace("Failed to remove temporary file", e); + } + } + } + + static File unpackStubJarToATemporaryFolder(String tempDirPrefix) { + try { + return createTempDirectory(tempDirPrefix) + .toFile(); + } + catch (IOException e) { + throw new IllegalStateException( + "Cannot create tmp dir with prefix: [" + tempDirPrefix + "]", e); + } + } +} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java index df9e3c6bed..eb62e0bcde 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java @@ -165,6 +165,11 @@ public class StubRunnerRule implements TestRule, StubFinder, StubRunnerRuleOptio return this.delegate; } + @Override public StubRunnerRule withProperties(Map properties) { + builder().withProperties(properties); + return this.delegate; + } + @Override public URL findStubUrl(String groupId, String artifactId) { return this.stubFinder().findStubUrl(groupId, artifactId); diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleOptions.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleOptions.java index 405f5cde31..2a28857197 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleOptions.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleOptions.java @@ -1,6 +1,7 @@ package org.springframework.cloud.contract.stubrunner.junit; import java.util.List; +import java.util.Map; import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; @@ -105,4 +106,9 @@ interface StubRunnerRuleOptions { * folder after running tests */ StubRunnerRule withDeleteStubsAfterTest(boolean deleteStubsAfterTest); + + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + StubRunnerRule withProperties(Map properties); } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java index e5eb781b81..4d7dd7b0d0 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java @@ -30,7 +30,6 @@ import org.springframework.cloud.contract.stubrunner.StubConfiguration; import org.springframework.cloud.contract.stubrunner.StubDownloaderBuilderProvider; import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; import org.springframework.cloud.contract.verifier.messaging.MessageVerifier; import org.springframework.cloud.contract.verifier.messaging.noop.NoOpStubMessages; import org.springframework.context.annotation.Bean; @@ -39,7 +38,7 @@ import org.springframework.context.annotation.Import; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.io.Resource; +import org.springframework.util.StringUtils; /** * Configuration that initializes a {@link BatchStubRunner} that runs @@ -86,8 +85,7 @@ public class StubRunnerConfiguration { private StubRunnerOptionsBuilder builder() throws IOException { return new StubRunnerOptionsBuilder() .withMinMaxPort(this.props.getMinPort(), this.props.getMaxPort()) - .withStubRepositoryRoot( - uriStringOrEmpty(this.props.getRepositoryRoot())) + .withStubRepositoryRoot(this.props.getRepositoryRoot()) .withStubsMode(this.props.getStubsMode()) .withStubsClassifier(this.props.getClassifier()) .withStubs(this.props.getIds()) @@ -107,10 +105,6 @@ public class StubRunnerConfiguration { return this.environment.getProperty("spring.application.name"); } - private String uriStringOrEmpty(Resource stubRepositoryRoot) throws IOException { - return stubRepositoryRoot != null ? stubRepositoryRoot.getURI().toString() : ""; - } - private void registerPort(RunningStubs runStubs) { MutablePropertySources propertySources = this.environment.getPropertySources(); if (!propertySources.contains(STUBRUNNER_PREFIX)) { @@ -126,4 +120,4 @@ public class StubRunnerConfiguration { } } -} +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java index 88b13a5f42..3d2e78356b 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java @@ -17,9 +17,11 @@ package org.springframework.cloud.contract.stubrunner.spring; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.cloud.contract.stubrunner.ResourceResolver; import org.springframework.core.io.Resource; /** @@ -107,6 +109,11 @@ public class StubRunnerProperties { */ private boolean deleteStubsAfterTest = true; + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + private Map properties = new HashMap<>(); + /** * An enumeration stub modes. */ @@ -149,7 +156,7 @@ public class StubRunnerProperties { } public void setRepositoryRoot(String repositoryRoot) { - this.repositoryRoot = new DefaultResourceLoader().getResource(repositoryRoot); + this.repositoryRoot = ResourceResolver.resource(repositoryRoot); } public String getUsername() { @@ -216,10 +223,6 @@ public class StubRunnerProperties { this.consumerName = consumerName; } - public void setRepositoryRoot(Resource repositoryRoot) { - this.repositoryRoot = repositoryRoot; - } - public String getMappingsOutputFolder() { return this.mappingsOutputFolder; } @@ -252,6 +255,14 @@ public class StubRunnerProperties { this.deleteStubsAfterTest = deleteStubsAfterTest; } + public Map getProperties() { + return this.properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + @Override public String toString() { return "StubRunnerProperties{" + "minPort=" + this.minPort + ", maxPort=" + this.maxPort + ", repositoryRoot=" + this.repositoryRoot @@ -259,6 +270,7 @@ public class StubRunnerProperties { + ", setStubsPerConsumer='" + this.stubsPerConsumer + "', consumerName='" + this.consumerName + '\'' + ", stubsMode='" + this.stubsMode + '\'' + ", snapshotCheckSkip='" + this.snapshotCheckSkip + '\'' + + ", size of properties=" + this.properties.size() + '}'; } } diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java index e3036c0cff..edee0cad48 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java @@ -21,7 +21,7 @@ import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.contract.stubrunner.StubConfiguration; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; +import org.springframework.util.StringUtils; /** * Maps Ivy based ids to service Ids. You might want to name the service you're calling diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java index d98313f262..44d2c0cb94 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java @@ -29,7 +29,7 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.contract.stubrunner.RunningStubs; import org.springframework.cloud.contract.stubrunner.StubFinder; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; +import org.springframework.util.StringUtils; /** * Custom version of {@link DiscoveryClient} that tries to find an instance diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java index ce4eb47709..541d52793d 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java @@ -30,7 +30,7 @@ import org.springframework.cloud.contract.stubrunner.RunningStubs; import org.springframework.cloud.contract.stubrunner.StubConfiguration; import org.springframework.cloud.contract.stubrunner.StubFinder; import org.springframework.cloud.contract.stubrunner.spring.cloud.StubMapperProperties; -import org.springframework.cloud.contract.stubrunner.util.StringUtils; +import org.springframework.util.StringUtils; /** * Stub Runner representation of a server list diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StringUtils.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StringUtils.java deleted file mode 100644 index f9e6c52197..0000000000 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StringUtils.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.contract.stubrunner.util; - -/** - * Utils ported from Apache Commons - * - * @author Marcin Grzejszczak - */ -public class StringUtils { - private static final String EMPTY = ""; - private static final int INDEX_NOT_FOUND = -1; - - // Empty checks - // ----------------------------------------------------------------------- - /** - *

- * Checks if a String is empty ("") or null. - *

- * - *
-	 * StringUtils.isEmpty(null)      = true
-	 * StringUtils.isEmpty("")        = true
-	 * StringUtils.isEmpty(" ")       = false
-	 * StringUtils.isEmpty("bob")     = false
-	 * StringUtils.isEmpty("  bob  ") = false
-	 * 
- * - *

- * NOTE: This method changed in Lang version 2.0. It no longer trims the String. That - * functionality is available in isBlank(). - *

- * - * @param str the String to check, may be null - * @return true if the String is empty or null - */ - private static boolean isEmpty(String str) { - return str == null || str.length() == 0; - } - - private static boolean isNotEmpty(String string) { - return string != null && !string.isEmpty(); - } - - public static boolean hasText(String string) { - if (!isNotEmpty(string)) { - return false; - } - int strLen = string.length(); - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(string.charAt(i))) { - return true; - } - } - return false; - } - - /** - *

- * Gets the substring before the last occurrence of a separator. The separator is not - * returned. - *

- * - *

- * A null string input will return null. An empty ("") - * string input will return the empty string. An empty or null separator - * will return the input string. - *

- * - *

- * If nothing is found, the string input is returned. - *

- * - *
-	 * StringUtils.substringBeforeLast(null, *)      = null
-	 * StringUtils.substringBeforeLast("", *)        = ""
-	 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
-	 * StringUtils.substringBeforeLast("abc", "c")   = "ab"
-	 * StringUtils.substringBeforeLast("a", "a")     = ""
-	 * StringUtils.substringBeforeLast("a", "z")     = "a"
-	 * StringUtils.substringBeforeLast("a", null)    = "a"
-	 * StringUtils.substringBeforeLast("a", "")      = "a"
-	 * 
- * - * @param str the String to get a substring from, may be null - * @param separator the String to search for, may be null - * @return the substring before the last occurrence of the separator, - * null if null String input - * @since 2.0 - */ - public static String substringBeforeLast(String str, String separator) { - if (isEmpty(str) || isEmpty(separator)) { - return str; - } - int pos = str.lastIndexOf(separator); - if (pos == INDEX_NOT_FOUND) { - return str; - } - return str.substring(0, pos); - } - - /** - *

- * Gets the substring after the last occurrence of a separator. The separator is not - * returned. - *

- * - *

- * A null string input will return null. An empty ("") - * string input will return the empty string. An empty or null separator - * will return the empty string if the input string is not null. - *

- * - *

- * If nothing is found, the empty string is returned. - *

- * - *
-	 * StringUtils.substringAfterLast(null, *)      = null
-	 * StringUtils.substringAfterLast("", *)        = ""
-	 * StringUtils.substringAfterLast(*, "")        = ""
-	 * StringUtils.substringAfterLast(*, null)      = ""
-	 * StringUtils.substringAfterLast("abc", "a")   = "bc"
-	 * StringUtils.substringAfterLast("abcba", "b") = "a"
-	 * StringUtils.substringAfterLast("abc", "c")   = ""
-	 * StringUtils.substringAfterLast("a", "a")     = ""
-	 * StringUtils.substringAfterLast("a", "z")     = ""
-	 * 
- * - * @param str the String to get a substring from, may be null - * @param separator the String to search for, may be null - * @return the substring after the last occurrence of the separator, null - * if null String input - * @since 2.0 - */ - public static String substringAfterLast(String str, String separator) { - if (isEmpty(str)) { - return str; - } - if (isEmpty(separator)) { - return EMPTY; - } - int pos = str.lastIndexOf(separator); - if (pos == INDEX_NOT_FOUND || pos == (str.length() - separator.length())) { - return EMPTY; - } - return str.substring(pos + separator.length()); - } -} diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java index fcce3d6e10..612081164d 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/util/StubsParser.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import org.springframework.cloud.contract.stubrunner.StubConfiguration; +import org.springframework.util.StringUtils; /** * Utility to parse string into a list of configuration of stubs diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy index 0bf2474060..f98d130ac9 100644 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy @@ -3,11 +3,10 @@ package org.springframework.cloud.contract.stubrunner import io.specto.hoverfly.junit.HoverflyRule import org.eclipse.aether.RepositorySystemSession import org.junit.Rule -import spock.lang.Specification -import spock.util.environment.RestoreSystemProperties - import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties import org.springframework.util.ResourceUtils +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties class AetherStubDownloaderSpec extends Specification { @@ -76,12 +75,18 @@ class AetherStubDownloaderSpec extends Specification { System.properties.setProperty("stubrunner.snapshot-check-skip", "false") and: - AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) { + StubRunnerPropertyUtils.FETCHER = new PropertyFetcher() { @Override - String getSkipSnapEnvProp() { + String systemProp(String prop) { + return super.systemProp(prop) + } + + @Override + String envVar(String prop) { return "true" } } + AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) when: def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("org.springframework.cloud", "spring-cloud-contract-spec", "+", "")) @@ -98,18 +103,28 @@ class AetherStubDownloaderSpec extends Specification { .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local") .build() - AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) { + and: + StubRunnerPropertyUtils.FETCHER = new PropertyFetcher() { @Override - String getSkipSnapEnvProp() { + String systemProp(String prop) { + return super.systemProp(prop) + } + + @Override + String envVar(String prop) { return "true" } } + AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) when: def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("org.springframework.cloud", "spring-cloud-contract-spec", "+", "")) then: jar != null + + cleanup: + StubRunnerPropertyUtils.FETCHER = new PropertyFetcher() } def 'Should not throw an exception when a jar is in local m2 and not in remote repo and option disabled snapshot check'() { diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy index cfe5ef5cb4..56b48a9773 100644 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy @@ -16,7 +16,7 @@ class ContractDownloaderSpec extends Specification { given: String contractPath = File.separator + ['a','b','c','d'].join(File.separator) ContractDownloader contractDownloader = new ContractDownloader(stubDownloader, - stubConfiguration, contractPath, '', '') + stubConfiguration, contractPath, '', '', '') ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() and: stubDownloader.downloadAndUnpackStubJar(_) >> new AbstractMap.SimpleEntry(stubConfiguration, file) @@ -33,7 +33,7 @@ class ContractDownloaderSpec extends Specification { given: String contractPath = ['a','b','c','d'].join(File.separator) ContractDownloader contractDownloader = new ContractDownloader(stubDownloader, - stubConfiguration, contractPath, '', '') + stubConfiguration, contractPath, '', '', '') ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() and: stubDownloader.downloadAndUnpackStubJar(_) >> new AbstractMap.SimpleEntry(stubConfiguration, file) diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/GitStubDownloaderPropertiesSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/GitStubDownloaderPropertiesSpec.groovy new file mode 100644 index 0000000000..03a26d83ab --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/GitStubDownloaderPropertiesSpec.groovy @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import spock.lang.Specification + +import org.springframework.core.io.AbstractResource +import org.springframework.core.io.Resource + +/** + * @author Marcin Grzejszczak + */ +class GitStubDownloaderPropertiesSpec extends Specification { + + def "should parse only the URL after protocol if it doesn't start with git"() { + given: + Resource resource = resource("git://https://foo.com") + when: + GitStubDownloaderProperties props = new GitStubDownloaderProperties(resource, new StubRunnerOptionsBuilder().build()) + then: + props.url == URI.create("https://foo.com") + } + + def "should return the whole address if it starts with git@ but doesn't finish with .git"() { + given: + Resource resource = resource("git://git@foo.com/foo") + when: + GitStubDownloaderProperties props = new GitStubDownloaderProperties(resource, new StubRunnerOptionsBuilder().build()) + then: + props.url == URI.create("git:git@foo.com/foo") + } + + Resource resource(String uri) { + return new AbstractResource() { + @Override + String getDescription() { + return null + } + + @Override + InputStream getInputStream() throws IOException { + return null + } + + @Override + URI getURI() throws IOException { + return URI.create(uri) + } + } + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy index 707220e8ff..63493ca351 100644 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy @@ -1,21 +1,23 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.stubrunner +import org.springframework.core.io.ClassPathResource +import org.springframework.core.io.FileSystemResource import spock.lang.Issue import spock.lang.Specification import spock.util.environment.RestoreSystemProperties @@ -26,6 +28,44 @@ class StubRunnerOptionsBuilderSpec extends Specification { private StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder() + def shouldReturnURIOfAResourceFromString() { + + given: + builder.withStubRepositoryRoot("classpath:/logback.xml") + + when: + StubRunnerOptions options = builder.build() + + then: + options.getStubRepositoryRootAsString().startsWith("file:/") + options.getStubRepositoryRootAsString().endsWith("logback.xml") + } + + def shouldReturnURIOfAResourceFromResource() { + + given: + builder.withStubRepositoryRoot(new ClassPathResource("logback.xml")) + + when: + StubRunnerOptions options = builder.build() + + then: + options.getStubRepositoryRootAsString().startsWith("file:/") + options.getStubRepositoryRootAsString().endsWith("logback.xml") + } + + def shouldReturnEmptyStringWhenFileNotFound() { + + given: + builder.withStubRepositoryRoot(new ClassPathResource("fileThatDoesNotExist.xml")) + + when: + StubRunnerOptions options = builder.build() + + then: + options.getStubRepositoryRootAsString() == "" + } + def shouldCreateDependenciesForStub() { given: @@ -189,16 +229,16 @@ class StubRunnerOptionsBuilderSpec extends Specification { @Issue("#466") def shouldSetAllDependenciesFromOptions() { given: - StubRunnerOptionsBuilder builder = builder.withOptions(new StubRunnerOptions(1, 2, "root", StubRunnerProperties.StubsMode.LOCAL, + StubRunnerOptionsBuilder builder = builder.withOptions(new StubRunnerOptions(1, 2, new FileSystemResource("root"), StubRunnerProperties.StubsMode.LOCAL, "classifier", [new StubConfiguration("a:b:c")], [(new StubConfiguration("a:b:c")): 3], "foo", "bar", - new StubRunnerOptions.StubRunnerProxyOptions("host", 4), true, "consumer", "folder", true, false)) + new StubRunnerOptions.StubRunnerProxyOptions("host", 4), true, "consumer", "folder", true, false, [foo: "bar"])) builder.withStubs("foo:bar:baz") when: StubRunnerOptions options = builder.build() then: options.minPortValue == 1 options.maxPortValue == 2 - options.stubRepositoryRoot == "root" + options.stubRepositoryRoot == new FileSystemResource("root") options.stubsMode == StubRunnerProperties.StubsMode.LOCAL options.stubsClassifier == "classifier" options.dependencies == [new StubConfiguration("a:b:c"), new StubConfiguration("foo:bar:baz:classifier")] @@ -212,14 +252,15 @@ class StubRunnerOptionsBuilderSpec extends Specification { options.mappingsOutputFolder == "folder" options.snapshotCheckSkip == true options.deleteStubsAfterTest == false + options.properties == [foo: "bar"] } def shouldNotPrintUsernameAndPassword() { given: - StubRunnerOptionsBuilder builder = builder.withOptions(new StubRunnerOptions(1, 2, "root", + StubRunnerOptionsBuilder builder = builder.withOptions(new StubRunnerOptions(1, 2, new FileSystemResource("root"), StubRunnerProperties.StubsMode.CLASSPATH, "classifier", [new StubConfiguration("a:b:c")], [(new StubConfiguration("a:b:c")): 3], "username123", "password123", - new StubRunnerOptions.StubRunnerProxyOptions("host", 4), true, "consumer", "folder", true, false)) + new StubRunnerOptions.StubRunnerProxyOptions("host", 4), true, "consumer", "folder", true, false, [:])) builder.withStubs("foo:bar:baz") when: String options = builder.build().toString() @@ -247,12 +288,15 @@ class StubRunnerOptionsBuilderSpec extends Specification { System.setProperty("stubrunner.proxy.port", "4") System.setProperty("stubrunner.mappings-output-folder", "folder") System.setProperty("stubrunner.snapshot-check-skip", "true") + System.setProperty("stubrunner.properties.foo-bar", "bar") + System.setProperty("stubrunner.properties.foo-baz", "baz") + System.setProperty("stubrunner.properties.bar.bar", "foo") when: StubRunnerOptions options = StubRunnerOptions.fromSystemProps() then: options.minPortValue == 1 options.maxPortValue == 2 - options.stubRepositoryRoot == "root" + options.stubRepositoryRoot == new ClassPathResource("root") options.stubsMode == StubRunnerProperties.StubsMode.LOCAL options.stubsClassifier == "classifier" options.dependencies == [new StubConfiguration("a:b:c"), new StubConfiguration("foo:bar:baz:classifier")] @@ -264,5 +308,6 @@ class StubRunnerOptionsBuilderSpec extends Specification { options.consumerName == "consumer" options.mappingsOutputFolder == "folder" options.snapshotCheckSkip == true + options.properties == ["foo-bar": "bar", "foo-baz": "baz", "bar.bar": "foo"] } } diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerPropertyUtilsSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerPropertyUtilsSpec.groovy new file mode 100644 index 0000000000..88ce54e71d --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerPropertyUtilsSpec.groovy @@ -0,0 +1,88 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties + +class StubRunnerPropertyUtilsSpec extends Specification { + + @RestoreSystemProperties + def "should return [#expectedResult] when checking if [#queriedProp] is set, and system is [#systemProperty] and env [#envVariable]"() { + given: + def sysProp = systemProperty + def envVar = envVariable + def expectedEnv = expectedEnvVar + PropertyFetcher fetcher = new PropertyFetcher() { + @Override + String systemProp(String prop) { + return sysProp + } + + @Override + String envVar(String prop) { + assert prop == expectedEnv || prop == "STUBRUNNER_PROPERTIES_" + expectedEnv + return envVar + } + } + StubRunnerPropertyUtils.FETCHER = fetcher + expect: + expectedResult == StubRunnerPropertyUtils.isPropertySet(queriedProp) + where: + queriedProp | systemProperty | envVariable | expectedEnvVar | expectedResult + "foo.bar-baz" | null | null | "FOO_BAR_BAZ" | false + "foo.bar-baz" | null | "true" | "FOO_BAR_BAZ" | true + "foo.bar-baz" | null | "false" | "FOO_BAR_BAZ" | false + "foo.bar-baz" | "false" | "true" | "FOO_BAR_BAZ" | false + "foo.bar-baz" | "true" | "true" | "FOO_BAR_BAZ" | true + } + + @RestoreSystemProperties + def "should return [#expectedResult] when queried for [#queriedProp] and system is [#systemProperty] and env [#envVariable]"() { + given: + def sysProp = systemProperty + def envVar = envVariable + def checkedSysProp = assertedSystemProp + def checkedEnvVar = assertedEnvVar + PropertyFetcher fetcher = new PropertyFetcher() { + @Override + String systemProp(String prop) { + assert prop == checkedSysProp || prop == checkedSysProp - "stubrunner.properties." + return sysProp + } + + @Override + String envVar(String prop) { + assert prop == checkedEnvVar || prop == checkedEnvVar - "STUBRUNNER_PROPERTIES_" + return envVar + } + } + StubRunnerPropertyUtils.FETCHER = fetcher + expect: + expectedResult == StubRunnerPropertyUtils.getProperty(map, queriedProp) + where: + queriedProp | map | systemProperty | envVariable | expectedResult | assertedSystemProp | assertedEnvVar + "foo.bar-baz" | ["foo.bar-baz": "faz"] | "ab" | "bc" | "faz" | "stubrunner.properties.foo.bar-baz" | "STUBRUNNER_PROPERTIES_FOO_BAR_BAZ" + "foo.bar-baz" | [:] | "ab" | "bc" | "ab" | "stubrunner.properties.foo.bar-baz" | "STUBRUNNER_PROPERTIES_FOO_BAR_BAZ" + "foo.bar-baz" | [:] | "" | "bc" | "bc" | "stubrunner.properties.foo.bar-baz" | "STUBRUNNER_PROPERTIES_FOO_BAR_BAZ" + "foo.bar-baz" | null | "" | "bc" | "bc" | "stubrunner.properties.foo.bar-baz" | "STUBRUNNER_PROPERTIES_FOO_BAR_BAZ" + } + + def cleanupSpec() { + StubRunnerPropertyUtils.FETCHER = new PropertyFetcher() + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/AbstractGitTest.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/AbstractGitTest.java new file mode 100644 index 0000000000..637a182ad2 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/AbstractGitTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.net.URISyntaxException; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.RemoteRemoveCommand; +import org.eclipse.jgit.api.RemoteSetUrlCommand; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.transport.RefSpec; +import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.URIish; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; + +/** + * @author Marcin Grzejszczak + */ +public abstract class AbstractGitTest { + + @Rule public TemporaryFolder tmp = new TemporaryFolder(); + File tmpFolder; + + @Before + public void setupTemp() throws IOException { + this.tmpFolder = this.tmp.newFolder(); + } + + File createNewFile(File project) throws Exception { + File newFile = new File(project, "newFile"); + newFile.createNewFile(); + try (PrintStream out = new PrintStream(new FileOutputStream(newFile))) { + out.print("foo"); + } + try(Git git = openGitProject(project)) { + git.add().addFilepattern("newFile").call(); + } + return newFile; + } + + void setOriginOnProjectToTmp(File origin, File project, boolean push) + throws GitAPIException, IOException, URISyntaxException { + try(Git git = openGitProject(project)) { + RemoteRemoveCommand remove = git.remoteRemove(); + remove.setName("origin"); + remove.call(); + RemoteSetUrlCommand command = git.remoteSetUrl(); + command.setUri(new URIish(origin.toURI().toURL())); + command.setName("origin"); + command.setPush(push); + command.call(); + StoredConfig config = git.getRepository().getConfig(); + RemoteConfig originConfig = new RemoteConfig(config, "origin"); + originConfig.addFetchRefSpec(new RefSpec("+refs/heads/*:refs/remotes/origin/*")); + originConfig.update(config); + config.save(); + } + } + + Git openGitProject(File project) { + return new GitRepo.JGitFactory().open(project); + } + + File clonedProject(File baseDir, File projectToClone) throws IOException { + GitRepo projectRepo = new GitRepo(baseDir); + projectRepo.cloneProject(projectToClone.toURI()); + return baseDir; + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/ContractProjectUpdaterTest.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/ContractProjectUpdaterTest.java new file mode 100644 index 0000000000..6bd0380d3f --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/ContractProjectUpdaterTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; + +import org.assertj.core.api.BDDAssertions; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.ResetCommand; +import org.eclipse.jgit.revwalk.RevCommit; +import org.junit.Before; +import org.junit.Test; +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class ContractProjectUpdaterTest extends AbstractGitTest { + File originalProject; + File project; + ContractProjectUpdater updater; + GitRepo gitRepo; + File origin; + + @Before + public void setup() throws Exception { + GitContractsRepo.CACHED_LOCATIONS.clear(); + this.originalProject = new File(GitRepoTests.class.getResource("/git_samples/contract-git").toURI()); + TestUtils.prepareLocalRepo(); + this.gitRepo = new GitRepo(this.tmpFolder); + this.origin = clonedProject(this.tmp.newFolder(), this.originalProject); + this.project = this.gitRepo.cloneProject(this.originalProject.toURI()); + setOriginOnProjectToTmp(this.origin, this.project, true); + StubRunnerOptions options = new StubRunnerOptionsBuilder() + .withStubRepositoryRoot("file://" + this.project.getAbsolutePath() + "/") + .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) + .build(); + this.updater = new ContractProjectUpdater(options); + } + + @Test + public void should_push_changes_to_current_branch() throws Exception { + File stubs = new File(GitRepoTests.class.getResource("/git_samples/sample_stubs").toURI()); + + this.updater.updateContractProject("hello-world", stubs.toPath()); + + // project, not origin, cause we're making one more clone of the local copy + try(Git git = openGitProject(this.project)) { + RevCommit revCommit = git.log().call().iterator().next(); + then(revCommit.getShortMessage()).isEqualTo("Updating project [hello-world] with stubs"); + // I have no idea but the file gets deleted after pushing + git.reset().setMode(ResetCommand.ResetType.HARD).call(); + } + BDDAssertions.then(new File(this.project, "META-INF/com.example/hello-world/0.0.2/mappings/someMapping.json")).exists(); + } + + @Test + public void should_not_push_changes_to_current_branch_when_no_changes_were_made() throws Exception { + this.updater.updateContractProject("hello-world", this.origin.toPath()); + + try(Git git = openGitProject(this.project)) { + RevCommit revCommit = git.log().call().iterator().next(); + then(revCommit.getShortMessage()).isEqualTo("Initial commit"); + } + BDDAssertions.then(new File(this.project, "META-INF/com.example/hello-world/0.0.2/mappings/someMapping.json")).doesNotExist(); + } +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java new file mode 100644 index 0000000000..4896422425 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitRepoTests.java @@ -0,0 +1,172 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; + +import org.eclipse.jgit.api.CloneCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.revwalk.RevCommit; +import org.junit.Before; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.BDDAssertions.then; +import static org.assertj.core.api.BDDAssertions.thenThrownBy; + +/** + * @author Marcin Grzejszczak + * taken from: https://github.com/spring-cloud/spring-cloud-release-tools + */ +public class GitRepoTests extends AbstractGitTest { + + File project; + GitRepo gitRepo; + + @Before + public void setup() throws IOException, URISyntaxException { + this.project = new File(GitRepoTests.class.getResource("/git_samples/contract-git").toURI()); + TestUtils.prepareLocalRepo(); + this.gitRepo = new GitRepo(this.tmpFolder); + } + + @Test + public void should_clone_the_project_from_a_given_location() throws IOException { + this.gitRepo.cloneProject(this.project.toURI()); + + then(new File(this.tmpFolder, ".git")).exists(); + } + + @Test + public void should_throw_exception_when_there_is_no_repo() throws IOException, URISyntaxException { + thenThrownBy(() -> this.gitRepo + .cloneProject(GitRepoTests.class.getResource("/git_samples/").toURI())) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Exception occurred while cloning repo"); + } + + @Test + public void should_throw_an_exception_when_failed_to_initialize_the_repo() throws IOException { + thenThrownBy(() -> new GitRepo(this.tmpFolder, new ExceptionThrowingJGitFactory()).cloneProject(this.project.toURI())) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Exception occurred while cloning repo") + .hasCauseInstanceOf(CustomException.class); + } + + @Test + public void should_check_out_a_branch_on_cloned_repo() throws IOException { + File project = this.gitRepo.cloneProject(this.project.toURI()); + this.gitRepo.checkout(project, "master"); + + File pom = new File(this.tmpFolder, "README.adoc"); + then(pom).exists(); + } + + @Test + public void should_throw_an_exception_when_checking_out_nonexisting_branch() throws IOException { + File project = this.gitRepo.cloneProject(this.project.toURI()); + try { + this.gitRepo.checkout(project, "nonExistingBranch"); + fail("should throw an exception"); + } catch (IllegalStateException e) { + then(e).hasMessageContaining("Ref nonExistingBranch can not be resolved"); + } + } + + @Test + public void should_commit_changes() throws Exception { + File project = this.gitRepo.cloneProject(this.project.toURI()); + createNewFile(project); + + this.gitRepo.commit(project, "some message"); + + try(Git git = openGitProject(project)) { + RevCommit revCommit = git.log().call().iterator().next(); + then(revCommit.getShortMessage()).isEqualTo("some message"); + } + } + + @Test + public void should_reset_any_changes() throws Exception { + File project = this.gitRepo.cloneProject(this.project.toURI()); + File file = createNewFile(project); + + this.gitRepo.reset(project); + + then(file).doesNotExist(); + } + + @Test + public void should_not_commit_empty_changes() throws Exception { + File project = this.gitRepo.cloneProject(this.project.toURI()); + createNewFile(project); + this.gitRepo.commit(project, "some message"); + + this.gitRepo.commit(project, "empty commit"); + + try(Git git = openGitProject(project)) { + RevCommit revCommit = git.log().call().iterator().next(); + then(revCommit.getShortMessage()).isNotEqualTo("empty commit"); + } + } + + @Test + public void should_push_changes_to_current_branch() throws Exception { + File origin = clonedProject(this.tmp.newFolder(), this.project); + File project = this.gitRepo.cloneProject(this.project.toURI()); + setOriginOnProjectToTmp(origin, project, true); + createNewFile(project); + this.gitRepo.commit(project, "some message"); + + this.gitRepo.pushCurrentBranch(project); + + try(Git git = openGitProject(origin)) { + RevCommit revCommit = git.log().call().iterator().next(); + then(revCommit.getShortMessage()).isEqualTo("some message"); + } + } + + @Test + public void should_pull_changes_to_current_branch() throws Exception { + File origin = clonedProject(this.tmp.newFolder(), this.project); + File project = this.gitRepo.cloneProject(this.project.toURI()); + setOriginOnProjectToTmp(origin, project, false); + createNewFile(origin); + this.gitRepo.commit(origin, "some message"); + + this.gitRepo.pull(project); + + try(Git git = openGitProject(project)) { + RevCommit revCommit = git.log().call().iterator().next(); + then(revCommit.getShortMessage()).isEqualTo("some message"); + } + } +} + +class ExceptionThrowingJGitFactory extends GitRepo.JGitFactory { + @Override CloneCommand getCloneCommandByCloneRepository() { + throw new CustomException("foo"); + } +} + +class CustomException extends RuntimeException { + public CustomException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java new file mode 100644 index 0000000000..bda2abe724 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/GitStubDownloaderTests.java @@ -0,0 +1,129 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.net.URISyntaxException; +import java.util.Map; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; +import org.springframework.util.FileSystemUtils; + +import static org.assertj.core.api.BDDAssertions.then; + +public class GitStubDownloaderTests { + + @Rule public TemporaryFolder tmp = new TemporaryFolder(); + File temporaryFolder; + + @Before + public void setup() throws Exception { + this.temporaryFolder = this.tmp.newFolder(); + TestUtils.prepareLocalRepo(); + FileSystemUtils.copyRecursively(file("/git_samples/"), this.temporaryFolder); + } + + @Test + public void should_return_a_null_downloader_for_a_classptath_mode() { + StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + + StubDownloader stubDownloader = stubDownloaderBuilder.build(new StubRunnerOptionsBuilder() + .withStubsMode(StubRunnerProperties.StubsMode.CLASSPATH) + .build()); + + then(stubDownloader).isNull(); + } + + @Test + public void should_return_a_null_downloader_for_a_empty_repo() { + StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + + StubDownloader stubDownloader = stubDownloaderBuilder.build(new StubRunnerOptionsBuilder() + .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) + .build()); + + then(stubDownloader).isNull(); + } + + @Test + public void should_return_a_null_downloader_for_a_non_git_repo() { + StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + + StubDownloader stubDownloader = stubDownloaderBuilder.build(new StubRunnerOptionsBuilder() + .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) + .withStubRepositoryRoot("http://foo.com") + .build()); + + then(stubDownloader).isNull(); + } + + @Test + public void should_pick_stubs_for_group_and_artifact_with_version_from_a_git_repo() throws Exception { + StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + StubDownloader stubDownloader = stubDownloaderBuilder.build(new StubRunnerOptionsBuilder() + .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) + .withStubRepositoryRoot("git://" + file("/git_samples/contract-git/").getAbsolutePath() + "/") + .build()); + + Map.Entry entry = stubDownloader + .downloadAndUnpackStubJar(new StubConfiguration("foo.bar:bazService:0.0.1-SNAPSHOT")); + + then(entry).isNotNull(); + then(entry.getValue().getAbsolutePath()).contains("foo.bar" + File.separator + "bazService" + File.separator + "0.0.1-SNAPSHOT"); + } + + @Test + public void should_fail_to_fetch_stubs_when_latest_version_was_specified() + throws URISyntaxException { + StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + StubDownloader stubDownloader = stubDownloaderBuilder.build(new StubRunnerOptionsBuilder() + .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) + .withStubRepositoryRoot("git://" + file("/git_samples/contract-git").getAbsolutePath()) + .build()); + + try { + stubDownloader + .downloadAndUnpackStubJar(new StubConfiguration("foo.bar:bazService:+")); + } catch (IllegalStateException e) { + then(e).hasMessageContaining("Concrete version wasn't passed for [foo.bar:bazService:+:stubs]"); + } + } + + @Test + public void should_fail_to_fetch_stubs_when_concrete_version_was_not_specified() + throws URISyntaxException { + StubDownloaderBuilder stubDownloaderBuilder = new ScmStubDownloaderBuilder(); + StubDownloader stubDownloader = stubDownloaderBuilder.build(new StubRunnerOptionsBuilder() + .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) + .withStubRepositoryRoot("git://" + file("/git_samples/contract-git").getAbsolutePath()) + .build()); + + try { + stubDownloader + .downloadAndUnpackStubJar(new StubConfiguration("foo.bar", "bazService", "")); + } catch (IllegalStateException e) { + then(e).hasMessageContaining("Concrete version wasn't passed for [foo.bar:bazService::stubs]"); + } + } + + private File file(String relativePath) throws URISyntaxException { + return new File(GitStubDownloaderTests.class.getResource(relativePath).toURI()); + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/TestUtils.java b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/TestUtils.java new file mode 100644 index 0000000000..686769f991 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/java/org/springframework/cloud/contract/stubrunner/TestUtils.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.jgit.util.FileUtils; + +class TestUtils { + + public static void prepareLocalRepo() throws IOException { + prepareLocalRepo("target/test-classes/git_samples/", "contract-git"); + } + + private static void prepareLocalRepo(String buildDir, String repoPath) throws IOException { + File dotGit = new File(buildDir + repoPath + "/.git"); + File git = new File(buildDir + repoPath + "/git"); + if (git.exists()) { + if (dotGit.exists()) { + FileUtils.delete(dotGit, FileUtils.RECURSIVE); + } + } + git.renameTo(dotGit); + } + +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/LICENSE.txt b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/LICENSE.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/messaging/shouldSendAcceptedVerification.groovy b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/messaging/shouldSendAcceptedVerification.groovy new file mode 100644 index 0000000000..247c62bae9 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/messaging/shouldSendAcceptedVerification.groovy @@ -0,0 +1,33 @@ +package contracts.beer.messaging + +org.springframework.cloud.contract.spec.Contract.make { + description(""" +Sends a positive verification message when person is eligible to get the beer + +``` +given: + client is old enough +when: + he applies for a beer +then: + we'll send a message with a positive verification +``` + +""") + // Label by means of which the output message can be triggered + label 'accepted_verification' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('clientIsOldEnough()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo 'verifications' + // the body of the output message + body([ + eligible: true + ]) + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/messaging/shouldSendRejectedVerification.groovy b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/messaging/shouldSendRejectedVerification.groovy new file mode 100644 index 0000000000..514f244883 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/messaging/shouldSendRejectedVerification.groovy @@ -0,0 +1,33 @@ +package contracts.beer.messaging + +org.springframework.cloud.contract.spec.Contract.make { + description(""" +Sends a negative verification message when person is not eligible to get the beer + +``` +given: + client is too young +when: + he applies for a beer +then: + we'll send a message with a negative verification +``` + +""") + // Label by means of which the output message can be triggered + label 'rejected_verification' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('clientIsTooYoung()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo 'verifications' + // the body of the output message + body([ + eligible: false + ]) + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/rest/shouldGrantABeerIfOldEnough.groovy b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/rest/shouldGrantABeerIfOldEnough.groovy new file mode 100644 index 0000000000..3e71c00ed5 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/rest/shouldGrantABeerIfOldEnough.groovy @@ -0,0 +1,37 @@ +package contracts.beer.rest + +org.springframework.cloud.contract.spec.Contract.make { + request { + description(""" +Represents a successful scenario of getting a beer + +given: + client is old enough +when: + he applies for a beer +then: + we'll grant him the beer +""") + method 'POST' + url '/check' + body( + age: value(consumer(regex('[2-9][0-9]'))) + ) + headers { + header 'Content-Type', 'application/json' + } + } + response { + status 200 + body( """ + { + "status": "OK" + } + """) + headers { + header( + 'Content-Type', value(consumer('application/json'),producer(regex('application/json.*'))) + ) + } + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/rest/shouldRejectABeerIfTooYoung.groovy b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/rest/shouldRejectABeerIfTooYoung.groovy new file mode 100644 index 0000000000..ef84a9a58e --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/contracts/beer-api-consumer/rest/shouldRejectABeerIfTooYoung.groovy @@ -0,0 +1,37 @@ +package contracts.beer.rest + +org.springframework.cloud.contract.spec.Contract.make { + request { + description(""" +Represents a unsuccessful scenario of getting a beer + +given: + client is not old enough +when: + he applies for a beer +then: + we'll NOT grant him the beer +""") + method 'POST' + url '/check' + body( + age: value(consumer(regex('[0-1][0-9]'))) + ) + headers { + header 'Content-Type', 'application/json' + } + } + response { + status 200 + body( """ + { + "status": "NOT_OK" + } + """) + headers { + header( + 'Content-Type', value(consumer('application/json'),producer(regex('application/json.*'))) + ) + } + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/mappings/beer-api-consumer/rest/shouldGrantABeerIfOldEnough.json b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/mappings/beer-api-consumer/rest/shouldGrantABeerIfOldEnough.json new file mode 100644 index 0000000000..4e627786fd --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/mappings/beer-api-consumer/rest/shouldGrantABeerIfOldEnough.json @@ -0,0 +1,24 @@ +{ + "id" : "e5413ef6-0f3e-4b81-9e78-7a90b53c6ed1", + "request" : { + "url" : "/check", + "method" : "POST", + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + }, + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.['age'] =~ /[2-9][0-9]/)]" + } ] + }, + "response" : { + "status" : 200, + "body" : "{\"status\":\"OK\"}", + "headers" : { + "Content-Type" : "application/json" + }, + "transformers" : [ "response-template" ] + }, + "uuid" : "e5413ef6-0f3e-4b81-9e78-7a90b53c6ed1" +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/mappings/beer-api-consumer/rest/shouldRejectABeerIfTooYoung.json b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/mappings/beer-api-consumer/rest/shouldRejectABeerIfTooYoung.json new file mode 100644 index 0000000000..932477d065 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/com.example/beer-api-producer-external/0.0.1-SNAPSHOT/mappings/beer-api-consumer/rest/shouldRejectABeerIfTooYoung.json @@ -0,0 +1,24 @@ +{ + "id" : "b54426aa-b2ef-4b12-adc9-a05fcf6a4e08", + "request" : { + "url" : "/check", + "method" : "POST", + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + }, + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.['age'] =~ /[0-1][0-9]/)]" + } ] + }, + "response" : { + "status" : 200, + "body" : "{\"status\":\"NOT_OK\"}", + "headers" : { + "Content-Type" : "application/json" + }, + "transformers" : [ "response-template" ] + }, + "uuid" : "b54426aa-b2ef-4b12-adc9-a05fcf6a4e08" +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/foo.bar/bazService/0.0.1-SNAPSHOT/contracts/bazConsumer1/rest/shouldSayHello.groovy b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/foo.bar/bazService/0.0.1-SNAPSHOT/contracts/bazConsumer1/rest/shouldSayHello.groovy new file mode 100644 index 0000000000..5a99d7f0e1 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/foo.bar/bazService/0.0.1-SNAPSHOT/contracts/bazConsumer1/rest/shouldSayHello.groovy @@ -0,0 +1,11 @@ +package contracts.foo.bar.bazService.bazConsumer.rest + +org.springframework.cloud.contract.spec.Contract.make { + request { + method 'GET' + url '/hello' + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/foo.bar/bazService/0.0.1-SNAPSHOT/mappings/bazConsumer1/rest/shouldSayHello.json b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/foo.bar/bazService/0.0.1-SNAPSHOT/mappings/bazConsumer1/rest/shouldSayHello.json new file mode 100644 index 0000000000..8ec1c01300 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/META-INF/foo.bar/bazService/0.0.1-SNAPSHOT/mappings/bazConsumer1/rest/shouldSayHello.json @@ -0,0 +1,12 @@ +{ + "id" : "f4080f7d-4cb2-4301-81d6-492570316aae", + "request" : { + "url" : "/hello", + "method" : "GET" + }, + "response" : { + "status" : 200, + "transformers" : [ "response-template" ] + }, + "uuid" : "f4080f7d-4cb2-4301-81d6-492570316aae" +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/README.adoc b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/README.adoc new file mode 100644 index 0000000000..98908bc72f --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/README.adoc @@ -0,0 +1,70 @@ += Common contracts repo + +This repo contains all contracts for apps in the system. + +== As a consumer + +You are working offline in order to play around with the API of the producer. +What you need to do is to have the producer's stubs installed locally. To do that +you have to (from the root of the repo) + +[source,bash] +---- +cd src/main/resources/contracts/com/example/beer-api-producer-external/1.0.0 +mvn clean install -DskipTests +---- + +Then if you do `ls ./target` you'll see `beer-api-producer-external-0.0.1-SNAPSHOT-stubs.jar`. This jar will + contain the stubs generated from your contracts. That way you +can reference the `com.example:server:+:stubs` dependency in your consumer tests. + +TIP: Don't mind that there's a version mismatch in the stubs and the folder structure. +The version number is there in the folder name for tests related to dealing with +non-Java friendly naming of packages. + +== As a producer + +Assuming that the consumers have filed a PR with the proposed contract the producers +can work offline to generate tests and stubs. To work offline, as a producer you just have +to go to the root folder of the contracts and: + +[source,bash] +---- +./mvnw clean install -DskipTests +---- + +Then if you do `ls ./target` you'll see `contracts-0.0.1-SNAPSHOT.jar`. This file contains +all DSL contracts, for all applications. + +Now the producer can include the `contracts-0.0.1-SNAPSHOT.jar` from your local maven repository. +You can achieve that by setting the proper flag in plugin properties. + +Example for Maven + +[source,xml] +---- + + org.springframework.cloud + spring-cloud-contract-maven-plugin + + + true + + com.example + beer-contracts + + + +---- + +and for Gradle: + +[source,groovy] +---- +contracts { + contractsWorkOffline = true + contractDependency { + stringNotation = "com.example:beer-contracts" + } +} +---- diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/HEAD b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/HEAD new file mode 100644 index 0000000000..cb089cd89a --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/config b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/config new file mode 100644 index 0000000000..15061e6c76 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true +[remote "origin"] + url = git@github.com:marcingrzejszczak/contract-git.git + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/description b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/description new file mode 100644 index 0000000000..498b267a8c --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/applypatch-msg.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/applypatch-msg.sample new file mode 100755 index 0000000000..a5d7b84a67 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/commit-msg.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/commit-msg.sample new file mode 100755 index 0000000000..b58d1184a9 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/post-update.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/post-update.sample new file mode 100755 index 0000000000..ec17ec1939 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-applypatch.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-applypatch.sample new file mode 100755 index 0000000000..4142082bcb --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-commit.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-commit.sample new file mode 100755 index 0000000000..68d62d5446 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-push.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-push.sample new file mode 100755 index 0000000000..6187dbf439 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +z40=0000000000000000000000000000000000000000 + +while read local_ref local_sha remote_ref remote_sha +do + if [ "$local_sha" = $z40 ] + then + # Handle delete + : + else + if [ "$remote_sha" = $z40 ] + then + # New branch, examine all commits + range="$local_sha" + else + # Update to existing branch, examine new commits + range="$remote_sha..$local_sha" + fi + + # Check for WIP commit + commit=`git rev-list -n 1 --grep '^WIP' "$range"` + if [ -n "$commit" ] + then + echo >&2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-rebase.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-rebase.sample new file mode 100755 index 0000000000..33730ca647 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up-to-date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-receive.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-receive.sample new file mode 100755 index 0000000000..a1fd29ec14 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/prepare-commit-msg.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000000..f093a02ec4 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/prepare-commit-msg.sample @@ -0,0 +1,36 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first comments out the +# "Conflicts:" part of a merge commit. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +case "$2,$3" in + merge,) + /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; + +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$1" ;; + + *) ;; +esac + +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/update.sample b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/update.sample new file mode 100755 index 0000000000..80ba94135c --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/index b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/index new file mode 100644 index 0000000000..4977ad0968 Binary files /dev/null and b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/index differ diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/info/exclude b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/info/exclude new file mode 100644 index 0000000000..a5196d1be8 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/HEAD b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/HEAD new file mode 100644 index 0000000000..91006b3a8e --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 0b36113e5fa9713025d50f046e8fd209fc8d9597 Marcin Grzejszczak 1522062299 +0200 clone: from git@github.com:marcingrzejszczak/contract-git.git diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/refs/heads/master b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/refs/heads/master new file mode 100644 index 0000000000..91006b3a8e --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 0b36113e5fa9713025d50f046e8fd209fc8d9597 Marcin Grzejszczak 1522062299 +0200 clone: from git@github.com:marcingrzejszczak/contract-git.git diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/refs/remotes/origin/HEAD b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000000..91006b3a8e --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 0b36113e5fa9713025d50f046e8fd209fc8d9597 Marcin Grzejszczak 1522062299 +0200 clone: from git@github.com:marcingrzejszczak/contract-git.git diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/objects/pack/pack-36eb4e6b44a393bca412489cd42ac7cc572b42d3.idx b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/objects/pack/pack-36eb4e6b44a393bca412489cd42ac7cc572b42d3.idx new file mode 100644 index 0000000000..ef612d3f04 Binary files /dev/null and b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/objects/pack/pack-36eb4e6b44a393bca412489cd42ac7cc572b42d3.idx differ diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/objects/pack/pack-36eb4e6b44a393bca412489cd42ac7cc572b42d3.pack b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/objects/pack/pack-36eb4e6b44a393bca412489cd42ac7cc572b42d3.pack new file mode 100644 index 0000000000..fb8e35c7d1 Binary files /dev/null and b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/objects/pack/pack-36eb4e6b44a393bca412489cd42ac7cc572b42d3.pack differ diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/packed-refs b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/packed-refs new file mode 100644 index 0000000000..5a69e4592d --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled +0b36113e5fa9713025d50f046e8fd209fc8d9597 refs/remotes/origin/master diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/refs/heads/master b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/refs/heads/master new file mode 100644 index 0000000000..505804a448 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/refs/heads/master @@ -0,0 +1 @@ +0b36113e5fa9713025d50f046e8fd209fc8d9597 diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/refs/remotes/origin/HEAD b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/refs/remotes/origin/HEAD new file mode 100644 index 0000000000..6efe28fff8 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/contract-git/git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/spring-cloud-contract-stub-runner/src/test/resources/git_samples/sample_stubs/META-INF/com.example/hello-world/0.0.2/mappings/someMapping.json b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/sample_stubs/META-INF/com.example/hello-world/0.0.2/mappings/someMapping.json new file mode 100644 index 0000000000..d9339d85c5 --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/git_samples/sample_stubs/META-INF/com.example/hello-world/0.0.2/mappings/someMapping.json @@ -0,0 +1,13 @@ +{ + "id" : "b54426bb-b2ef-4b12-adc9-a05fcf6a4e08", + "request" : { + "url" : "/hello", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "world", + "transformers" : [ "response-template" ] + }, + "uuid" : "b54426bb-b2ef-4b12-adc9-a05fcf6a4e08" +} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy index efbb938dbd..043002d9c7 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy @@ -95,12 +95,12 @@ class RecursiveFilesConverter { convertedContent.entrySet().eachWithIndex { Map.Entry content, int index -> Contract dsl = content.key String converted = content.value - if (converted) { - Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) - File newJsonFile = createTargetFileWithProperName(stubGenerator, absoluteTargetPath, - sourceFile, contractsSize, index, dsl) - newJsonFile.setText(converted, StandardCharsets.UTF_8.toString()) - } + if (converted) { + Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) + File newJsonFile = createTargetFileWithProperName(stubGenerator, absoluteTargetPath, + sourceFile, contractsSize, index, dsl) + newJsonFile.setText(converted, StandardCharsets.UTF_8.toString()) + } } } } catch (Exception e) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/.gitignore b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/.gitignore new file mode 100644 index 0000000000..466e24805a --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/.gitignore @@ -0,0 +1 @@ +out/ \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/production/resources/META-INF/gradle-plugins/spring-cloud-contract.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/production/resources/META-INF/gradle-plugins/spring-cloud-contract.properties deleted file mode 100644 index 4531c882cd..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/production/resources/META-INF/gradle-plugins/spring-cloud-contract.properties +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -implementation-class=org.springframework.cloud.contract.verifier.plugin.SpringCloudContractVerifierGradlePlugin \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/build.gradle deleted file mode 100644 index 2a33e16b91..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/build.gradle +++ /dev/null @@ -1,65 +0,0 @@ -buildscript { - repositories { - mavenCentral() - 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-cloud-contract' -apply plugin: 'maven-publish' - -group = 'org.springframework.cloud.testprojects' - -ext { - restAssuredVersion = '3.0.2' - - contractsDir = file("repository/mappings") - stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/repository/") -} - -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 { - compile "org.springframework:spring-web" - compile "org.springframework:spring-context-support" - compile "org.codehaus.groovy:groovy-all:2.5.0-beta-1" - compile 'com.jayway.jsonpath:json-path-assert:2.2.0' - - testCompile "com.github.tomakehurst:wiremock:${wiremockVersion}" - testCompile "com.toomuchcoding.jsonassert:jsonassert:${jsonAssertVersion}" - testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" - testCompile "io.restassured:rest-assured:$restAssuredVersion" - testCompile "io.restassured:spring-mock-mvc:$restAssuredVersion" - testCompile "ch.qos.logback:logback-classic:1.1.2" - testCompile "org.springframework.cloud:spring-cloud-contract-verifier:${verifierVersion}" -} - -contracts { - baseClassForTests = 'org.springframework.cloud.contract.verifier.twitter.places.BaseMockMvcSpec' - basePackageForTests = 'contracts' - contractsDslDir = contractsDir -// generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") - stubsOutputDir = stubsOutputDirRoot - targetFramework = 'Spock' -} - -generateContractTests.dependsOn generateWireMockClientStubs - -wrapper { - gradleVersion '3.5' -} - -test { - testLogging { - exceptionFormat = 'full' - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle.properties deleted file mode 100644 index 4cde276f6d..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle.properties +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -wiremockVersion=2.12.0 -jsonAssertVersion=0.4.10 -verifierVersion=2.0.0.BUILD-SNAPSHOT - diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 6ffa237849..0000000000 Binary files a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 1534560008..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Apr 28 10:55:26 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradlew b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradlew deleted file mode 100755 index 27309d9231..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/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 "$@" diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradlew.bat b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradlew.bat deleted file mode 100644 index 832fdb6079..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@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 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy deleted file mode 100644 index 2288cfd263..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import org.springframework.cloud.contract.spec.Contract - -Contract.make { - priority 2 - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - status 200 - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy deleted file mode 100644 index 24ed641ddd..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import org.springframework.cloud.contract.spec.Contract - -Contract.make { - request { - method 'PUT' - url $(consumer(regex('^/api/[0-9]{2}$')), producer('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - headers { - header 'Content-Type': $(consumer('application/json'), producer(regex('application/json.*'))) - header 'Location': $(consumer('https://localhost:8080'), producer(execute('isEmpty($it)'))) - } - body ( - path: $(consumer('/api/12'), producer(regex('^/api/[0-9]{2}$'))), - correlationId: $(consumer('1223456'), producer(execute('isProperCorrelationId($it)'))) - ) - status 200 - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/settings.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/settings.gradle deleted file mode 100644 index b830ebf4ae..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/settings.gradle +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -rootProject.name='bootSimple' diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy deleted file mode 100644 index d1d2a8dc5f..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.contract.verifier.twitter.place - -import groovy.transform.TypeChecked -import groovy.util.logging.Slf4j -import org.springframework.http.MediaType -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -import static org.springframework.web.bind.annotation.RequestMethod.PUT - -@Slf4j -@RestController -@RequestMapping('/api') -@TypeChecked -class PairIdController { - - @RequestMapping( - value = '{pairId}', - method = PUT, - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { - log.info("Inside PairIdController, doing very important logic") - if (tweets?.text != ["Gonna see you at Warsaw"]) { - throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") - } - return """ - { - "path" : "/api/$pairId", - "correlationId" : 123456 - } - """ - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java deleted file mode 100644 index 3a00ad2722..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.springframework.cloud.contract.verifier.twitter.place; - -public class Tweet { - private String text; - - public String getText() { - return this.text; - } - - public void setText(String text) { - this.text = text; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy deleted file mode 100644 index bced54eaf0..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.contract.verifier.twitter.places - -import org.springframework.cloud.contract.verifier.twitter.place.PairIdController -import org.springframework.http.MediaType -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import spock.lang.Specification - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status - -class AcceptanceSpec extends Specification { - - def "should have controller up and running"() { - given: - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() - expect: - mockMvc.perform(put("/api/${1}"). - contentType(MediaType.APPLICATION_JSON). - content("""[{"text":"Gonna see you at Warsaw"}]""")). - andExpect(status().isOk()) - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy deleted file mode 100644 index 98942df7bd..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.contract.verifier.twitter.places - -import io.restassured.module.mockmvc.RestAssuredMockMvc -import org.springframework.cloud.contract.verifier.twitter.place.PairIdController -import spock.lang.Specification - -// tag::base_class[] -abstract class BaseMockMvcSpec extends Specification { - - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } - - void isProperCorrelationId(Integer correlationId) { - assert correlationId == 123456 - } - - void isEmpty(String value) { - assert value == null - } - -} -// end::base_class[] diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy deleted file mode 100644 index 35592dfc46..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import ch.qos.logback.classic.encoder.PatternLayoutEncoder -import ch.qos.logback.core.ConsoleAppender - -String console = "CONSOLE" -String logPattern = "%d{yyyy-MM-dd HH:mm:ss.SSSZ, Europe/Warsaw} | %-5level | %X{correlationId} | %thread | %logger{1} | %m%n" - -appender(console, ConsoleAppender) { - encoder(PatternLayoutEncoder) { - pattern = logPattern - } -} - -root(INFO, [console]) -logger("org.springframework.cloud", DEBUG) diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/build.gradle deleted file mode 100644 index 5105616b15..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -buildscript { - repositories { - mavenLocal() - mavenCentral() - 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:2.0.0.BUILD-SNAPSHOT") - } -} - -apply plugin: 'checkstyle' - -allprojects { - group = 'com.example.jersey' -} - -ext { - spockVersion = '1.0-groovy-2.4' - - contractVerifierStubsBaseDirectory = 'src/test/resources/stubs' -} - -subprojects { - apply plugin: 'groovy' - - 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 { - testCompile 'org.codehaus.groovy:groovy-all:2.5.0-beta-1' - testCompile "org.spockframework:spock-core:$spockVersion" - testCompile 'junit:junit:4.12' - testCompile "com.github.tomakehurst:wiremock:${wiremockVersion}" - testCompile "com.toomuchcoding.jsonassert:jsonassert:${jsonAssertVersion}" - testCompile "org.springframework.cloud:spring-cloud-contract-verifier:${verifierVersion}" - } -} - -configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { - apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' - apply plugin: 'maven-publish' - - ext['jetty.version'] = '9.2.17.v20160517' - - jar { - version = '0.0.1' - } - - configurations { - compile.exclude module: "spring-boot-starter-tomcat" - } - - dependencies { - compile('org.glassfish.jersey.containers:jersey-container-jetty-http:2.23.2') { - exclude group: 'org.eclipse.jetty' - } - compile 'org.springframework.boot:spring-boot-starter-jersey' - compile 'org.springframework.boot:spring-boot-starter-jetty' - - testRuntime "org.spockframework:spock-spring:$spockVersion" - - compile('org.glassfish.jersey.connectors:jersey-apache-connector:2.23.2') { - exclude group: 'org.eclipse.jetty' - } - testCompile "org.mockito:mockito-core" - testCompile "org.springframework:spring-test" - testCompile "org.springframework.boot:spring-boot-test" - testCompile("com.github.tomakehurst:wiremock:${wiremockVersion}") { - exclude group: 'org.eclipse.jetty' - } - } - - task cleanup(type: Delete) { - delete 'src/test/resources/mappings', 'src/test/resources/stubs' - } - - clean.dependsOn('cleanup') - - test { - testLogging { - exceptionFormat = 'full' - } - } - -} - -configure(project(':fraudDetectionService')) { - test.dependsOn('generateWireMockClientStubs') - - apply plugin: 'spring-cloud-contract' - - ext { - contractsDir = file("mappings") - stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - } - ext['jetty.version'] = '9.2.17.v20160517' - - contracts { - targetFramework = 'Spock' - testMode = 'JaxRsClient' - baseClassForTests = 'org.springframework.cloud.MvcSpec' - contractsRepositoryUrl = "file://" + file("${project.rootDir.absolutePath}/m2repo/repository").absolutePath - contractDependency { - stringNotation("com.example:jersey-contracts:+:") - } - generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") - stubsOutputDir = stubsOutputDirRoot - disableStubPublication(project.hasProperty("disablePublication")) - } -} - -configure(project(':loanApplicationService')) { - - task copyCollaboratorStubs(type: Copy) { - File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) { - include '**/*.json' - } - into "src/test/resources/mappings" - } - - test.dependsOn('copyCollaboratorStubs') -} - -wrapper { - gradleVersion '3.5' -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java deleted file mode 100644 index e671a56892..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import org.glassfish.jersey.server.ResourceConfig; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Bean; -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); - } - - @Bean - ResourceConfig resourceConfig() { - return ResourceConfig.forApplication(new FraudRestApplication()); - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java deleted file mode 100644 index 3eaaea3a42..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import org.springframework.cloud.frauddetection.model.FraudCheck; -import org.springframework.cloud.frauddetection.model.FraudCheckResult; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestBody; - -import javax.ws.rs.*; -import java.math.BigDecimal; - -import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.FRAUD; -import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.OK; - -@Controller -@Path("/") -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"); - - @PUT - @Path("/fraudcheck") - @Produces(FRAUD_SERVICE_JSON_VERSION_1) - @Consumes(FRAUD_SERVICE_JSON_VERSION_1) - public FraudCheckResult fraudCheck(@RequestBody(required = false) FraudCheck fraudCheck) { - if (amountGreaterThanThreshold(fraudCheck)) { - return new FraudCheckResult(FRAUD, AMOUNT_TOO_HIGH); - } - return new FraudCheckResult(OK, NO_REASON); - } - - private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { - return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java deleted file mode 100644 index 064e59196b..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import java.util.Collections; -import java.util.Set; - -public class FraudRestApplication extends javax.ws.rs.core.Application { - - @Override - public Set> getClasses() { - return Collections.>singleton(FraudDetectionController.class); - } - -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java deleted file mode 100644 index 6bb1893764..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudCheck { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudCheck() { - } - - public String getClientPesel() { - return this.clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return this.loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java deleted file mode 100644 index 23dd31d3c8..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.cloud.frauddetection.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 this.fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b4fd951df2..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml deleted file mode 100644 index 1c421cf2b7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ -server.port=0 \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy deleted file mode 100644 index 64055ec4fc..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud -import org.springframework.cloud.frauddetection.Application -import org.springframework.cloud.frauddetection.FraudRestApplication -import org.eclipse.jetty.server.Server -import org.glassfish.jersey.apache.connector.ApacheConnectorProvider -import org.glassfish.jersey.client.ClientConfig -import org.glassfish.jersey.jetty.JettyHttpContainerFactory -import org.glassfish.jersey.server.ResourceConfig -import org.springframework.context.annotation.AnnotationConfigApplicationContext -import spock.lang.Shared -import spock.lang.Specification - -import javax.ws.rs.client.Client -import javax.ws.rs.client.ClientBuilder -import javax.ws.rs.client.WebTarget -import javax.ws.rs.core.UriBuilder - -import static org.springframework.util.SocketUtils.findAvailableTcpPort - -abstract class MvcSpec extends Specification { - - @Shared - WebTarget webTarget - - @Shared - private Server server - - @Shared - private Client client - - def setupSpec() { - - URI baseUri = UriBuilder.fromUri("http://localhost").port(findAvailableTcpPort(8000)).build() - - - ResourceConfig resourceConfig = ResourceConfig.forApplication(new FraudRestApplication()) - resourceConfig.property("contextConfig", new AnnotationConfigApplicationContext(Application)) - server = JettyHttpContainerFactory.createServer(baseUri, resourceConfig, true) - - ClientConfig clientConfig = new ClientConfig() - clientConfig.connectorProvider(new ApacheConnectorProvider()) - client = ClientBuilder.newClient(clientConfig) - - webTarget = client.target(baseUri) - - server.start() - } - - def cleanupSpec() { - client?.close() - server?.stop() - } - - void assertThatRejectionReasonIsNull(def rejectionReason) { - assert !rejectionReason - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java deleted file mode 100644 index 93c9209621..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.springframework.cloud; - -import org.springframework.cloud.frauddetection.Application; -import org.springframework.cloud.frauddetection.FraudRestApplication; -import org.eclipse.jetty.server.Server; -import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.jetty.JettyHttpContainerFactory; -import org.glassfish.jersey.server.ResourceConfig; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.UriBuilder; -import java.net.URI; - -import static org.springframework.util.SocketUtils.findAvailableTcpPort; - -public abstract class MvcTest { - - public static WebTarget webTarget; - - private static Server server; - - private static Client client; - - @BeforeClass - public static void setupTest() { - - URI baseUri = UriBuilder.fromUri("http://localhost").port(findAvailableTcpPort(8000)).build(); - - - ResourceConfig resourceConfig = ResourceConfig.forApplication(new FraudRestApplication()); - resourceConfig.property("contextConfig", new AnnotationConfigApplicationContext(Application.class)); - server = JettyHttpContainerFactory.createServer(baseUri, resourceConfig, true); - - ClientConfig clientConfig = new ClientConfig(); - clientConfig.connectorProvider(new ApacheConnectorProvider()); - client = ClientBuilder.newClient(clientConfig); - - webTarget = client.target(baseUri); - - try { - server.start(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @AfterClass - public static void cleanupTest() { - if(client != null) { - client.close(); - } - if (server != null) { - try { - server.stop(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void assertThatRejectionReasonIsNull(Object rejectionReason) { - assert rejectionReason == null; - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle.properties deleted file mode 100644 index 99be1efefa..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -wiremockVersion=2.12.0 -jsonAssertVersion=0.4.10 -verifierVersion=2.0.0.BUILD-SNAPSHOT diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 6ffa237849..0000000000 Binary files a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 1534560008..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Apr 28 10:55:26 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradlew b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradlew deleted file mode 100755 index 27309d9231..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/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 "$@" diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradlew.bat b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradlew.bat deleted file mode 100644 index 832fdb6079..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@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 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java deleted file mode 100644 index 6a48b8f620..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection; - -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); - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java deleted file mode 100644 index 0923a7a25f..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection; - -import org.springframework.cloud.frauddetection.model.FraudCheckStatus; -import org.springframework.cloud.frauddetection.model.FraudServiceRequest; -import org.springframework.cloud.frauddetection.model.FraudServiceResponse; -import org.springframework.cloud.frauddetection.model.LoanApplication; -import org.springframework.cloud.frauddetection.model.LoanApplicationResult; -import org.springframework.cloud.frauddetection.model.LoanApplicationStatus; -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; - -@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 = 8080; - - public LoanApplicationService() { - this.restTemplate = new RestTemplate(); - } - - 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); - - ResponseEntity response = - this.restTemplate.exchange("http://localhost:" + this.port + "/fraudcheck", HttpMethod.PUT, - new HttpEntity<>(request, httpHeaders), - FraudServiceResponse.class); - - 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 void setPort(int port) { - this.port = port; - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java deleted file mode 100644 index 69bbf8a5be..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.model; - -public class Client { - - private String pesel; - - public String getPesel() { - return this.pesel; - } - - public void setPesel(String pesel) { - this.pesel = pesel; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index 423043dfc3..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java deleted file mode 100644 index fb7c69c80e..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudServiceRequest { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudServiceRequest() { - } - - public FraudServiceRequest(LoanApplication loanApplication) { - this.clientPesel = loanApplication.getClient().getPesel(); - this.loanAmount = loanApplication.getAmount(); - } - - public String getClientPesel() { - return this.clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return this.loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java deleted file mode 100644 index 2299edfaf1..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.model; - -public class FraudServiceResponse { - - private FraudCheckStatus fraudCheckStatus; - - private String rejectionReason; - - public FraudServiceResponse() { - } - - public FraudCheckStatus getFraudCheckStatus() { - return this.fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java deleted file mode 100644 index 1078143f53..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class LoanApplication { - - private Client client; - - private BigDecimal amount; - - private String loanApplicationId; - - public Client getClient() { - return this.client; - } - - public void setClient(Client client) { - this.client = client; - } - - public BigDecimal getAmount() { - return this.amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public String getLoanApplicationId() { - return this.loanApplicationId; - } - - public void setLoanApplicationId(String loanApplicationId) { - this.loanApplicationId = loanApplicationId; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java deleted file mode 100644 index b70bf5d293..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.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 this.loanApplicationStatus; - } - - public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { - this.loanApplicationStatus = loanApplicationStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java deleted file mode 100644 index b70bedf8d1..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.frauddetection.model; - -public enum LoanApplicationStatus { - LOAN_APPLIED, LOAN_APPLICATION_REJECTED -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml deleted file mode 100644 index 1c421cf2b7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ -server.port=0 \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy deleted file mode 100644 index c41c59b9bf..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud - -import org.springframework.boot.test.context.SpringBootContextLoader -import org.springframework.cloud.frauddetection.Application -import org.springframework.cloud.frauddetection.LoanApplicationService -import org.springframework.cloud.frauddetection.model.Client -import org.springframework.cloud.frauddetection.model.LoanApplication -import org.springframework.cloud.frauddetection.model.LoanApplicationResult -import org.springframework.cloud.frauddetection.model.LoanApplicationStatus -import com.github.tomakehurst.wiremock.junit.WireMockClassRule -import org.junit.ClassRule -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.context.ContextConfiguration -import spock.lang.Shared -import spock.lang.Specification - -@ContextConfiguration(loader = SpringBootContextLoader, classes = Application) -class LoanApplicationServiceSpec extends Specification { - - public static int port = org.springframework.util.SocketUtils.findAvailableTcpPort() - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule(port) - - @Autowired - LoanApplicationService sut - - def setup() { - sut.port = port - } - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '1234567890'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } - - def 'should be rejected due to abnormal loan amount'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '1234567890'), amount: 99_999) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLICATION_REJECTED - loanApplication.rejectionReason == 'Amount too high' - } - - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json deleted file mode 100644 index 7229872299..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?99999\"?\\s*\\}\\s*" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json deleted file mode 100644 index 5a251171c7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?123.123\"?\\s*\\}\\s*" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/jersey-contracts-0.0.1-SNAPSHOT.jar b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/jersey-contracts-0.0.1-SNAPSHOT.jar deleted file mode 100644 index 04621a7bb9..0000000000 Binary files a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/jersey-contracts-0.0.1-SNAPSHOT.jar and /dev/null differ diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/jersey-contracts-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/jersey-contracts-0.0.1-SNAPSHOT.pom deleted file mode 100644 index a1c605f7e2..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/jersey-contracts-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,25 +0,0 @@ - - - - - 4.0.0 - com.example - jersey-contracts - 0.0.1-SNAPSHOT - pom - diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 05d9ce3299..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - com.example - jersey-contracts - 0.0.1-SNAPSHOT - - - true - - 20160916125313 - - - jar - 0.0.1-SNAPSHOT - 20160916125313 - - - pom - 0.0.1-SNAPSHOT - 20160916125313 - - - - diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/maven-metadata.xml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/maven-metadata.xml deleted file mode 100644 index 86fde72fbf..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/m2repo/repository/com/example/jersey-contracts/maven-metadata.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - com.example - jersey-contracts - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/settings.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/settings.gradle deleted file mode 100644 index 40ba6eed43..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleJerseyProject/settings.gradle +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -include ':fraudDetectionService' -include ':loanApplicationService' diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/build.gradle deleted file mode 100644 index cf55cbe6ea..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/build.gradle +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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:2.0.0.BUILD-SNAPSHOT") - } -} - -ext { - restAssuredVersion = '3.0.2' - spockVersion = '1.0-groovy-2.4' - - contractVerifierStubsBaseDirectory = 'src/test/resources/stubs' -} - -group = 'org.springframework.cloud.testprojects' - -subprojects { - apply plugin: 'groovy' - - 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 { - testCompile "org.codehaus.groovy:groovy-all:2.5.0-beta-1" - testCompile "org.spockframework:spock-core:$spockVersion" - testCompile("junit:junit:4.12") - testCompile "com.github.tomakehurst:wiremock:${wiremockVersion}" - testCompile "com.toomuchcoding.jsonassert:jsonassert:${jsonAssertVersion}" - testCompile "org.springframework.cloud:spring-cloud-contract-verifier:${verifierVersion}" - } -} - -configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { - apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' - apply plugin: 'spring-cloud-contract' - apply plugin: 'maven-publish' - - ext { - contractsDir = file("mappings") - stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - } - - contracts { - targetFramework = 'Spock' - testMode = 'MockMvc' - baseClassForTests = 'org.springframework.cloud.MvcSpec' - contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") - stubsOutputDir = stubsOutputDirRoot - } - - jar { - version = '0.0.1' - } - - dependencies { - compile("org.springframework.boot:spring-boot-starter-web") { - exclude module: "spring-boot-starter-tomcat" - } - compile("org.springframework.boot:spring-boot-starter-jetty") - compile("org.springframework.boot:spring-boot-starter-actuator") - - testRuntime "org.spockframework:spock-spring:$spockVersion" - testCompile "org.mockito:mockito-core" - testCompile "org.springframework:spring-test" - testCompile "org.springframework.boot:spring-boot-test" - testCompile "io.rest-assured:rest-assured:$restAssuredVersion" - testCompile "io.rest-assured:spring-mock-mvc:$restAssuredVersion" - } - - task cleanup(type: Delete) { - delete 'src/test/resources/mappings', 'src/test/resources/stubs' - } - - clean.dependsOn('cleanup') - - test { - testLogging { - exceptionFormat = 'full' - } - } -} - -configure(project(':fraudDetectionService')) { - test.dependsOn('generateWireMockClientStubs') -} - -configure(project(':loanApplicationService')) { - - task copyCollaboratorStubs(type: Copy) { - File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) - into "src/test/resources/" - } - - generateContractTests.dependsOn('copyCollaboratorStubs') -} - -wrapper { - gradleVersion '3.5' -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy deleted file mode 100644 index abe0e9ebf6..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import org.springframework.cloud.contract.spec.Contract - -Contract.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(consumer(regex('[0-9]{10}')), producer('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(consumer('FRAUD'), producer(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" -}""") - headers { - header('Content-Type': value( - producer(regex('application/vnd.fraud.v1.json.*')), - consumer('application/vnd.fraud.v1+json')) - ) - } - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy deleted file mode 100644 index 9e86f291c0..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import org.springframework.cloud.contract.spec.Contract - -Contract.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(consumer(regex('[0-9]{10}')), producer('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': value( - producer(regex('application/vnd.fraud.v1.json.*')), - consumer('application/vnd.fraud.v1+json')) - ) - } - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java deleted file mode 100644 index bc8131fe49..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.springframework.cloud.frauddetection; - -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( - org.springframework.cloud.frauddetection.Application.class, args); - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java deleted file mode 100644 index 213a037f87..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import org.springframework.cloud.frauddetection.model.FraudCheck; -import org.springframework.cloud.frauddetection.model.FraudCheckResult; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.math.BigDecimal; - -import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.FRAUD; -import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.OK; -import static org.springframework.web.bind.annotation.RequestMethod.PUT; - -@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(FRAUD, AMOUNT_TOO_HIGH); - } - return new FraudCheckResult(OK, NO_REASON); - } - - private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { - return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java deleted file mode 100644 index 6bb1893764..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudCheck { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudCheck() { - } - - public String getClientPesel() { - return this.clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return this.loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java deleted file mode 100644 index 23dd31d3c8..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.cloud.frauddetection.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 this.fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b4fd951df2..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.properties deleted file mode 100644 index 3bfa895df9..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.properties +++ /dev/null @@ -1,4 +0,0 @@ -#WireMock password - http://wiremock.org/docs/running-standalone/ -server.ssl.key-store-password=password -server.ssl.key-password=password -server.ssl.trust-store-password=password \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml deleted file mode 100644 index 1c421cf2b7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ -server.port=0 \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy deleted file mode 100644 index 97bf23938c..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud - -import org.springframework.cloud.frauddetection.FraudDetectionController -import io.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) - } - - void assertThatRejectionReasonIsNull(def rejectionReason) { - assert !rejectionReason - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java deleted file mode 100644 index fd0104594f..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.springframework.cloud; - -import io.restassured.module.mockmvc.RestAssuredMockMvc; -import org.junit.Before; - -public class MvcTest { - - @Before - public void setup() { - RestAssuredMockMvc.standaloneSetup(new org.springframework.cloud.frauddetection.FraudDetectionController()); - } - - public void assertThatRejectionReasonIsNull(Object rejectionReason) { - assert rejectionReason == null; - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle.properties deleted file mode 100644 index a771813121..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -wiremockVersion=2.12.0 -jsonAssertVersion=0.4.10 -verifierVersion=2.0.0.BUILD-SNAPSHOT \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 6ffa237849..0000000000 Binary files a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 1534560008..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Apr 28 10:55:26 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradlew b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradlew deleted file mode 100755 index 27309d9231..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/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 "$@" diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradlew.bat b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradlew.bat deleted file mode 100644 index 832fdb6079..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@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 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java deleted file mode 100644 index bc8131fe49..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.springframework.cloud.frauddetection; - -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( - org.springframework.cloud.frauddetection.Application.class, args); - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java deleted file mode 100644 index 521c7e0337..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import org.springframework.cloud.frauddetection.model.FraudCheckStatus; -import org.springframework.cloud.frauddetection.model.FraudServiceRequest; -import org.springframework.cloud.frauddetection.model.FraudServiceResponse; -import org.springframework.cloud.frauddetection.model.LoanApplication; -import org.springframework.cloud.frauddetection.model.LoanApplicationResult; -import org.springframework.cloud.frauddetection.model.LoanApplicationStatus; -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; - -@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 = 8080; - - public LoanApplicationService() { - this.restTemplate = new RestTemplate(); - } - - 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); - - ResponseEntity response = - this.restTemplate.exchange("http://localhost:" + this.port + "/fraudcheck", HttpMethod.PUT, - new HttpEntity<>(request, httpHeaders), - FraudServiceResponse.class); - - 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 void setPort(int port) { - this.port = port; - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java deleted file mode 100644 index ece842ac53..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public class Client { - - private String pesel; - - public String getPesel() { - return this.pesel; - } - - public void setPesel(String pesel) { - this.pesel = pesel; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b4fd951df2..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java deleted file mode 100644 index 2539638592..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudServiceRequest { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudServiceRequest() { - } - - public FraudServiceRequest(LoanApplication loanApplication) { - this.clientPesel = loanApplication.getClient().getPesel(); - this.loanAmount = loanApplication.getAmount(); - } - - public String getClientPesel() { - return this.clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return this.loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java deleted file mode 100644 index b6b6269c8e..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public class FraudServiceResponse { - - private FraudCheckStatus fraudCheckStatus; - - private String rejectionReason; - - public FraudServiceResponse() { - } - - public FraudCheckStatus getFraudCheckStatus() { - return this.fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java deleted file mode 100644 index 2446b2a8bd..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class LoanApplication { - - private Client client; - - private BigDecimal amount; - - private String loanApplicationId; - - public Client getClient() { - return this.client; - } - - public void setClient(Client client) { - this.client = client; - } - - public BigDecimal getAmount() { - return this.amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public String getLoanApplicationId() { - return this.loanApplicationId; - } - - public void setLoanApplicationId(String loanApplicationId) { - this.loanApplicationId = loanApplicationId; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java deleted file mode 100644 index a7de71b5e8..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.cloud.frauddetection.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 this.loanApplicationStatus; - } - - public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { - this.loanApplicationStatus = loanApplicationStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java deleted file mode 100644 index bdb886d0fc..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum LoanApplicationStatus { - LOAN_APPLIED, LOAN_APPLICATION_REJECTED -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml deleted file mode 100644 index 1c421cf2b7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ -server.port=0 \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy deleted file mode 100644 index 64e61a869c..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud - -import com.github.tomakehurst.wiremock.junit.WireMockClassRule -import org.junit.ClassRule -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootContextLoader -import org.springframework.cloud.frauddetection.Application -import org.springframework.cloud.frauddetection.LoanApplicationService -import org.springframework.cloud.frauddetection.model.Client -import org.springframework.cloud.frauddetection.model.LoanApplication -import org.springframework.cloud.frauddetection.model.LoanApplicationResult -import org.springframework.cloud.frauddetection.model.LoanApplicationStatus -import org.springframework.test.context.ContextConfiguration -import spock.lang.Shared -import spock.lang.Specification - -@ContextConfiguration(loader = SpringBootContextLoader, classes = Application) -class LoanApplicationServiceSpec extends Specification { - - public static int port = org.springframework.util.SocketUtils.findAvailableTcpPort() - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule(port) - - @Autowired - LoanApplicationService sut - - def setup() { - sut.port = port - } - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '1234567890'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } - - def 'should be rejected due to abnormal loan amount'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '1234567890'), amount: 99_999) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLICATION_REJECTED - loanApplication.rejectionReason == 'Amount too high' - } - - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json deleted file mode 100644 index 157726ca2e..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"99999\"}" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json deleted file mode 100644 index afa27159d9..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"123.123\"}" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/settings.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/settings.gradle deleted file mode 100644 index 40ba6eed43..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/sampleProject/settings.gradle +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -include ':fraudDetectionService' -include ':loanApplicationService' diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/build.gradle deleted file mode 100644 index 97fddcb286..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/build.gradle +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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:2.0.0.BUILD-SNAPSHOT") - } -} - -ext { - restAssuredVersion = '3.0.2' - spockVersion = '1.0-groovy-2.4' - - contractVerifierStubsBaseDirectory = 'src/test/resources/stubs' -} - -group = 'org.springframework.cloud.testprojects' - -subprojects { - apply plugin: 'groovy' - apply plugin: 'maven-publish' - - 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 { - testCompile "org.codehaus.groovy:groovy-all:2.5.0-beta-1" - testCompile "org.spockframework:spock-core:$spockVersion" - testCompile "junit:junit:4.12" - testCompile "com.github.tomakehurst:wiremock:${wiremockVersion}" - testCompile "com.toomuchcoding.jsonassert:jsonassert:${jsonAssertVersion}" - testCompile "org.assertj:assertj-core:2.4.1" - testCompile "org.springframework.cloud:spring-cloud-contract-verifier:${verifierVersion}" - } -} - -configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { - apply plugin: 'org.springframework.boot' - apply plugin: 'io.spring.dependency-management' - apply plugin: 'spring-cloud-contract' - - // tag::jar_setup[] - ext { - contractsDir = file("mappings") - stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - } - - // Automatically added by plugin: - // copyContracts - copies contracts to the output folder from which JAR will be created - // verifierStubsJar - JAR with a provided stub suffix - // the presented publication is also added by the plugin but you can modify it as you wish - - publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact verifierStubsJar - } - } - } - // end::jar_setup[] - - contracts { - // tag::target_framework[] - targetFramework = 'Spock' - // end::target_framework[] - testMode = 'MockMvc' - //baseClassForTests = 'org.springframework.cloud.MvcSpec' - // tag::base_class_mapping[] - baseClassMappings { - baseClassMapping('.*', 'org.springframework.cloud.MvcSpec') - } - // end::base_class_mapping[] - contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") - stubsOutputDir = stubsOutputDirRoot - } - - jar { - version = '0.0.1' - } - - dependencies { - compile("org.springframework.boot:spring-boot-starter-web") { - exclude module: "spring-boot-starter-tomcat" - } - compile("org.springframework.boot:spring-boot-starter-jetty") - compile("org.springframework.boot:spring-boot-starter-actuator") - - testRuntime "org.spockframework:spock-spring:$spockVersion" - testCompile "org.mockito:mockito-core" - testCompile "org.springframework:spring-test" - testCompile "org.springframework.boot:spring-boot-test" - testCompile "io.rest-assured:rest-assured:$restAssuredVersion" - testCompile "io.rest-assured:spring-mock-mvc:$restAssuredVersion" - } - - task cleanup(type: Delete) { - delete 'src/test/resources/mappings', 'src/test/resources/stubs' - } - - clean.dependsOn('cleanup') - - test { - testLogging { - exceptionFormat = 'full' - } - } -} - -configure(project(':fraudDetectionService')) { - test.dependsOn('generateWireMockClientStubs') -} - -configure(project(':loanApplicationService')) { - - task copyCollaboratorStubs(type: Copy) { - File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) - into "src/test/resources/mappings" - } - - generateContractTests.dependsOn('copyCollaboratorStubs') -} - -wrapper { - gradleVersion '3.5' -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy deleted file mode 100644 index 9e86f291c0..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import org.springframework.cloud.contract.spec.Contract - -Contract.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(consumer(regex('[0-9]{10}')), producer('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': value( - producer(regex('application/vnd.fraud.v1.json.*')), - consumer('application/vnd.fraud.v1+json')) - ) - } - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy deleted file mode 100644 index 0b3d49edc0..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import org.springframework.cloud.contract.spec.Contract - -Contract.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(consumer(regex('[0-9]{10}')), producer('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(consumer('FRAUD'), producer(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" -}""") - headers { - header('Content-Type': value( - producer(regex('application/vnd.fraud.v1.json.*')), - consumer('application/vnd.fraud.v1+json')) - ) - } - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java deleted file mode 100644 index bc8131fe49..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.springframework.cloud.frauddetection; - -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( - org.springframework.cloud.frauddetection.Application.class, args); - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java deleted file mode 100644 index 213a037f87..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import org.springframework.cloud.frauddetection.model.FraudCheck; -import org.springframework.cloud.frauddetection.model.FraudCheckResult; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.math.BigDecimal; - -import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.FRAUD; -import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.OK; -import static org.springframework.web.bind.annotation.RequestMethod.PUT; - -@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(FRAUD, AMOUNT_TOO_HIGH); - } - return new FraudCheckResult(OK, NO_REASON); - } - - private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { - return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java deleted file mode 100644 index 6bb1893764..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudCheck { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudCheck() { - } - - public String getClientPesel() { - return this.clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return this.loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java deleted file mode 100644 index 23dd31d3c8..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.cloud.frauddetection.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 this.fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b4fd951df2..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml deleted file mode 100644 index 1c421cf2b7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ -server.port=0 \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy deleted file mode 100644 index 97bf23938c..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud - -import org.springframework.cloud.frauddetection.FraudDetectionController -import io.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) - } - - void assertThatRejectionReasonIsNull(def rejectionReason) { - assert !rejectionReason - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java deleted file mode 100644 index fd0104594f..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.springframework.cloud; - -import io.restassured.module.mockmvc.RestAssuredMockMvc; -import org.junit.Before; - -public class MvcTest { - - @Before - public void setup() { - RestAssuredMockMvc.standaloneSetup(new org.springframework.cloud.frauddetection.FraudDetectionController()); - } - - public void assertThatRejectionReasonIsNull(Object rejectionReason) { - assert rejectionReason == null; - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle.properties deleted file mode 100644 index 4cde276f6d..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle.properties +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright 2013-2017 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -wiremockVersion=2.12.0 -jsonAssertVersion=0.4.10 -verifierVersion=2.0.0.BUILD-SNAPSHOT - diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 6ffa237849..0000000000 Binary files a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 1534560008..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Apr 28 10:55:26 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradlew b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradlew deleted file mode 100755 index 27309d9231..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/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 "$@" diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradlew.bat b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradlew.bat deleted file mode 100644 index 832fdb6079..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@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 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java deleted file mode 100644 index bc8131fe49..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.springframework.cloud.frauddetection; - -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( - org.springframework.cloud.frauddetection.Application.class, args); - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java deleted file mode 100644 index 521c7e0337..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.cloud.frauddetection; - -import org.springframework.cloud.frauddetection.model.FraudCheckStatus; -import org.springframework.cloud.frauddetection.model.FraudServiceRequest; -import org.springframework.cloud.frauddetection.model.FraudServiceResponse; -import org.springframework.cloud.frauddetection.model.LoanApplication; -import org.springframework.cloud.frauddetection.model.LoanApplicationResult; -import org.springframework.cloud.frauddetection.model.LoanApplicationStatus; -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; - -@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 = 8080; - - public LoanApplicationService() { - this.restTemplate = new RestTemplate(); - } - - 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); - - ResponseEntity response = - this.restTemplate.exchange("http://localhost:" + this.port + "/fraudcheck", HttpMethod.PUT, - new HttpEntity<>(request, httpHeaders), - FraudServiceResponse.class); - - 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 void setPort(int port) { - this.port = port; - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java deleted file mode 100644 index ece842ac53..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public class Client { - - private String pesel; - - public String getPesel() { - return this.pesel; - } - - public void setPesel(String pesel) { - this.pesel = pesel; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b4fd951df2..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java deleted file mode 100644 index 2539638592..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudServiceRequest { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudServiceRequest() { - } - - public FraudServiceRequest(LoanApplication loanApplication) { - this.clientPesel = loanApplication.getClient().getPesel(); - this.loanAmount = loanApplication.getAmount(); - } - - public String getClientPesel() { - return this.clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return this.loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java deleted file mode 100644 index b6b6269c8e..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public class FraudServiceResponse { - - private FraudCheckStatus fraudCheckStatus; - - private String rejectionReason; - - public FraudServiceResponse() { - } - - public FraudCheckStatus getFraudCheckStatus() { - return this.fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java deleted file mode 100644 index 2446b2a8bd..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -import java.math.BigDecimal; - -public class LoanApplication { - - private Client client; - - private BigDecimal amount; - - private String loanApplicationId; - - public Client getClient() { - return this.client; - } - - public void setClient(Client client) { - this.client = client; - } - - public BigDecimal getAmount() { - return this.amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public String getLoanApplicationId() { - return this.loanApplicationId; - } - - public void setLoanApplicationId(String loanApplicationId) { - this.loanApplicationId = loanApplicationId; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java deleted file mode 100644 index a7de71b5e8..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.cloud.frauddetection.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 this.loanApplicationStatus; - } - - public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { - this.loanApplicationStatus = loanApplicationStatus; - } - - public String getRejectionReason() { - return this.rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java deleted file mode 100644 index bdb886d0fc..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.springframework.cloud.frauddetection.model; - -public enum LoanApplicationStatus { - LOAN_APPLIED, LOAN_APPLICATION_REJECTED -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml deleted file mode 100644 index 1c421cf2b7..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml +++ /dev/null @@ -1 +0,0 @@ -server.port=0 \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy deleted file mode 100644 index 6ddba68db5..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud - -import org.springframework.boot.test.context.SpringBootContextLoader -import org.springframework.cloud.frauddetection.Application -import org.springframework.cloud.frauddetection.LoanApplicationService -import org.springframework.cloud.frauddetection.model.Client -import org.springframework.cloud.frauddetection.model.LoanApplication -import org.springframework.cloud.frauddetection.model.LoanApplicationResult -import org.springframework.cloud.frauddetection.model.LoanApplicationStatus -import com.github.tomakehurst.wiremock.junit.WireMockClassRule -import org.junit.ClassRule -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.context.ContextConfiguration -import spock.lang.Shared -import spock.lang.Specification -import spock.lang.Stepwise - -@ContextConfiguration(loader = SpringBootContextLoader, classes = Application) -@Stepwise -class LoanApplicationServiceSpec extends Specification { - - public static int port = org.springframework.util.SocketUtils.findAvailableTcpPort() - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule(port) - - @Autowired - LoanApplicationService sut - - def setup() { - sut.port = port - } - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '1234567890'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } - - def 'should be rejected due to abnormal loan amount'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '1234567890'), amount: 99_999) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLICATION_REJECTED - loanApplication.rejectionReason == 'Amount too high' - } - - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json deleted file mode 100644 index 157726ca2e..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"99999\"}" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json deleted file mode 100644 index afa27159d9..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"123.123\"}" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" - } -} \ No newline at end of file diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/settings.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/settings.gradle deleted file mode 100644 index 40ba6eed43..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/out/test/resources/functionalTest/scenarioProject/settings.gradle +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -include ':fraudDetectionService' -include ':loanApplicationService' diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy index 0275f1391c..13517e1473 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.verifier.plugin import groovy.transform.ToString @@ -168,6 +184,11 @@ class ContractVerifierExtension { */ boolean deleteStubsAfterTest = true + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + Map contractsProperties = [:] + void contractDependency(@DelegatesTo(Dependency) Closure closure) { closure.delegate = contractDependency closure.call() @@ -183,6 +204,10 @@ class ContractVerifierExtension { closure.call() } + void contractsProperties(Map props) { + contractsProperties = props + } + /** * Is set to true will not provide the default publication task */ @@ -192,7 +217,7 @@ class ContractVerifierExtension { this.disableStubPublication = disableStubPublication } - @ToString + @ToString(includeNames = true, includePackage = false) static class Dependency { String groupId String artifactId diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractsCopyTask.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractsCopyTask.groovy index 2d8dbbe80d..7404ffd7ac 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractsCopyTask.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractsCopyTask.groovy @@ -1,7 +1,24 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.verifier.plugin import groovy.transform.PackageScope import org.gradle.api.internal.ConventionTask +import org.gradle.api.logging.Logger import org.gradle.api.tasks.TaskAction import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties @@ -22,6 +39,7 @@ class ContractsCopyTask extends ConventionTask { void copy() { ContractVerifierConfigProperties props = ExtensionToProperties.fromExtension(getExtension()) File file = getDownloader().downloadAndUnpackContractsIfRequired(getExtension(), props) + file = contractsSubDirIfPresent(logger, file) String antPattern = "${props.includedRootFolderAntPattern}*.*" String slashSeparatedGroupId = project.group.toString().replace(".", File.separator) String slashSeparatedAntPattern = antPattern.replace(slashSeparatedGroupId, project.group.toString()) @@ -44,4 +62,15 @@ class ContractsCopyTask extends ConventionTask { into(outputContractsFolder) } } + + private File contractsSubDirIfPresent(Logger logger, File contractsDirectory) { + File contracts = new File(contractsDirectory, "contracts") + if (contracts.exists()) { + if (logger.isDebugEnabled()) { + logger.debug("Contracts folder found [" + contracts + "]") + } + contractsDirectory = contracts + } + return contractsDirectory + } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateClientStubsFromDslTask.groovy similarity index 69% rename from spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy rename to spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateClientStubsFromDslTask.groovy index af0a5d05f8..4598547f35 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateClientStubsFromDslTask.groovy @@ -1,17 +1,17 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.verifier.plugin @@ -28,11 +28,9 @@ import static org.springframework.cloud.contract.verifier.plugin.SpringCloudCont * Generates stubs from the contracts. The name is WireMock related but the implementation * can differ * - * @since 1.0.0 + * @since 2.0.0 */ -class GenerateWireMockClientStubsFromDslTask extends ConventionTask { - - private static final String DEFAULT_MAPPINGS_FOLDER = 'mappings' +class GenerateClientStubsFromDslTask extends ConventionTask { File stubsOutputDir @@ -48,13 +46,9 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask { logger.info("Spring Cloud Contract Verifier Plugin: Invoking DSL to client stubs conversion") props.contractsDslDir = contractsDslDir props.includedContracts = ".*" - String root = OutputFolderBuilder.buildRootPath(project) - File outMappingsDir = getStubsOutputDir() != null ? - new File(getStubsOutputDir(), "${root}/${DEFAULT_MAPPINGS_FOLDER}") - : new File(project.buildDir, "stubs/${root}/${DEFAULT_MAPPINGS_FOLDER}") + File outMappingsDir = OutputFolderBuilder.outputMappingsDir(project, getStubsOutputDir()) logger.info("Contracts dir is [${contractsDslDir}] output stubs dir is [${outMappingsDir}]") - RecursiveFilesConverter converter = new RecursiveFilesConverter( - props, outMappingsDir) + RecursiveFilesConverter converter = new RecursiveFilesConverter(props, outMappingsDir) converter.processFiles() } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloader.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloader.groovy index 0ef09b46b9..527f5ece93 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloader.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloader.groovy @@ -71,12 +71,16 @@ class GradleContractsDownloader { protected ContractDownloader contractDownloader(ContractVerifierExtension extension, StubConfiguration configuration) { return new ContractDownloader(stubDownloader(extension), configuration, - extension.contractsPath, this.project.group as String, this.project.name) + extension.contractsPath, this.project.group as String, this.project.name, this.project.version as String) } protected StubDownloader stubDownloader(ContractVerifierExtension extension) { StubDownloaderBuilderProvider provider = new StubDownloaderBuilderProvider() - StubRunnerOptionsBuilder options = new StubRunnerOptionsBuilder() + return provider.get(options(extension)) + } + + protected StubRunnerOptions options(ContractVerifierExtension extension) { + StubRunnerOptionsBuilder options = new StubRunnerOptionsBuilder() .withOptions(StubRunnerOptions.fromSystemProps()) .withStubRepositoryRoot(extension.contractRepository.repositoryUrl) .withStubsMode(extension.contractsMode) @@ -84,10 +88,11 @@ class GradleContractsDownloader { .withPassword(extension.contractRepository.password) .withSnapshotCheckSkip(extension.contractsSnapshotCheckSkip) .withDeleteStubsAfterTest(extension.deleteStubsAfterTest) + .withProperties(extension.contractsProperties) if (extension.contractRepository.proxyPort) { options = options.withProxy(extension.contractRepository.proxyHost, extension.contractRepository.proxyPort) } - return provider.get(options.build()) + return options.build() } @PackageScope StubConfiguration stubConfiguration(ContractVerifierExtension.Dependency contractDependency) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/OutputFolderBuilder.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/OutputFolderBuilder.groovy index 515e814b84..80d4df0e58 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/OutputFolderBuilder.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/OutputFolderBuilder.groovy @@ -10,6 +10,8 @@ import org.gradle.api.Project @CompileStatic @PackageScope class OutputFolderBuilder { + + private static final String DEFAULT_MAPPINGS_FOLDER = 'mappings' static String buildRootPath(Project project) { String groupId = project.group as String @@ -17,4 +19,11 @@ class OutputFolderBuilder { String version = project.version return "META-INF/${groupId}/${artifactId}/${version}" } + + static File outputMappingsDir(Project project, File stubsOutputDir) { + String root = OutputFolderBuilder.buildRootPath(project) + return stubsOutputDir != null ? + new File(stubsOutputDir, "${root}/${DEFAULT_MAPPINGS_FOLDER}") + : new File(project.buildDir, "stubs/${root}/${DEFAULT_MAPPINGS_FOLDER}") + } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/PublishStubsToScmTask.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/PublishStubsToScmTask.groovy new file mode 100644 index 0000000000..83908491c0 --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/PublishStubsToScmTask.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import org.gradle.api.internal.ConventionTask +import org.gradle.api.tasks.TaskAction + +import org.springframework.cloud.contract.stubrunner.ContractProjectUpdater +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions + +/** + * For SCM based repositories will copy the generated stubs + * to the cloned repo with contracts and stubs. Will also + * commit the changes and push them to origin. + * + * @author Marcin Grzejszczak + * @since 2.0.0 + */ +@PackageScope +@CompileStatic +class PublishStubsToScmTask extends ConventionTask { + File stubsOutputDir + ContractVerifierExtension configProperties + GradleContractsDownloader downloader + + @TaskAction + void publishStubsToScm() { + String projectName = project.group.toString() + ":" + project.name.toString() + ":" + this.project.version.toString() + project.logger.info("Pushing Stubs to SCM for project [" + projectName + "]") + StubRunnerOptions options = getDownloader().options(getConfigProperties()) + new ContractProjectUpdater(options).updateContractProject(projectName, getStubsOutputDir().toPath()); + } +} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy index 0cc930735c..b284b5d8cf 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy @@ -1,17 +1,17 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.verifier.plugin @@ -24,6 +24,9 @@ import org.gradle.api.plugins.GroovyPlugin import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.plugins.MavenPublishPlugin import org.gradle.jvm.tasks.Jar + +import org.springframework.cloud.contract.stubrunner.ScmStubDownloaderBuilder + /** * Gradle plugin for Spring Cloud Contract Verifier that from the DSL contract can *
    @@ -39,12 +42,11 @@ import org.gradle.jvm.tasks.Jar class SpringCloudContractVerifierGradlePlugin implements Plugin { private static final String GENERATE_SERVER_TESTS_TASK_NAME = 'generateContractTests' - private static final String DEPRECATED_DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWireMockClientStubs' private static final String DSL_TO_CLIENT_TASK_NAME = 'generateClientStubs' @PackageScope static final String COPY_CONTRACTS_TASK_NAME = 'copyContracts' private static final String VERIFIER_STUBS_JAR_TASK_NAME = 'verifierStubsJar' + private static final String PUBLISH_STUBS_TO_SCM_TASK_NAME = 'publishStubsToScm' - private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin private static final String GROUP_NAME = "Verification" private static final String EXTENSION_NAME = 'contracts' @@ -61,9 +63,9 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { Task stubsJar = createAndConfigureStubsJarTasks(extension) Task copyContracts = createAndConfigureCopyContractsTask(stubsJar, downloader, extension) createAndConfigureMavenPublishPlugin(stubsJar, extension) - createGenerateTestsTask(extension, copyContracts) - Task clientTask = createAndConfigureGenerateClientStubsFromDslTask(extension, copyContracts) - createAndConfigureGenerateWireMockClientStubsFromDslTask(extension, clientTask) + createGenerateTestsTask(extension, copyContracts, downloader) + createAndConfigureGenerateClientStubs(extension, copyContracts) + createAndConfigurePublishStubsToScmTask(extension, downloader) addIdeaTestSources(project, extension) } @@ -96,7 +98,8 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { return project.file("${project.projectDir}/src/test/resources/contracts") } - private void createGenerateTestsTask(ContractVerifierExtension extension, Task copyContracts) { + private void createGenerateTestsTask(ContractVerifierExtension extension, Task copyContracts, + GradleContractsDownloader gradleContractsDownloader) { Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) task.description = "Generate server tests from the contracts" task.group = GROUP_NAME @@ -110,18 +113,31 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { project.tasks.findByName("compileTestJava").dependsOn(task) } - // TODO: Remove this task at some point - private void createAndConfigureGenerateWireMockClientStubsFromDslTask(ContractVerifierExtension extension, - Task mainTask) { - Task task = project.tasks.create(DEPRECATED_DSL_TO_WIREMOCK_CLIENT_TASK_NAME) - task.description = "DEPRECATED: Generate WireMock client stubs from the contracts. Use ${DSL_TO_CLIENT_TASK_NAME} task." + private void createAndConfigurePublishStubsToScmTask(ContractVerifierExtension extension, + GradleContractsDownloader gradleContractsDownloader) { + Task task = project.tasks.create(PUBLISH_STUBS_TO_SCM_TASK_NAME, PublishStubsToScmTask) + task.description = "The generated stubs get committed to the SCM repo and pushed to origin" task.group = GROUP_NAME - task.dependsOn mainTask + task.conventionMapping.with { + downloader = { gradleContractsDownloader } + configProperties = { extension } + stubsOutputDir = { extension.stubsOutputDir } + } + task.onlyIf { + String contractRepoUrl = extension.contractsRepositoryUrl ?: + extension.contractRepository.repositoryUrl ?: "" + if (!contractRepoUrl || !ScmStubDownloaderBuilder.isProtocolAccepted(contractRepoUrl)) { + project.logger.info("Skipping pushing stubs to scm since your [contractsRepositoryUrl] property doesn't match any of the accepted protocols") + return false + } + return true + } + task.dependsOn DSL_TO_CLIENT_TASK_NAME } - private Task createAndConfigureGenerateClientStubsFromDslTask(ContractVerifierExtension extension, - Task copyContracts) { - Task task = project.tasks.create(DSL_TO_CLIENT_TASK_NAME, GenerateWireMockClientStubsFromDslTask) + private Task createAndConfigureGenerateClientStubs(ContractVerifierExtension extension, + Task copyContracts) { + Task task = project.tasks.create(DSL_TO_CLIENT_TASK_NAME, GenerateClientStubsFromDslTask) task.description = "Generate client stubs from the contracts" task.group = GROUP_NAME task.conventionMapping.with { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy deleted file mode 100755 index e2f81bd2b1..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.contract.verifier.plugin - -import org.gradle.testkit.runner.BuildResult -import org.junit.Ignore -import org.springframework.cloud.contract.verifier.util.AssertionUtil -import spock.lang.Stepwise - -import static org.gradle.testkit.runner.TaskOutcome.SUCCESS -import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE - -@Stepwise -@Ignore -class BasicFunctionalSpec extends ContractVerifierIntegrationSpec { - - private static final String GENERATED_TEST = "build//generated-test-sources//contracts//contracts//spring//cloud//twitter_places_analyzer//PairIdSpec.groovy" - private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//spring//cloud//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" - private static final String GROOVY_DSL_CONTRACT = "repository//mappings//spring//cloud//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" - private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/test/TEST-contracts.spring.cloud.twitter_places_analyzer.PairIdSpec.xml" - - def setup() { - setupForProject("functionalTest/bootSimple") - runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it - } - - def "should pass basic flow"() { - when: - BuildResult result = run(checkAndPublishToMavenLocal()) - then: - result.task(":generateWireMockClientStubs").outcome == SUCCESS - result.task(":generateClientStubs").outcome == SUCCESS - result.task(":generateContractTests").outcome == SUCCESS - - and: "tests generated" - fileExists(GENERATED_TEST) - - and: "client stubs generated" - fileExists(GENERATED_CLIENT_JSON_STUB) - - and: "generated tests executed" - fileExists(TEST_EXECUTION_XML_REPORT) - } - - def "should generate valid client json stubs for simple input"() { - when: - run('generateWireMockClientStubs') - then: - def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text - AssertionUtil.assertThatJsonsAreEqual(""" - { - "request" : { - "url" : "/api/12", - "method" : "PUT", - "bodyPatterns" : [ { - "matchesJsonPath" : "\$[*][?(@.text == 'Gonna see you at Warsaw')]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 200 - }, - "priority" : 2 - } - """, generatedClientJsonStub) - } - - @Ignore("for some reason it's flickering") - def "tasks should be up-to-date when appropriate"() { - given: - assert !fileExists(GENERATED_CLIENT_JSON_STUB) - assert !fileExists(TEST_EXECUTION_XML_REPORT) - when: - runTasksSuccessfully('generateWireMockClientStubs', 'generateContractTests') - then: - fileExists(GENERATED_CLIENT_JSON_STUB) - fileExists(GENERATED_TEST) - - when: "running generation without change inputs" - def secondExecutionResult = run('generateWireMockClientStubs', 'generateContractTests') - - then: "tasks should be up-to-date" - validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateWireMockClientStubs', 'generateContractTests') - - when: "inputs changed" - def groovyDslFile = file(GROOVY_DSL_CONTRACT) - groovyDslFile.text = groovyDslFile.text.replace("200", "599") - - and: "tasks run" - def thirdExecutionResult = run('generateWireMockClientStubs', 'generateContractTests') - - then: "tasks should be reexecuted" - validateTasksOutcome(thirdExecutionResult, SUCCESS, 'generateWireMockClientStubs', 'generateContractTests') - - and: "changes visible in generate files" - file(GENERATED_CLIENT_JSON_STUB).text.contains("599") - file(GENERATED_TEST).text.contains("599") - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy index 0b6ca2514f..82a2ae666e 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy @@ -50,7 +50,7 @@ class ContractVerifierSpec extends Specification { project.tasks.check.getDependsOn().contains("generateContractTests") } - def "should create generateWireMockClientStubs task"() { + def "should create generateClientStubs task"() { given: project.plugins.apply(SpringCloudContractVerifierGradlePlugin) @@ -66,7 +66,7 @@ class ContractVerifierSpec extends Specification { project.tasks.findByName("verifierStubsJar") != null } - def "should configure generateWireMockClientStubs task as a dependency of the verifierStubsJar task"() { + def "should configure generateClientStubs task as a dependency of the verifierStubsJar task"() { given: project.plugins.apply(SpringCloudContractVerifierGradlePlugin) @@ -74,6 +74,14 @@ class ContractVerifierSpec extends Specification { project.tasks.verifierStubsJar.getDependsOn().contains("generateClientStubs") } + def "should configure generateClientStubs task as a dependency of the publishStubsToScm task"() { + given: + project.plugins.apply(SpringCloudContractVerifierGradlePlugin) + + expect: + project.tasks.publishStubsToScm.getDependsOn().contains("generateClientStubs") + } + def "should create copyContracts task"() { given: project.plugins.apply(SpringCloudContractVerifierGradlePlugin) diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 93049fc9b8..2495415709 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -53,7 +53,7 @@ contracts { targetFramework = 'Spock' } -generateContractTests.dependsOn generateWireMockClientStubs +generateContractTests.dependsOn generateClientStubs wrapper { gradleVersion '3.5' diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index 074eef7af1..3f1c06b451 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -106,7 +106,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') } configure(project(':fraudDetectionService')) { - test.dependsOn('generateWireMockClientStubs') + test.dependsOn('generateClientStubs') apply plugin: 'spring-cloud-contract' diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index b1399f74f3..62f4407ffe 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -111,7 +111,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') } configure(project(':fraudDetectionService')) { - test.dependsOn('generateWireMockClientStubs') + test.dependsOn('generateClientStubs') } configure(project(':loanApplicationService')) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 06a0a5b70e..f54d7b18b0 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -135,7 +135,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') } configure(project(':fraudDetectionService')) { - test.dependsOn('generateWireMockClientStubs') + test.dependsOn('generateClientStubs') } configure(project(':loanApplicationService')) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/ConvertMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/ConvertMojo.java index 5681423795..639953ba16 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/ConvertMojo.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/ConvertMojo.java @@ -1,28 +1,29 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-2017 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.cloud.contract.maven.verifier; import java.io.File; +import java.util.HashMap; +import java.util.Map; import javax.inject.Inject; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; @@ -148,6 +149,7 @@ public class ConvertMojo extends AbstractMojo { @Parameter(property = "contractsSnapshotCheckSkip", defaultValue = "false") private boolean contractsSnapshotCheckSkip; + /** * If set to {@code false} will NOT delete stubs from a temporary * folder after running tests @@ -155,6 +157,12 @@ public class ConvertMojo extends AbstractMojo { @Parameter(property = "deleteStubsAfterTest", defaultValue = "true") private boolean deleteStubsAfterTest; + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + @Parameter(property = "contractsProperties") + private Map contractsProperties = new HashMap<>(); + @Component(role = MavenResourcesFiltering.class, hint = "default") private MavenResourcesFiltering mavenResourcesFiltering; @@ -165,7 +173,7 @@ public class ConvertMojo extends AbstractMojo { this.aetherStubDownloaderFactory = aetherStubDownloaderFactory; } - public void execute() throws MojoExecutionException, MojoFailureException { + public void execute() throws MojoExecutionException { if (this.skip) { getLog().info(String.format( "Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip=%s", @@ -179,33 +187,60 @@ public class ConvertMojo extends AbstractMojo { // download contracts, unzip them and pass as output directory ContractVerifierConfigProperties config = new ContractVerifierConfigProperties(); config.setExcludeBuildFolders(this.excludeBuildFolders); - File contractsDirectory = new MavenContractsDownloader(this.project, this.contractDependency, - this.contractsPath, this.contractsRepositoryUrl, this.contractsMode, getLog(), - this.contractsRepositoryUsername, this.contractsRepositoryPassword, - this.contractsRepositoryProxyHost, this.contractsRepositoryProxyPort, - this.contractsSnapshotCheckSkip, this.deleteStubsAfterTest) - .downloadAndUnpackContractsIfRequired(config, this.contractsDirectory); + File contractsDirectory = locationOfContracts(config); getLog().info("Directory with contract is present at [" + contractsDirectory + "]"); - + contractsDirectory = contractSubfolderIfPresent(contractsDirectory); new CopyContracts(this.project, this.mavenSession, this.mavenResourcesFiltering, config) .copy(contractsDirectory, this.stubsDirectory, rootPath); + File contractsDslDir = contractsDslDir(contractsDirectory); + config.setContractsDslDir(contractsDslDir); + config.setStubsOutputDir(stubsOutputDir(rootPath)); + logSetup(config, contractsDslDir); + RecursiveFilesConverter converter = new RecursiveFilesConverter(config); + converter.processFiles(); + } - config.setContractsDslDir(isInsideProject() ? - contractsDirectory : this.source); - config.setStubsOutputDir( - isInsideProject() ? new File(this.stubsDirectory, rootPath + MAPPINGS_PATH) : this.destination); - + private void logSetup(ContractVerifierConfigProperties config, File contractsDslDir) { + if (getLog().isDebugEnabled()) { + getLog().debug("The contracts dir equals [" + contractsDslDir + "]"); + } getLog().info( "Converting from Spring Cloud Contract Verifier contracts to WireMock stubs mappings"); getLog().info(String.format( " Spring Cloud Contract Verifier contracts directory: %s", config.getContractsDslDir())); - getLog().info(String.format("WireMock stubs mappings directory: %s", + getLog().info(String.format("Stub Server stubs mappings directory: %s", config.getStubsOutputDir())); + } + private File contractSubfolderIfPresent(File contractsDirectory) { + File contractsSubFolder = new File(contractsDirectory, "contracts"); + if (contractsSubFolder.exists()) { + if (getLog().isDebugEnabled()) { + getLog().debug( + "The subfolder [contracts] exists, will pick it as a source of contracts"); + } + contractsDirectory = contractsSubFolder; + } + return contractsDirectory; + } - RecursiveFilesConverter converter = new RecursiveFilesConverter(config); - converter.processFiles(); + private File locationOfContracts(ContractVerifierConfigProperties config) { + return new MavenContractsDownloader(this.project, this.contractDependency, + this.contractsPath, this.contractsRepositoryUrl, this.contractsMode, getLog(), + this.contractsRepositoryUsername, this.contractsRepositoryPassword, + this.contractsRepositoryProxyHost, this.contractsRepositoryProxyPort, + this.contractsSnapshotCheckSkip, this.deleteStubsAfterTest, this.contractsProperties) + .downloadAndUnpackContractsIfRequired(config, this.contractsDirectory); + } + + private File stubsOutputDir(String rootPath) { + return isInsideProject() ? new File(this.stubsDirectory, rootPath + MAPPINGS_PATH) : this.destination; + } + + private File contractsDslDir(File contractsDirectory) { + return isInsideProject() ? + contractsDirectory : this.source; } private boolean isInsideProject() { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/CopyContracts.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/CopyContracts.java index feb86a66e2..d8339fa37b 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/CopyContracts.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/CopyContracts.java @@ -49,15 +49,23 @@ class CopyContracts { public void copy(File contractsDirectory, File outputDirectory, String rootPath) throws MojoExecutionException { - log.info("Copying Spring Cloud Contract Verifier contracts. Only files matching " - + "[" + this.config.getIncludedContracts() + "] pattern will end up in " + File outputFolderWithContracts = outputDirectory.getPath().endsWith("contracts") ? + outputDirectory : new File(outputDirectory, rootPath + CONTRACTS_PATH); + log.info("Copying Spring Cloud Contract Verifier contracts to ["+ outputFolderWithContracts + "]" + + ". Only files matching [" + this.config.getIncludedContracts() + "] pattern will end up in " + "the final JAR with stubs."); Resource resource = new Resource(); - // by default group id is slash separated... String includedRootFolderAntPattern = this.config.getIncludedRootFolderAntPattern() + "*.*"; - resource.addInclude(includedRootFolderAntPattern); - // ...we also want to allow dot separation - resource.addInclude(includedRootFolderAntPattern.replace(slashSeparatedGroupId(), this.project.getGroupId())); + String slashSeparatedGroupIdAntPattern = + slashSeparatedGroupIdAntPattern(includedRootFolderAntPattern); + String dotSeparatedGroupIdAntPattern = + dotSeparatedGroupIdAntPattern(includedRootFolderAntPattern); + // by default group id is slash separated... + resource.addInclude(slashSeparatedGroupIdAntPattern); + if (!slashSeparatedGroupIdAntPattern.equals(dotSeparatedGroupIdAntPattern)) { + // ...we also want to allow dot separation + resource.addInclude(dotSeparatedGroupIdAntPattern); + } if (this.config.isExcludeBuildFolders()) { resource.addExclude("**/target/**"); resource.addExclude("**/build/**"); @@ -65,7 +73,7 @@ class CopyContracts { resource.setDirectory(contractsDirectory.getAbsolutePath()); MavenResourcesExecution execution = new MavenResourcesExecution(); execution.setResources(Collections.singletonList(resource)); - execution.setOutputDirectory(new File(outputDirectory, rootPath + CONTRACTS_PATH)); + execution.setOutputDirectory(outputFolderWithContracts); execution.setMavenProject(this.project); execution.setEncoding("UTF-8"); execution.setMavenSession(this.mavenSession); @@ -81,8 +89,30 @@ class CopyContracts { } } + private String slashSeparatedGroupIdAntPattern(String includedRootFolderAntPattern) { + if (includedRootFolderAntPattern.contains(slashSeparatedGroupId())) { + return includedRootFolderAntPattern; + } else if (includedRootFolderAntPattern.contains(dotSeparatedGroupId())) { + return includedRootFolderAntPattern.replace(dotSeparatedGroupId(), slashSeparatedGroupId()); + } + return includedRootFolderAntPattern; + } + + private String dotSeparatedGroupIdAntPattern(String includedRootFolderAntPattern) { + if (includedRootFolderAntPattern.contains(dotSeparatedGroupId())) { + return includedRootFolderAntPattern; + } else if (includedRootFolderAntPattern.contains(slashSeparatedGroupId())) { + return includedRootFolderAntPattern.replace(slashSeparatedGroupId(), dotSeparatedGroupId()); + } + return includedRootFolderAntPattern; + } + private String slashSeparatedGroupId() { return this.project.getGroupId().replace(".", File.separator); } + private String dotSeparatedGroupId() { + return this.project.getGroupId(); + } + } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateStubsMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateStubsMojo.java index 3398186708..20a72dfcf5 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateStubsMojo.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateStubsMojo.java @@ -39,11 +39,6 @@ import org.codehaus.plexus.archiver.jar.JarArchiver; requiresProject = true) public class GenerateStubsMojo extends AbstractMojo { - private static final String STUB_MAPPING_FILE_PATTERN = "**/*.json"; - private static final String GROOVY_CONTRACT_FILE_PATTERN = "**/*.groovy"; - private static final String YAML_CONTRACT_FILE_PATTERN = "**/*.yaml"; - private static final String YML_CONTRACT_FILE_PATTERN = "**/*.yml"; - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) private File projectBuildDirectory; @@ -79,9 +74,6 @@ public class GenerateStubsMojo extends AbstractMojo { @Component(role = Archiver.class, hint = "jar") private JarArchiver archiver; - @Parameter(defaultValue = "true") - private boolean attachContracts; - @Parameter(defaultValue = "stubs") private String classifier; @@ -110,21 +102,8 @@ public class GenerateStubsMojo extends AbstractMojo { getLog().info("Files matching this pattern will be excluded from " + "stubs generation " + Arrays.toString(excludes)); try { - if (this.attachContracts) { - this.archiver.addDirectory(stubsOutputDir, - new String[] { STUB_MAPPING_FILE_PATTERN, - GROOVY_CONTRACT_FILE_PATTERN, - YAML_CONTRACT_FILE_PATTERN, - YML_CONTRACT_FILE_PATTERN }, - excludedFilesEmpty() ? new String[0] : this.excludedFiles); - } - else { - getLog().info( - "Skipping attaching Spring Cloud Contract Verifier contracts"); - this.archiver.addDirectory(stubsOutputDir, - new String[] { STUB_MAPPING_FILE_PATTERN }, - excludes); - } + this.archiver.addDirectory(stubsOutputDir, new String[] { "**/*.*" }, + excludedFilesEmpty() ? new String[0] : this.excludedFiles); this.archiver.setCompress(true); this.archiver.setDestFile(stubsJarFile); this.archiver.addConfiguredManifest(ManifestCreator.createManifest(this.project)); @@ -139,9 +118,6 @@ public class GenerateStubsMojo extends AbstractMojo { private String[] excludes() { List excludes = new ArrayList<>(); - excludes.add(GROOVY_CONTRACT_FILE_PATTERN); - excludes.add(YAML_CONTRACT_FILE_PATTERN); - excludes.add(YML_CONTRACT_FILE_PATTERN); if (!excludedFilesEmpty()) { excludes.addAll(Arrays.asList(this.excludedFiles)); } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java index 7549e37f76..7ba4fd532b 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java @@ -122,7 +122,7 @@ public class GenerateTestsMojo extends AbstractMojo { @Parameter(property = "skipTests", defaultValue = "false") private boolean skipTests; /** - * The URL from which a JAR containing the contracts should get downloaded. If not provided + * The URL from which a contracts should get downloaded. If not provided * but artifactid / coordinates notation was provided then the current Maven's build repositories will be * taken into consideration */ @@ -210,6 +210,12 @@ public class GenerateTestsMojo extends AbstractMojo { @Parameter(property = "deleteStubsAfterTest", defaultValue = "true") private boolean deleteStubsAfterTest; + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + @Parameter(property = "contractsProperties") + private Map contractsProperties = new HashMap<>(); + private final AetherStubDownloaderFactory aetherStubDownloaderFactory; @Inject @@ -232,7 +238,7 @@ public class GenerateTestsMojo extends AbstractMojo { this.contractsPath, this.contractsRepositoryUrl, this.contractsMode, getLog(), this.contractsRepositoryUsername, this.contractsRepositoryPassword, this.contractsRepositoryProxyHost, this.contractsRepositoryProxyPort, - this.contractsSnapshotCheckSkip, this.deleteStubsAfterTest).downloadAndUnpackContractsIfRequired(config, this.contractsDirectory); + this.contractsSnapshotCheckSkip, this.deleteStubsAfterTest, this.contractsProperties).downloadAndUnpackContractsIfRequired(config, this.contractsDirectory); getLog().info("Directory with contract is present at [" + contractsDirectory + "]"); setupConfig(config, contractsDirectory); this.project.addTestCompileSourceRoot(this.generatedTestSourcesDir.getAbsolutePath()); diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/MavenContractsDownloader.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/MavenContractsDownloader.java index 7ddbe8f6c0..db8e82283b 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/MavenContractsDownloader.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/MavenContractsDownloader.java @@ -1,6 +1,23 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.maven.verifier; import java.io.File; +import java.util.Map; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.logging.Log; @@ -39,14 +56,14 @@ class MavenContractsDownloader { private final Integer repositoryProxyPort; private final boolean contractsSnapshotCheckSkip; private final boolean deleteStubsAfterTest; + private final Map contractsProperties; MavenContractsDownloader(MavenProject project, Dependency contractDependency, String contractsPath, String contractsRepositoryUrl, - StubRunnerProperties.StubsMode stubsMode, Log log, - String repositoryUsername, + StubRunnerProperties.StubsMode stubsMode, Log log, String repositoryUsername, String repositoryPassword, String repositoryProxyHost, Integer repositoryProxyPort, boolean contractsSnapshotCheckSkip, - boolean deleteStubsAfterTest) { + boolean deleteStubsAfterTest, Map contractsProperties) { this.project = project; this.contractDependency = contractDependency; this.contractsPath = contractsPath; @@ -60,6 +77,7 @@ class MavenContractsDownloader { this.stubDownloaderBuilderProvider = new StubDownloaderBuilderProvider(); this.contractsSnapshotCheckSkip = contractsSnapshotCheckSkip; this.deleteStubsAfterTest = deleteStubsAfterTest; + this.contractsProperties = contractsProperties; } File downloadAndUnpackContractsIfRequired(ContractVerifierConfigProperties config, File defaultContractsDir) { @@ -82,12 +100,14 @@ class MavenContractsDownloader { } private boolean shouldDownloadContracts() { - return this.contractDependency != null && StringUtils.hasText(this.contractDependency.getArtifactId()); + return this.contractDependency != null && StringUtils.hasText(this.contractDependency.getArtifactId()) || + StringUtils.hasText(this.contractsRepositoryUrl); } private ContractDownloader contractDownloader() { return new ContractDownloader(stubDownloader(), stubConfiguration(), - this.contractsPath, this.project.getGroupId(), this.project.getArtifactId()); + this.contractsPath, this.project.getGroupId(), this.project.getArtifactId(), + this.project.getVersion()); } private StubDownloader stubDownloader() { @@ -99,12 +119,15 @@ class MavenContractsDownloader { StubRunnerOptions buildOptions() { StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder() .withOptions(StubRunnerOptions.fromSystemProps()) - .withStubRepositoryRoot(this.contractsRepositoryUrl) .withStubsMode(this.stubsMode) .withUsername(this.repositoryUsername) .withPassword(this.repositoryPassword) .withSnapshotCheckSkip(this.contractsSnapshotCheckSkip) - .withDeleteStubsAfterTest(this.deleteStubsAfterTest); + .withDeleteStubsAfterTest(this.deleteStubsAfterTest) + .withProperties(this.contractsProperties); + if (StringUtils.hasText(this.contractsRepositoryUrl)) { + builder.withStubRepositoryRoot(this.contractsRepositoryUrl); + } if (this.repositoryProxyPort != null) { builder.withProxy(this.repositoryProxyHost, this.repositoryProxyPort); } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/PushStubsToScmMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/PushStubsToScmMojo.java new file mode 100644 index 0000000000..bdff73263f --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/PushStubsToScmMojo.java @@ -0,0 +1,132 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.maven.verifier; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.springframework.cloud.contract.stubrunner.ContractProjectUpdater; +import org.springframework.cloud.contract.stubrunner.ScmStubDownloaderBuilder; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder; +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; +import org.springframework.util.StringUtils; + +/** + * The generated stubs get committed to the SCM repo and pushed to origin. + */ +@SuppressWarnings("FieldCanBeLocal") +@Mojo(name = "pushStubsToScm") +public class PushStubsToScmMojo extends AbstractMojo { + + @Parameter(defaultValue = "${project.build.directory}", readonly = true, + required = true) + private File projectBuildDirectory; + + @Parameter(property = "stubsDirectory", + defaultValue = "${project.build.directory}/stubs") + private File outputDirectory; + + /** + * Set this to "true" to bypass the whole Verifier execution + */ + @Parameter(property = "spring.cloud.contract.verifier.skip", defaultValue = "false") + private boolean skip; + + /** + * Set this to "true" to bypass only JAR creation + */ + @Parameter(property = "spring.cloud.contract.verifier.publish-stubs-to-scm.skip", defaultValue = "false") + private boolean taskSkip; + + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; + + /** + * The user name to be used to connect to the repo with contracts. + */ + @Parameter(property = "contractsRepositoryUsername") + private String contractsRepositoryUsername; + + /** + * The password to be used to connect to the repo with contracts. + */ + @Parameter(property = "contractsRepositoryPassword") + private String contractsRepositoryPassword; + + /** + * The URL from which a contracts should get downloaded. If not provided + * but artifactid / coordinates notation was provided then the current Maven's build repositories will be + * taken into consideration + */ + @Parameter(property = "contractsRepositoryUrl") + private String contractsRepositoryUrl; + + /** + * Picks the mode in which stubs will be found and registered + */ + @Parameter(property = "contractsMode", defaultValue = "CLASSPATH") + private StubRunnerProperties.StubsMode contractsMode; + + + /** + * If set to {@code false} will NOT delete stubs from a temporary + * folder after running tests + */ + @Parameter(property = "deleteStubsAfterTest", defaultValue = "true") + private boolean deleteStubsAfterTest; + + /** + * Map of properties that can be passed to custom {@link org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder} + */ + @Parameter(property = "contractsProperties") + private Map contractsProperties = new HashMap<>(); + + public void execute() { + if (this.skip || this.taskSkip) { + getLog().info( + "Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip=" + + this.skip + ", spring.cloud.contract.verifier.publish-stubs-to-scm.skip=" + this.taskSkip); + return; + } + if (StringUtils.isEmpty(this.contractsRepositoryUrl) || + !ScmStubDownloaderBuilder.isProtocolAccepted(this.contractsRepositoryUrl)) { + getLog().info("Skipping pushing stubs to scm since your [contractsRepositoryUrl] property doesn't match any of the accepted protocols"); + return; + } + String projectName = this.project.getGroupId() + ":" + this.project.getArtifactId() + ":" + this.project.getVersion(); + getLog().info("Pushing Stubs to SCM for project [" + projectName + "]"); + new ContractProjectUpdater(buildOptions()).updateContractProject(projectName, this.outputDirectory.toPath()); + } + + StubRunnerOptions buildOptions() { + StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder() + .withOptions(StubRunnerOptions.fromSystemProps()) + .withStubRepositoryRoot(this.contractsRepositoryUrl) + .withStubsMode(this.contractsMode) + .withUsername(this.contractsRepositoryUsername) + .withPassword(this.contractsRepositoryPassword) + .withDeleteStubsAfterTest(this.deleteStubsAfterTest) + .withProperties(this.contractsProperties); + return builder.build(); + } + +} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/stubrunner/AetherStubDownloaderFactory.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/stubrunner/AetherStubDownloaderFactory.java index d1b96f7f69..bb44d1c2ba 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/stubrunner/AetherStubDownloaderFactory.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/stubrunner/AetherStubDownloaderFactory.java @@ -28,6 +28,8 @@ import org.springframework.cloud.contract.stubrunner.AetherStubDownloader; import org.springframework.cloud.contract.stubrunner.StubDownloader; import org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder; import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; @Named @Singleton @@ -51,6 +53,11 @@ public class AetherStubDownloaderFactory { return new AetherStubDownloader(AetherStubDownloaderFactory.this.repoSystem, AetherStubDownloaderFactory.this.project.getRemoteProjectRepositories(), repoSession); } + + @Override + public Resource resolve(String location, ResourceLoader resourceLoader) { + return null; + } }; } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml index 21291d6d09..bd46ddf1c2 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml @@ -7,6 +7,7 @@ run generateTests generateStubs + pushStubsToScm diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java index d8adfc1ea3..54beac401b 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java @@ -24,6 +24,7 @@ import org.apache.commons.io.FileUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.junit.Rule; import org.junit.Test; +import org.springframework.boot.test.rule.OutputCapture; import org.springframework.util.StringUtils; import static io.takari.maven.testing.TestMavenRuntime.newParameter; @@ -33,6 +34,9 @@ import static org.assertj.core.api.BDDAssertions.then; public class PluginUnitTest { + @Rule + public OutputCapture capture = new OutputCapture(); + @Rule public final TestResources resources = new TestResources(); @@ -292,4 +296,13 @@ public class PluginUnitTest { .countOccurrencesOf(testContents, "\t\tMockMvcRequestSpecification"); then(countOccurrencesOf).isEqualTo(4); } + + @Test + public void shouldRunPushStubsToScm() throws Exception { + File basedir = this.resources.getBasedir("git-basic-remote-contracts"); + + this.maven.executeMojo(basedir, "pushStubsToScm", defaultPackageForTests()); + + then(this.capture.toString()).contains("Skipping pushing stubs to scm since your"); + } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/git-basic-remote-contracts/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/git-basic-remote-contracts/pom.xml new file mode 100644 index 0000000000..8c189947fd --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/git-basic-remote-contracts/pom.xml @@ -0,0 +1,38 @@ + + + + 4.0.0 + + com.example + server + 0.1.BUILD-SNAPSHOT + + + + + org.springframework.cloud + spring-cloud-contract-maven-plugin + + REMOTE + http://foo.bar + + + + + + \ No newline at end of file diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy index 85beb832f4..494695e7aa 100755 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy @@ -88,8 +88,8 @@ class ContractFileScanner { */ private void appendRecursively(File baseDir, ListMultimap result) { List converters = SpringFactoriesLoader.loadFactories(ContractConverter, null) - if (log.isDebugEnabled()) { - log.debug("Found the following contract converters ${converters}") + if (log.isTraceEnabled()) { + log.trace("Found the following contract converters ${converters}") } File[] files = baseDir.listFiles() if (!files) { diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy index 08399a1819..75a875c9d5 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderWithMatchersSpec.groovy @@ -180,8 +180,8 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString()) } catch (ClassFormatError classFormatError) { String output = outputCapture.toString() - output.contains('error: cannot find symbol') - output.contains('assertThatValueIsANumber(parsedJson.read("$.duck"));') + assert output.contains('error: cannot find symbol') + assert output.contains('assertThatValueIsANumber(parsedJson.read("$.duck"));') } where: methodBuilderName | methodBuilder | rootElement