From c550ba2c4d0e301e1113686b63d63d26fdc88bbc Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 11 Apr 2016 19:15:54 +0200 Subject: [PATCH] allow using custom artifact downloader --- .../stubrunner/BatchStubRunnerFactory.groovy | 10 +- .../stubrunner/GrapeStubDownloader.groovy | 172 ++++++++++++++++++ .../accurest/stubrunner/StubDownloader.groovy | 171 +---------------- .../stubrunner/StubRunnerFactory.groovy | 11 +- 4 files changed, 188 insertions(+), 176 deletions(-) create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index 18652eb767..99b01dcfc0 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -13,14 +13,22 @@ class BatchStubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final Collection dependencies + private final StubDownloader stubDownloader BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies) { + this(stubRunnerOptions, dependencies, new GrapeStubDownloader()) + } + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, + Collection dependencies, + StubDownloader stubDownloader) { this.stubRunnerOptions = stubRunnerOptions this.dependencies = dependencies + this.stubDownloader = stubDownloader } BatchStubRunner buildBatchStubRunner() { - StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies) + StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies, stubDownloader) return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy new file mode 100644 index 0000000000..638cadef84 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy @@ -0,0 +1,172 @@ +package io.codearte.accurest.stubrunner + +import groovy.grape.Grape +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.util.StringUtils +import io.codearte.accurest.stubrunner.util.ZipCategory + +import static java.nio.file.Files.createTempDirectory + +/** + * Downloads stubs from an external repository and unpacks them locally + */ +@Slf4j +class GrapeStubDownloader implements StubDownloader { + + private static final String LATEST_MODULE = '*' + private static final String REPOSITORY_NAME = 'dependency-repository' + private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' + private static final String GRAPE_CONFIG = 'grape.config' + private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" + + /** + * Downloads stubs from an external repository and unpacks them locally. + * Depending on the switch either uses only local repository to check for + * stub presence. + * + * @param workOffline -flag that defines whether only local cache should be used + * @param stubRepositoryRoot - address of the repo from which deps should be grabbed + * @param stubsGroup - group name of the jar containing stubs + * @param stubsModule - artifact id with a classifier name of the jar containing stubs + * @return file where the stubs where unpacked + */ + File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String + stubsModule, String classifier) { + log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) + if (!stubJarUri) { + log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + return null + } + File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) + unzippedStubsDir.deleteOnExit() + Thread.addShutdownHook { + unzippedStubsDir.deleteDir() + } + return unzippedStubsDir + } + + private File unpackStubJarToATemporaryFolder(URI stubJarUri) { + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() + tmpDirWhereStubsWillBeUnzipped.deleteOnExit() + log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") + use(ZipCategory) { + new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) + } + return tmpDirWhereStubsWillBeUnzipped + } + + private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { + Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] + String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) + initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) + String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) + try { + System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) + log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") + if (StringUtils.hasText(stubRepositoryRoot)) { + return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) + } + log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") + return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) + } finally { + restoreOldGrapeConfigIfApplicable(oldGrapeConfig) + } + } + + private DependencyResolver buildResolver(boolean workOffline) { + return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() + } + + private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { + File accurestGrape = new File(accurestGrapePath) + if (!accurestGrape.exists()) { + accurestGrape.parentFile.mkdirs() + accurestGrape.createNewFile() + accurestGrape.text = GrapeStubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text + } + } + + private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { + if (oldGrapeConfig) { + System.setProperty(GRAPE_CONFIG, oldGrapeConfig) + } + } + + private String getDefaultAccurestGrapeConfigPath() { + return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" + } + + /** + * Dependency resolver providing {@link URI} to remote dependencies. + */ + @Slf4j + private class RemoteDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) + } catch (UnknownHostException e) { + failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) + } catch (Exception e) { + failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) + } + } + + private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { + Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) + log.info("Resolving dependency ${depToGrab} location in remote repository...") + return resolveDependencyLocation(depToGrab) + } + + private void failureHandler(String stubRepository, String reason, Exception cause) { + log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) + } + + } + + /** + * Dependency resolver that first checks if a dependency is available in the local repository. + * If not, it will try to provide {@link URI} from the remote repository. + * + * @see RemoteDependencyResolver + */ + @Slf4j + private class LocalOnlyDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + log.info("Resolving dependency ${depToGrab} location in local repository...") + return resolveDependencyLocation(depToGrab) + } catch (Exception e) { //Grape throws ordinary RuntimeException + log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") + log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") + return null + } + } + } + + /** + * Base class of dependency resolvers providing {@link URI} to required dependency. + */ + abstract class DependencyResolver { + + /** + * Returns {@link URI} to a dependency. + * + * @param stubRepositoryRoot root of the repository where the dependency should be found + * @param depToGrab parameters describing dependency to search for + * + * @return {@link URI} to dependency + */ + abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) + + URI resolveDependencyLocation(Map depToGrab) { + return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() + } + + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index 8c4525b8bf..006e639cfd 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -1,172 +1,7 @@ package io.codearte.accurest.stubrunner -import groovy.grape.Grape -import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.util.StringUtils -import io.codearte.accurest.stubrunner.util.ZipCategory +interface StubDownloader { -import static java.nio.file.Files.createTempDirectory - -/** - * Downloads stubs from an external repository and unpacks them locally - */ -@Slf4j -class StubDownloader { - - private static final String LATEST_MODULE = '*' - private static final String REPOSITORY_NAME = 'dependency-repository' - private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' - private static final String GRAPE_CONFIG = 'grape.config' - private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" - - /** - * Downloads stubs from an external repository and unpacks them locally. - * Depending on the switch either uses only local repository to check for - * stub presence. - * - * @param workOffline -flag that defines whether only local cache should be used - * @param stubRepositoryRoot - address of the repo from which deps should be grabbed - * @param stubsGroup - group name of the jar containing stubs - * @param stubsModule - artifact id with a classifier name of the jar containing stubs - * @return file where the stubs where unpacked - */ File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String - stubsModule, String classifier) { - log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) - if (!stubJarUri) { - log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - return null - } - File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) - unzippedStubsDir.deleteOnExit() - Thread.addShutdownHook { - unzippedStubsDir.deleteDir() - } - return unzippedStubsDir - } - - private File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() - tmpDirWhereStubsWillBeUnzipped.deleteOnExit() - log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") - use(ZipCategory) { - new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) - } - return tmpDirWhereStubsWillBeUnzipped - } - - private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] - String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) - initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) - String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) - try { - System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) - log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") - if (StringUtils.hasText(stubRepositoryRoot)) { - return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) - } - log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") - return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) - } finally { - restoreOldGrapeConfigIfApplicable(oldGrapeConfig) - } - } - - private DependencyResolver buildResolver(boolean workOffline) { - return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() - } - - private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { - File accurestGrape = new File(accurestGrapePath) - if (!accurestGrape.exists()) { - accurestGrape.parentFile.mkdirs() - accurestGrape.createNewFile() - accurestGrape.text = StubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text - } - } - - private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { - if (oldGrapeConfig) { - System.setProperty(GRAPE_CONFIG, oldGrapeConfig) - } - } - - private String getDefaultAccurestGrapeConfigPath() { - return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" - } - - /** - * Dependency resolver providing {@link URI} to remote dependencies. - */ - @Slf4j - private class RemoteDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) - } catch (UnknownHostException e) { - failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) - } catch (Exception e) { - failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) - } - } - - private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { - Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) - log.info("Resolving dependency ${depToGrab} location in remote repository...") - return resolveDependencyLocation(depToGrab) - } - - private void failureHandler(String stubRepository, String reason, Exception cause) { - log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) - } - - } - - /** - * Dependency resolver that first checks if a dependency is available in the local repository. - * If not, it will try to provide {@link URI} from the remote repository. - * - * @see RemoteDependencyResolver - */ - @Slf4j - private class LocalOnlyDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - log.info("Resolving dependency ${depToGrab} location in local repository...") - return resolveDependencyLocation(depToGrab) - } catch (Exception e) { //Grape throws ordinary RuntimeException - log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") - log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") - return null - } - } - } - - /** - * Base class of dependency resolvers providing {@link URI} to required dependency. - */ - abstract class DependencyResolver { - - /** - * Returns {@link URI} to a dependency. - * - * @param stubRepositoryRoot root of the repository where the dependency should be found - * @param depToGrab parameters describing dependency to search for - * - * @return {@link URI} to dependency - */ - abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) - - URI resolveDependencyLocation(Map depToGrab) { - return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() - } - - } - -} + stubsModule, String classifier) +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index 9a12b1c94d..d06ae1f190 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -3,25 +3,22 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j + /** * Factory of StubRunners. Basing on the options and passed collaborators * downloads the stubs and returns a list of corresponding stub runners. */ @Slf4j @CompileStatic -@PackageScope class StubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final Collection collaborators private final StubDownloader stubDownloader - StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators) { - this(stubRunnerOptions, collaborators, new StubDownloader()) - } - - protected StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators, - StubDownloader stubDownloader) { + StubRunnerFactory(StubRunnerOptions stubRunnerOptions, + Collection collaborators, + StubDownloader stubDownloader) { this.stubRunnerOptions = stubRunnerOptions this.collaborators = collaborators this.stubDownloader = stubDownloader