From 28abd6fdceaf18367e98eb1d327db0761a17a31e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 13 Jul 2017 18:59:20 +0200 Subject: [PATCH] Added username and password for Gradle contract downloading without this change you can't generate tests when working with Gradle that is to download contracts from an external repo fixes #333 --- docs/src/main/asciidoc/verifier/rest.adoc | 13 ++- .../spring/StubRunnerProperties.java | 1 + .../plugin/ContractVerifierExtension.groovy | 81 +++++++++++++++-- .../plugin/GradleContractsDownloader.groovy | 21 +++-- .../GradleContractsDownloaderSpec.groovy | 90 ++++++++++++++++++- 5 files changed, 185 insertions(+), 21 deletions(-) diff --git a/docs/src/main/asciidoc/verifier/rest.adoc b/docs/src/main/asciidoc/verifier/rest.adoc index 86db4cd477..9e1e0650d0 100644 --- a/docs/src/main/asciidoc/verifier/rest.adoc +++ b/docs/src/main/asciidoc/verifier/rest.adoc @@ -124,7 +124,9 @@ contracts { } contractsPath = '' contractsWorkOffline = false - cacheDownloadedContracts = true + contractRepository { + cacheDownloadedContracts(true) + } } tasks.create(type: Jar, name: 'verifierStubsJar', dependsOn: 'generateClientStubs') { @@ -440,11 +442,16 @@ To change default configuration just add `configuration` section to plugin defin If you want to download your contract definitions from a Maven repository you can use - - **contractsRepositoryUrl** - URL to a repo with the artifacts with contracts, if not provided should use the current Maven ones - **contractDependency** - the contract dependency that contains all the packaged contracts - **contractsPath** - path to concrete contracts in the JAR with packaged contracts. Defaults to `groupid/artifactid` where `gropuid` is slash separated. - **contractsWorkOffline** - if the dependencies should be downloaded or local Maven only should be reused - - **cacheDownloadedContracts** - if you want to reuse download JARs that contain contract definitions. + - **contractsRepositoryUrl** - *DEPRECATED PROPERTY - please use the `contractRepository` closure* - URL to a repo with the artifacts with contracts, if not provided should use the current Maven ones + - **contractRepository** - closure where you can define properties related to repository with contracts + * **username** - username to be used to connect to the repo + * **password** - username to be used to connect to the repo + * **proxyHost** - proxy host to be used to connect to the repo + * **proxyPort** - proxy port to be used to connect to the repo + * **cacheDownloadedContracts** - if you want to reuse download JARs that contain contract definitions. We cache only non-snapshot, explicitly provided versions (e.g. `+` or `1.0.0.BUILD-SNAPSHOT` won't get cached). By default this feature is turned on. 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 3850751a24..eee860a906 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 @@ -63,6 +63,7 @@ public class StubRunnerProperties { /** * The context path that the stub server will run under. */ + @Deprecated private String contextPath = ""; /** 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 6dff15a8ff..124b02ee44 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 @@ -90,9 +90,22 @@ class ContractVerifierExtension { * The URL from which a JAR containing the 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 + * + * @deprecated - use {@link ContractVerifierExtension#contractRepository(groovy.lang.Closure)} */ + @Deprecated String contractsRepositoryUrl + /* + * @deprecated - use {@link ContractVerifierExtension#contractRepository(groovy.lang.Closure)} + */ + @Deprecated + void setContractsRepositoryUrl(String contractsRepositoryUrl) { + this.contractRepository.repositoryUrl(contractsRepositoryUrl) + } + + ContractRepository contractRepository = new ContractRepository() + /** * Dependency that contains packaged contracts */ @@ -141,12 +154,6 @@ class ContractVerifierExtension { */ boolean excludeBuildFolders - /** - * If set to true then will cache the folder where non snapshot contract artifacts - * got downloaded. - */ - boolean cacheDownloadedContracts = true - void contractDependency(@DelegatesTo(Dependency) Closure closure) { closure.delegate = contractDependency closure.call() @@ -157,6 +164,11 @@ class ContractVerifierExtension { closure.call() } + void contractRepository(@DelegatesTo(ContractRepository) Closure closure) { + closure.delegate = contractRepository + closure.call() + } + @ToString static class Dependency { String groupId @@ -201,4 +213,61 @@ class ContractVerifierExtension { this.delegate.putAll(mapping) } } + + static class ContractRepository { + /** + * Repository URL + */ + String repositoryUrl + + /** + * Repository username + */ + String username + + /** + * Repository password + */ + String password + + /** + * Repository proxy port + */ + Integer proxyPort + + /** + * Repository proxy host + */ + String proxyHost + + /** + * If set to true then will cache the folder where non snapshot contract artifacts + * got downloaded. + */ + boolean cacheDownloadedContracts = true + + void repositoryUrl(String repositoryUrl) { + this.repositoryUrl = repositoryUrl + } + + void username(String username) { + this.username = username + } + + void password(String password) { + this.password = password + } + + void proxyPort(Integer proxyPort) { + this.proxyPort = proxyPort + } + + void proxyHost(String proxyHost) { + this.proxyHost = proxyHost + } + + void cacheDownloadedContracts(boolean cacheDownloadedContracts) { + this.cacheDownloadedContracts = cacheDownloadedContracts + } + } } 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 d3a11fd39b..198279e6b2 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 @@ -7,6 +7,7 @@ import org.gradle.api.logging.Logger import org.springframework.cloud.contract.stubrunner.AetherStubDownloader import org.springframework.cloud.contract.stubrunner.ContractDownloader import org.springframework.cloud.contract.stubrunner.StubConfiguration +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.util.StringUtils @@ -41,8 +42,8 @@ class GradleContractsDownloader { StubConfiguration configuration = stubConfiguration(extension.contractDependency) this.log.info("Got the following contract dependency to download [{}]", configuration) this.log.info("The contract dependency is a changing one [{}] and cache download switch is set to [{}]", - configuration.isVersionChanging(), extension.cacheDownloadedContracts) - if (!configuration.isVersionChanging() && extension.cacheDownloadedContracts) { + configuration.isVersionChanging(), extension.contractRepository.cacheDownloadedContracts) + if (!configuration.isVersionChanging() && extension.contractRepository.cacheDownloadedContracts) { this.log.info("Resolved a non changing version - will try to return the folder from a cache") File cachedFolder = downloadedContract.get(configuration) if (cachedFolder) { @@ -60,7 +61,7 @@ class GradleContractsDownloader { } private boolean shouldDownloadContracts(ContractVerifierExtension extension) { - return (StringUtils.hasText(extension.contractsRepositoryUrl) || extension.contractsWorkOffline) && + return (StringUtils.hasText(extension.contractRepository.repositoryUrl) || extension.contractsWorkOffline) && (StringUtils.hasText(extension.contractDependency.artifactId) || StringUtils.hasText(extension.contractDependency.stringNotation)) } @@ -71,11 +72,15 @@ class GradleContractsDownloader { } protected AetherStubDownloader stubDownloader(ContractVerifierExtension extension) { - return new AetherStubDownloader( - new StubRunnerOptionsBuilder() - .withStubRepositoryRoot(extension.contractsRepositoryUrl) - .withWorkOffline(extension.contractsWorkOffline) - .build()) + StubRunnerOptionsBuilder options = new StubRunnerOptionsBuilder() + .withStubRepositoryRoot(extension.contractRepository.repositoryUrl) + .withWorkOffline(extension.contractsWorkOffline) + .withUsername(extension.contractRepository.username) + .withPassword(extension.contractRepository.password) + if (extension.contractRepository.proxyPort) { + options = options.withProxy(extension.contractRepository.proxyHost, extension.contractRepository.proxyPort) + } + return new AetherStubDownloader(options.build()) } @PackageScope StubConfiguration stubConfiguration(ContractVerifierExtension.Dependency contractDependency) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderSpec.groovy index 0e32053dc7..b32c78c6dd 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderSpec.groovy @@ -76,7 +76,7 @@ class GradleContractsDownloaderSpec extends Specification { stubConfig.classifier == "stubs" } - def "should pick dependency from cache for a non snapshot contract dependency"() { + def "should pick dependency from cache for a non snapshot contract dependency with old property"() { given: ContractVerifierExtension ext = new ContractVerifierExtension() ext.with { @@ -103,6 +103,35 @@ class GradleContractsDownloaderSpec extends Specification { file == expectedFileFromCache } + def "should pick dependency from cache for a non snapshot contract dependency with new property"() { + given: + ContractVerifierExtension ext = new ContractVerifierExtension() + ext.with { + contractDependency { + groupId("com.example") + artifactId("foo") + version("1.0.0") + classifier("stubs") + } + contractRepository { + repositoryUrl("foo") + } + } + and: + final AetherStubDownloader downloader = Mock(AetherStubDownloader) + final ContractDownloader contractDownloader = Mock(ContractDownloader) + and: + def gradleDownloader = stubbedContractDownloader(downloader, contractDownloader) + and: + StubConfiguration expectedStubConfig = new StubConfiguration("com.example:foo:1.0.0:stubs") + File expectedFileFromCache = new File("foo/bar") + GradleContractsDownloader.downloadedContract.put(expectedStubConfig, expectedFileFromCache) + when: + File file = gradleDownloader.downloadAndUnpackContractsIfRequired(ext, new ContractVerifierConfigProperties()) + then: + file == expectedFileFromCache + } + def "should not pick dependency from cache for a non snapshot contract dependency with cache switch off"() { given: ContractVerifierExtension ext = new ContractVerifierExtension() @@ -113,8 +142,10 @@ class GradleContractsDownloaderSpec extends Specification { version("1.0.0") classifier("stubs") } - contractsRepositoryUrl = "foo" - cacheDownloadedContracts = false + contractRepository { + repositoryUrl("foo") + cacheDownloadedContracts(false) + } } and: final AetherStubDownloader downloader = Mock(AetherStubDownloader) @@ -144,7 +175,9 @@ class GradleContractsDownloaderSpec extends Specification { version("1.0.0.BUILD-SNAPSHOT") classifier("stubs") } - contractsRepositoryUrl = "foo" + contractRepository { + repositoryUrl("foo") + } } and: final AetherStubDownloader downloader = Mock(AetherStubDownloader) @@ -193,4 +226,53 @@ class GradleContractsDownloaderSpec extends Specification { file == new File("/foo/bar/baz") } + def "should pass contract dependency properties as a parameter to the builder"() { + given: + ContractVerifierExtension ext = new ContractVerifierExtension() + ext.with { + contractDependency { + groupId("com.example") + artifactId("foo") + version("1.0.0.BUILD-SNAPSHOT") + classifier("stubs") + } + contractRepository { + repositoryUrl("foo") + username("foo1") + password("foo2") + proxyHost("foo3") + proxyPort(12) + } + } + and: + final AetherStubDownloader downloader = Mock(AetherStubDownloader) + final ContractDownloader contractDownloader = Mock(ContractDownloader) + File expectedFileNotFromCache = new File("foo/bar/baz") + contractDownloader.unpackedDownloadedContracts(_) >> expectedFileNotFromCache + and: + def gradleDownloader = assertingContractDownloader(downloader, contractDownloader) + when: + gradleDownloader.downloadAndUnpackContractsIfRequired(ext, new ContractVerifierConfigProperties()) + then: + noExceptionThrown() + } + + private GradleContractsDownloader assertingContractDownloader(downloader, contractDownloader) { + new GradleContractsDownloader(project, logger) { + @Override + protected AetherStubDownloader stubDownloader(ContractVerifierExtension extension) { + assert extension.contractRepository.username == "foo1" + assert extension.contractRepository.password == "foo2" + assert extension.contractRepository.proxyHost == "foo3" + assert extension.contractRepository.proxyPort == 12 + return downloader + } + + @Override + protected ContractDownloader contractDownloader(ContractVerifierExtension extension, StubConfiguration configuration) { + return contractDownloader + } + } + } + }