From a0bc2eb1c4218cf960b1ff895aa86e5c9804bf5c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 23 Aug 2018 13:30:56 +0200 Subject: [PATCH] Deprecating skipSnapshotCheck and providing fake m2 for Aether without this change Aether, when having both local and remote JARs, always picks the local one, even though we don't want it to. There seems to be no way to change it via an API. We had a check in Spring Cloud Contract to throw an exception when we wanted a remote JAR but the local one was fetched. You could have changed it by providing a system property or a plugin property called `skipSnapshotCheck` or `contractsSkipSnapshotCheck` with this change we're deprecating that flag since we're moving this logic to the internals of how we integrate with Aether. If the problem was that there was both the local and the remote JAR, what we could do is get rid of the local JAR. Obviously we don't want to remove it so what we're doing is when someone provides the REMOTE stub mode, we're creating a temporary directory and we're temporarily pointing Aether to that directory as our local m2. Since it's empty, Aether will not assume that we have any stubs stored locally. Thus, we will never have conflicts of remote vs local jars. fixes gh-643 additional links: - http://maven.40175.n5.nabble.com/Resolving-an-Artifact-from-Remote-Repository-instead-of-Local-td5875134.html - https://stackoverflow.com/questions/9123004/maven-is-it-possible-to-override-location-of-local-repository-via-the-use-of-co --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- docs/src/main/asciidoc/verifier_setup.adoc | 25 ---- .../contract/stubrunner/AetherFactories.java | 52 ++++++-- .../stubrunner/AetherStubDownloader.java | 41 ++---- .../stubrunner/StubRunnerOptions.java | 19 +-- .../stubrunner/StubRunnerOptionsBuilder.java | 13 +- .../stubrunner/junit/StubRunnerRule.java | 5 - .../junit/StubRunnerRuleOptions.java | 6 - .../spring/AutoConfigureStubRunner.java | 6 - .../spring/StubRunnerConfiguration.java | 1 - .../spring/StubRunnerProperties.java | 15 --- .../AetherStubDownloaderSpec.groovy | 120 +++--------------- .../StubRunnerOptionsBuilderSpec.groovy | 7 +- .../plugin/ContractVerifierExtension.groovy | 3 + .../plugin/GradleContractsDownloader.groovy | 1 - .../contract/maven/verifier/ConvertMojo.java | 5 +- .../maven/verifier/GenerateTestsMojo.java | 5 +- .../verifier/MavenContractsDownloader.java | 7 +- 18 files changed, 92 insertions(+), 241 deletions(-) diff --git a/docker/spring-cloud-contract-docker/project/gradle/wrapper/gradle-wrapper.properties b/docker/spring-cloud-contract-docker/project/gradle/wrapper/gradle-wrapper.properties index 949819d28a..2c2bbe5f9a 100644 --- a/docker/spring-cloud-contract-docker/project/gradle/wrapper/gradle-wrapper.properties +++ b/docker/spring-cloud-contract-docker/project/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip diff --git a/docs/src/main/asciidoc/verifier_setup.adoc b/docs/src/main/asciidoc/verifier_setup.adoc index ec5394fcad..d755b539ee 100644 --- a/docs/src/main/asciidoc/verifier_setup.adoc +++ b/docs/src/main/asciidoc/verifier_setup.adoc @@ -261,8 +261,6 @@ closure to set it up. separated. Otherwise, it scans contracts under the provided directory. * *contractsMode*: Specifies the mode of downloading contracts (whether the JAR is available offline, remotely etc.) -* *contractsSnapshotCheckSkip*: If set to `true` will not assert whether the -downloaded stubs / contract JAR was downloaded from a remote location or a local one(only applicable to Maven repos, not Git or Pact). * *deleteStubsAfterTest*: If set to `false` will not remove any downloaded contracts from temporary directories @@ -610,8 +608,6 @@ the following options: * *contractsPath*: The path to the concrete contracts in the JAR with packaged contracts. Defaults to `groupid/artifactid` where `gropuid` is slash separated. * *contractsMode*: Picks the mode in which stubs will be found and registered -* *contractsSnapshotCheckSkip*: If `true` then will not assert whether a stub / contract -JAR was downloaded from local or remote location * *deleteStubsAfterTest*: If set to `false` will not remove any downloaded contracts from temporary directories * *contractsRepositoryUrl*: URL to a repo with the artifacts that have contracts. If it is not provided, @@ -945,27 +941,6 @@ For example, you might decide to have no dependencies at all. As a consumer, if you add the stub dependency to your classpath, you can explicitly exclude the unwanted dependencies. -=== CI Server setup - -When fetching stubs / contracts in a CI, shared environment, what might happen is that -both the producer and the consumer reuse the same local Maven repository. Due to this, -the framework, responsible for downloading a stub JAR from remote location, -can't decide which JAR should be picked, local or remote one. That caused -the `"The artifact was found in the local repository but you have explicitly -stated that it should be downloaded from a remote one"` exception -and failed the build. - -For such cases we're introducing the property and plugin setup mechanism: - -- via `stubrunner.snapshot-check-skip` system property -- via `STUBRUNNER_SNAPSHOT_CHECK_SKIP` environment variable - -if either of these values is set to `true`, then the stub downloader will not -verify the origin of the downloaded JAR. - -For the plugins you need to set the `contractsSnapshotCheckSkip` property -to `true`. - === Scenarios You can handle scenarios with Spring Cloud Contract Verifier. All you need to do is to 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 aa9245c334..39f5707026 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 @@ -17,7 +17,12 @@ package org.springframework.cloud.contract.stubrunner; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Random; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; @@ -41,10 +46,14 @@ import shaded.org.eclipse.aether.transport.http.HttpTransporterFactory; class AetherFactories { + private static final Log log = LogFactory.getLog(AetherFactories.class); + private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = "maven.repo.local"; private static final String MAVEN_USER_SETTINGS_LOCATION = "org.apache.maven.user-settings"; private static final String MAVEN_GLOBAL_SETTINGS_LOCATION = "org.apache.maven.global-settings"; + private static final Random RANDOM = new Random(); + public static RepositorySystem newRepositorySystem() { DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); @@ -60,14 +69,34 @@ class AetherFactories { session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS); } session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_WARN); - LocalRepository localRepo = new LocalRepository(localRepositoryDirectory()); + String localRepositoryDirectory = localRepositoryDirectory(workOffline); + if (log.isDebugEnabled()) { + log.debug("Local Repository Directory set to [" + localRepositoryDirectory + "]. Work offline: [" + workOffline + "]"); + } + LocalRepository localRepo = new LocalRepository(localRepositoryDirectory); session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); return session; } - private static String localRepositoryDirectory() { + protected static String localRepositoryDirectory(boolean workOffline) { String localRepoLocationFromSettings = settings().getLocalRepository(); - return readPropertyFromSystemProps(localRepoLocationFromSettings); + String currentLocalRepo = readPropertyFromSystemProps(localRepoLocationFromSettings); + if (workOffline) { + return currentLocalRepo; + } + return temporaryDirectory(); + } + + private static String temporaryDirectory() { + try { + return Files.createTempDirectory("aether-local").toString(); + } + catch (IOException e) { + if (log.isDebugEnabled()) { + log.debug("Failed to create a new temporary directory, will generate a new one under temp dir"); + } + return System.getProperty("java.io.tmpdir") + File.separator + RANDOM.nextInt(); + } } private static String readPropertyFromSystemProps( @@ -87,16 +116,19 @@ class AetherFactories { return System.getenv(prop); } + private static File userSettings() { + String user = fromSystemPropOrEnv(MAVEN_USER_SETTINGS_LOCATION); + if (user == null) { + return new File(new File(System.getProperty("user.home")).getAbsoluteFile(), + File.separator + ".m2" + File.separator + "settings.xml"); + } + return new File(user); + } + private static Settings settings() { SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance(); SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); - String user = fromSystemPropOrEnv(MAVEN_USER_SETTINGS_LOCATION); - if (user == null) { - request.setUserSettingsFile(new File(new File(System.getProperty("user.home")).getAbsoluteFile(), - File.separator + ".m2" + File.separator + "settings.xml")); - } else { - request.setUserSettingsFile(new File(user)); - } + request.setUserSettingsFile(userSettings()); String global = fromSystemPropOrEnv(MAVEN_GLOBAL_SETTINGS_LOCATION); if (global != null) { request.setGlobalSettingsFile(new File(global)); 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 2206af6d9b..fef67e6742 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 @@ -57,7 +57,6 @@ public class AetherStubDownloader implements StubDownloader { private static final String ARTIFACT_EXTENSION = "jar"; 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"; // Preloading class for the shutdown hook not to throw ClassNotFound private static final Class CLAZZ = TemporaryFileStorage.class; @@ -65,7 +64,6 @@ public class AetherStubDownloader implements StubDownloader { private final RepositorySystem repositorySystem; private final RepositorySystemSession session; private final boolean workOffline; - private final boolean snapshotCheckSkip; private final boolean deleteStubsAfterTest; public AetherStubDownloader(StubRunnerOptions stubRunnerOptions) { @@ -92,8 +90,6 @@ public class AetherStubDownloader implements StubDownloader { this.repositorySystem = newRepositorySystem(); this.workOffline = stubRunnerOptions.stubsMode == StubRunnerProperties.StubsMode.LOCAL; this.session = newSession(this.repositorySystem, this.workOffline); - this.snapshotCheckSkip = - stubRunnerOptions.isSnapshotCheckSkip() || skipSnapshotCheck(); registerShutdownHook(); } @@ -118,7 +114,6 @@ public class AetherStubDownloader implements StubDownloader { log.error("Remote repositories for stubs are not specified and work offline flag wasn't passed"); } this.workOffline = false; - this.snapshotCheckSkip = skipSnapshotCheck(); registerShutdownHook(); } @@ -150,28 +145,24 @@ public class AetherStubDownloader implements StubDownloader { private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier) { - log.info("Resolved version is [" + resolvedVersion + "]"); - if (StringUtils.isEmpty(resolvedVersion)) { - log.warn("Stub for group [" + stubsGroup + "] module [" + stubsModule - + "] and classifier [" + classifier + "] not found in " - + this.remoteRepos); - return null; - } - Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, - ARTIFACT_EXTENSION, resolvedVersion); - ArtifactRequest request = new ArtifactRequest(artifact, this.remoteRepos, null); - if (log.isDebugEnabled()) { - log.debug("Resolving artifact [" + artifact - + "] using remote repositories " + this.remoteRepos); - } try { + log.info("Resolved version is [" + resolvedVersion + "]"); + if (StringUtils.isEmpty(resolvedVersion)) { + log.warn("Stub for group [" + stubsGroup + "] module [" + stubsModule + + "] and classifier [" + classifier + "] not found in " + + this.remoteRepos); + return null; + } + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, + ARTIFACT_EXTENSION, resolvedVersion); + ArtifactRequest request = new ArtifactRequest(artifact, this.remoteRepos, null); + if (log.isDebugEnabled()) { + log.debug("Resolving artifact [" + artifact + + "] using remote repositories " + this.remoteRepos); + } ArtifactResult result = this.repositorySystem.resolveArtifact(this.session, request); log.info("Resolved artifact [" + artifact + "] to " + result.getArtifact().getFile()); - if (!this.snapshotCheckSkip && resolvedFromLocalRepo(result) && shouldDownloadFromRemote()) { - throw new IllegalStateException("The artifact was found in the local repository " - + "but you have explicitly stated that it should be downloaded from a remote one"); - } File temporaryFile = unpackStubJarToATemporaryFolder( result.getArtifact().getFile().toURI()); log.info("Unpacked file to [" + temporaryFile + "]"); @@ -189,10 +180,6 @@ public class AetherStubDownloader implements StubDownloader { } } - private boolean skipSnapshotCheck() { - return StubRunnerPropertyUtils.isPropertySet(STUBRUNNER_SNAPSHOT_CHECK_SKIP_SYSTEM_PROP); - } - private boolean resolvedFromLocalRepo(ArtifactResult result) { return result.getRepository() instanceof LocalRepository; } 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 eb8511445f..b7569140f5 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 @@ -101,12 +101,6 @@ public class StubRunnerOptions { final StubRunnerProperties.StubsMode stubsMode; - /** - * If set to {@code true} will not assert whether the downloaded stubs / contract - * JAR was downloaded from a remote location or a local one(only applicable to Maven repos, not Git or Pact) - */ - private boolean snapshotCheckSkip; - /** * If set to {@code false} will NOT delete stubs from a temporary * folder after running tests @@ -118,13 +112,12 @@ public class StubRunnerOptions { */ private Map properties = new HashMap<>(); - StubRunnerOptions(Integer minPortValue, Integer maxPortValue, 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 stubsPerConsumer, String consumerName, String mappingsOutputFolder, boolean deleteStubsAfterTest, Map properties) { this.minPortValue = minPortValue; this.maxPortValue = maxPortValue; @@ -139,7 +132,6 @@ public class StubRunnerOptions { this.stubsPerConsumer = stubsPerConsumer; this.consumerName = consumerName; this.mappingsOutputFolder = mappingsOutputFolder; - this.snapshotCheckSkip = snapshotCheckSkip; this.deleteStubsAfterTest = deleteStubsAfterTest; this.properties = properties; } @@ -167,7 +159,6 @@ public class StubRunnerOptions { .withStubPerConsumer(Boolean.parseBoolean(System.getProperty("stubrunner.stubs-per-consumer", "false"))) .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"))) .withProperties(stubRunnerProps()); String proxyHost = System.getProperty("stubrunner.proxy.host"); @@ -277,14 +268,6 @@ public class StubRunnerOptions { this.mappingsOutputFolder = mappingsOutputFolder; } - public boolean isSnapshotCheckSkip() { - return this.snapshotCheckSkip; - } - - public void setSnapshotCheckSkip(boolean snapshotCheckSkip) { - this.snapshotCheckSkip = snapshotCheckSkip; - } - public boolean isDeleteStubsAfterTest() { return this.deleteStubsAfterTest; } 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 8c03973b01..5d60221106 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 @@ -48,7 +48,6 @@ public class StubRunnerOptionsBuilder { private String consumerName; private String mappingsOutputFolder; private StubRunnerProperties.StubsMode stubsMode; - private boolean snapshotCheckSkip = false; private boolean deleteStubsAfterTest = true; private Map properties = new HashMap<>(); @@ -133,10 +132,9 @@ public class StubRunnerOptionsBuilder { this.consumerName = options.getConsumerName(); this.mappingsOutputFolder = options.getMappingsOutputFolder(); this.stubConfigurations = options.dependencies != null ? - options.dependencies : new ArrayList(); + options.dependencies : new ArrayList<>(); this.stubIdsToPortMapping = options.stubIdsToPortMapping != null ? - options.stubIdsToPortMapping : new LinkedHashMap(); - this.snapshotCheckSkip = options.isSnapshotCheckSkip(); + options.stubIdsToPortMapping : new LinkedHashMap<>(); this.deleteStubsAfterTest = options.isDeleteStubsAfterTest(); this.properties = options.getProperties(); return this; @@ -147,11 +145,6 @@ public class StubRunnerOptionsBuilder { return this; } - public StubRunnerOptionsBuilder withSnapshotCheckSkip(boolean snapshotCheckSkip) { - this.snapshotCheckSkip = snapshotCheckSkip; - return this; - } - public StubRunnerOptionsBuilder withDeleteStubsAfterTest(boolean deleteStubsAfterTest) { this.deleteStubsAfterTest = deleteStubsAfterTest; return this; @@ -166,7 +159,7 @@ public class StubRunnerOptionsBuilder { 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.properties); + this.mappingsOutputFolder, this.deleteStubsAfterTest, this.properties); } private Collection buildDependencies() { 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 eb62e0bcde..6e440b3537 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 @@ -154,11 +154,6 @@ public class StubRunnerRule implements TestRule, StubFinder, StubRunnerRuleOptio return this.delegate; } - @Override public StubRunnerRule withSnapshotCheckSkip(boolean snapshotCheckSkip) { - builder().withSnapshotCheckSkip(snapshotCheckSkip); - return this.delegate; - } - @Override public StubRunnerRule withDeleteStubsAfterTest( boolean deleteStubsAfterTest) { builder().withDeleteStubsAfterTest(deleteStubsAfterTest); 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 90bc1fecc7..4981ca334d 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 @@ -95,12 +95,6 @@ interface StubRunnerRuleOptions { */ StubRunnerRule withMappingsOutputFolder(String mappingsOutputFolder); - /** - * If set to {@code true} will not assert whether the downloaded stubs / contract - * JAR was downloaded from a remote location or a local one(only applicable to Maven repos, not Git or Pact) - */ - StubRunnerRule withSnapshotCheckSkip(boolean snapshotCheckSkip); - /** * If set to {@code false} will NOT delete stubs from a temporary * folder after running tests diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java index 6ea080971e..c5aba14dd0 100644 --- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java +++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java @@ -109,12 +109,6 @@ public @interface AutoConfigureStubRunner { */ StubRunnerProperties.StubsMode stubsMode() default StubRunnerProperties.StubsMode.CLASSPATH; - /** - * If set to {@code true} will not assert whether the downloaded stubs / contract - * JAR was downloaded from a remote location or a local one(only applicable to Maven repos, not Git or Pact) - */ - boolean snapshotCheckSkip() default false; - /** * Properties in form {@literal key=value} * @return the properties to add 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 0fe7249658..af6db728e1 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 @@ -94,7 +94,6 @@ public class StubRunnerConfiguration { .withStubPerConsumer(this.props.isStubsPerConsumer()) .withConsumerName(consumerName()) .withMappingsOutputFolder(this.props.getMappingsOutputFolder()) - .withSnapshotCheckSkip(this.props.isSnapshotCheckSkip()) .withDeleteStubsAfterTest(this.props.isDeleteStubsAfterTest()) .withProperties(this.props.getProperties()); } 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 9b6fcc6146..926ad8486a 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 @@ -99,12 +99,6 @@ public class StubRunnerProperties { */ private StubsMode stubsMode; - /** - * If set to {@code true} will not assert whether the downloaded stubs / contract - * JAR was downloaded from a remote location or a local one(only applicable to Maven repos, not Git or Pact) - */ - private boolean snapshotCheckSkip; - /** * If set to {@code false} will NOT delete stubs from a temporary * folder after running tests @@ -241,14 +235,6 @@ public class StubRunnerProperties { this.stubsMode = stubsMode; } - public boolean isSnapshotCheckSkip() { - return this.snapshotCheckSkip; - } - - public void setSnapshotCheckSkip(boolean snapshotCheckSkip) { - this.snapshotCheckSkip = snapshotCheckSkip; - } - public boolean isDeleteStubsAfterTest() { return this.deleteStubsAfterTest; } @@ -278,7 +264,6 @@ public class StubRunnerProperties { + ", ids=" + Arrays.toString(this.ids) + ", classifier='" + this.classifier + '\'' + ", 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/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 f98d130ac9..ccd7e8707d 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,6 +3,8 @@ package org.springframework.cloud.contract.stubrunner import io.specto.hoverfly.junit.HoverflyRule import org.eclipse.aether.RepositorySystemSession import org.junit.Rule +import org.junit.rules.TemporaryFolder + import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties import org.springframework.util.ResourceUtils import spock.lang.Specification @@ -13,7 +15,10 @@ class AetherStubDownloaderSpec extends Specification { @Rule HoverflyRule hoverflyRule = HoverflyRule.inSimulationMode("simulation.json") - def 'Should throw an exception when artifact not found'() { + @Rule + TemporaryFolder folder = new TemporaryFolder() + + def 'should throw an exception when artifact not found in local m2'() { given: StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.LOCAL) @@ -22,126 +27,33 @@ class AetherStubDownloaderSpec extends Specification { AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) when: - def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("non.existing.group", "missing-artifact-id", "1.0-SNAPSHOT")) + aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("non.existing.group", "missing-artifact-id", "1.0-SNAPSHOT")) then: IllegalStateException e = thrown(IllegalStateException) e.message.contains("Exception occurred while trying to download a stub for group") } - def 'Should throw an exception when a jar is in local m2 and not in remote repo'() { + def 'should throw an exception when local m2 gets replaced with a temp dir and a jar is not found in remote'() { given: StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local") + .withStubRepositoryRoot("file://" + folder.newFolder().absolutePath) .build() - - AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) - - when: - def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("org.springframework.cloud", "spring-cloud-contract-spec", "+", "")) - - then: - IllegalStateException e = thrown(IllegalStateException) - e.message.contains("The artifact was found in the local repository but you have explicitly stated that it should be downloaded from a remote one") - } - - @RestoreSystemProperties - def 'Should not throw an exception when a jar is in local m2 and not in remote repo and system property disabled snapshot check'() { - given: - StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() - .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local") - .build() - System.properties.setProperty("stubrunner.snapshot-check-skip", "true") + and: + String localRepo = AetherFactories.localRepositoryDirectory(true) + new File(localRepo, "org/springframework/cloud/spring-cloud-contract-spec" + .replaceAll("/", File.separator)).list().size() > 0 and: AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) when: - def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("org.springframework.cloud", "spring-cloud-contract-spec", "+", "")) + aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("org.springframework.cloud", "spring-cloud-contract-spec", "+", "")) then: - jar != null - } - - @RestoreSystemProperties - def 'Should throw an exception when a jar is in local m2 and not in remote repo and system property disabled takes precedence over env'() { - given: - StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() - .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local") - .build() - System.properties.setProperty("stubrunner.snapshot-check-skip", "false") - - and: - StubRunnerPropertyUtils.FETCHER = new PropertyFetcher() { - @Override - 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: - IllegalStateException e = thrown(IllegalStateException) - e.message.contains("The artifact was found in the local repository but you have explicitly stated that it should be downloaded from a remote one") - } - - def 'Should not throw an exception when a jar is in local m2 and not in remote repo and env property disabled snapshot check'() { - given: - StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() - .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local") - .build() - - and: - StubRunnerPropertyUtils.FETCHER = new PropertyFetcher() { - @Override - 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'() { - given: - StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() - .withStubsMode(StubRunnerProperties.StubsMode.REMOTE) - .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local") - .withSnapshotCheckSkip(true) - .build() - - AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions) - - when: - def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("org.springframework.cloud", "spring-cloud-contract-spec", "+", "")) - - then: - jar != null + IllegalArgumentException e = thrown(IllegalArgumentException) + e.message.contains("Could not find metadata org.springframework.cloud:spring-cloud-contract-spec/maven-metadata.xml in remote0") } @RestoreSystemProperties 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 63493ca351..bc5f79f859 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 @@ -231,7 +231,7 @@ class StubRunnerOptionsBuilderSpec extends Specification { given: 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, [foo: "bar"])) + new StubRunnerOptions.StubRunnerProxyOptions("host", 4), true, "consumer", "folder", false, [foo: "bar"])) builder.withStubs("foo:bar:baz") when: StubRunnerOptions options = builder.build() @@ -250,7 +250,6 @@ class StubRunnerOptionsBuilderSpec extends Specification { options.stubsPerConsumer == true options.consumerName == "consumer" options.mappingsOutputFolder == "folder" - options.snapshotCheckSkip == true options.deleteStubsAfterTest == false options.properties == [foo: "bar"] } @@ -260,7 +259,7 @@ class StubRunnerOptionsBuilderSpec extends Specification { 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", false, [:])) builder.withStubs("foo:bar:baz") when: String options = builder.build().toString() @@ -287,7 +286,6 @@ class StubRunnerOptionsBuilderSpec extends Specification { System.setProperty("stubrunner.proxy.host", "host") 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") @@ -307,7 +305,6 @@ class StubRunnerOptionsBuilderSpec extends Specification { options.stubsPerConsumer == true 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-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 5cabf8516e..3554305263 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 @@ -175,7 +175,10 @@ class ContractVerifierExtension { /** * If set to {@code true} will not assert whether the downloaded stubs / contract * JAR was downloaded from a remote location or a local one(only applicable to Maven repos, not Git or Pact) + * + * @deprecated - with 2.1.0 this option is redundant */ + @Deprecated boolean contractsSnapshotCheckSkip = false /** 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 527f5ece93..29c3efc7a9 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 @@ -86,7 +86,6 @@ class GradleContractsDownloader { .withStubsMode(extension.contractsMode) .withUsername(extension.contractRepository.username) .withPassword(extension.contractRepository.password) - .withSnapshotCheckSkip(extension.contractsSnapshotCheckSkip) .withDeleteStubsAfterTest(extension.deleteStubsAfterTest) .withProperties(extension.contractsProperties) if (extension.contractRepository.proxyPort) { 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 639953ba16..1328801a79 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 @@ -145,8 +145,11 @@ public class ConvertMojo extends AbstractMojo { /** * If {@code true} then will not assert whether a stub / contract * JAR was downloaded from local or remote location + * + * @deprecated - with 2.1.0 this option is redundant */ @Parameter(property = "contractsSnapshotCheckSkip", defaultValue = "false") + @Deprecated private boolean contractsSnapshotCheckSkip; @@ -230,7 +233,7 @@ public class ConvertMojo extends AbstractMojo { this.contractsPath, this.contractsRepositoryUrl, this.contractsMode, getLog(), this.contractsRepositoryUsername, this.contractsRepositoryPassword, this.contractsRepositoryProxyHost, this.contractsRepositoryProxyPort, - this.contractsSnapshotCheckSkip, this.deleteStubsAfterTest, this.contractsProperties) + this.deleteStubsAfterTest, this.contractsProperties) .downloadAndUnpackContractsIfRequired(config, this.contractsDirectory); } 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 306bb604aa..99cd483dbc 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 @@ -207,8 +207,11 @@ public class GenerateTestsMojo extends AbstractMojo { /** * If {@code true} then will not assert whether a stub / contract * JAR was downloaded from local or remote location + * + * @deprecated - with 2.1.0 this option is redundant */ @Parameter(property = "contractsSnapshotCheckSkip", defaultValue = "false") + @Deprecated private boolean contractsSnapshotCheckSkip; /** @@ -246,7 +249,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, this.contractsProperties).downloadAndUnpackContractsIfRequired(config, this.contractsDirectory); + 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 338ba8b5ab..bd1027495a 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 @@ -54,7 +54,6 @@ class MavenContractsDownloader { private final String repositoryPassword; private final String repositoryProxyHost; private final Integer repositoryProxyPort; - private final boolean contractsSnapshotCheckSkip; private final boolean deleteStubsAfterTest; private final Map contractsProperties; @@ -62,8 +61,8 @@ class MavenContractsDownloader { String contractsPath, String contractsRepositoryUrl, StubRunnerProperties.StubsMode stubsMode, Log log, String repositoryUsername, String repositoryPassword, String repositoryProxyHost, - Integer repositoryProxyPort, boolean contractsSnapshotCheckSkip, - boolean deleteStubsAfterTest, Map contractsProperties) { + Integer repositoryProxyPort, boolean deleteStubsAfterTest, + Map contractsProperties) { this.project = project; this.contractDependency = contractDependency; this.contractsPath = contractsPath; @@ -75,7 +74,6 @@ class MavenContractsDownloader { this.repositoryProxyHost = repositoryProxyHost; this.repositoryProxyPort = repositoryProxyPort; this.stubDownloaderBuilderProvider = new StubDownloaderBuilderProvider(); - this.contractsSnapshotCheckSkip = contractsSnapshotCheckSkip; this.deleteStubsAfterTest = deleteStubsAfterTest; this.contractsProperties = contractsProperties; } @@ -122,7 +120,6 @@ class MavenContractsDownloader { .withStubsMode(this.stubsMode) .withUsername(this.repositoryUsername) .withPassword(this.repositoryPassword) - .withSnapshotCheckSkip(this.contractsSnapshotCheckSkip) .withDeleteStubsAfterTest(this.deleteStubsAfterTest) .withProperties(this.contractsProperties); if (StringUtils.hasText(this.contractsRepositoryUrl)) {