boot-based ModuleLauncher
deprecates default constructor for ModuleLauncher until dependencies are refactored
This commit is contained in:
committed by
Mark Fisher
parent
95a34f6ab0
commit
31daf48cc2
@@ -16,7 +16,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<start-class>org.springframework.cloud.stream.module.launcher.ModuleLauncher</start-class>
|
||||
<start-class>org.springframework.cloud.stream.module.launcher.ModuleLauncherApplication</start-class>
|
||||
<aether.version>1.0.2.v20150114</aether.version>
|
||||
<maven.version>3.1.0</maven.version>
|
||||
<wiremock.version>1.57</wiremock.version>
|
||||
@@ -27,6 +27,10 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-loader</artifactId>
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -34,13 +33,8 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Bootstrap for launching one or more modules. The module coordinates must be provided via the "modules" system
|
||||
* property or "MODULES" environment variable as a comma-delimited list. The format of each module must conform to the
|
||||
* <a href="http://www.eclipse.org/aether">Aether</a> convention:
|
||||
* <code><groupId>:<artifactId>[:<extension>[:<classifier>]]:<version></code>
|
||||
* <p>
|
||||
* To pass args to a module, prefix with the module name and a dot. The arg name will be de-qualified and passed along.
|
||||
* For example: <code>--foo.bar=123</code> becomes <code>--bar=123</code> and is only passed to the 'foo' module.
|
||||
* A component that launches one or more modules, delegating their resolution to an
|
||||
* underlying {@link ModuleResolver}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Ilayaperumal Gopinathan
|
||||
@@ -48,12 +42,6 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class ModuleLauncher {
|
||||
|
||||
// TODO ensure that this properly supports Windows too
|
||||
private static final String DEFAULT_LOCAL_REPO =
|
||||
System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository";
|
||||
|
||||
private static final String DEFAULT_REMOTE_REPO = "http://repo.spring.io/spring-cloud-stream-modules";
|
||||
|
||||
private static final String DEFAULT_EXTENSION = "jar";
|
||||
|
||||
private static final String DEFAULT_CLASSIFIER = "exec";
|
||||
@@ -63,15 +51,32 @@ public class ModuleLauncher {
|
||||
|
||||
private final ModuleResolver moduleResolver;
|
||||
|
||||
@Deprecated
|
||||
public ModuleLauncher() {
|
||||
this(determineLocalRepositoryLocation(),
|
||||
Collections.singletonMap("spring-cloud-stream-modules", determineRemoteRepositoryLocation()));
|
||||
this(new AetherModuleResolver(new File(ModuleLauncherConfiguration.DEFAULT_LOCAL_REPO),
|
||||
Collections.singletonMap("spring-cloud-stream-modules", ModuleLauncherConfiguration.DEFAULT_REMOTE_REPO)));
|
||||
}
|
||||
|
||||
public ModuleLauncher(String localRepository, Map<String, String> remoteRepositories) {
|
||||
this.moduleResolver = new AetherModuleResolver(new File(localRepository), remoteRepositories);
|
||||
/**
|
||||
* Creates a module launcher using the provided module resolver
|
||||
* @param moduleResolver the module resolver instance to use
|
||||
*/
|
||||
public ModuleLauncher(ModuleResolver moduleResolver) {
|
||||
this.moduleResolver = moduleResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches one or more modules, with the corresponding arguments, if any.
|
||||
*
|
||||
* The format of each module must conform to the <a href="http://www.eclipse.org/aether">Aether</a> convention:
|
||||
* <code><groupId>:<artifactId>[:<extension>[:<classifier>]]:<version></code>
|
||||
*
|
||||
* To pass arguments to a module, prefix with the module name and a dot. The arg name will be de-qualified and passed along.
|
||||
* For example: <code>---Dorg.springframework.cloud.stream.module:time-source:1.0.0.BUILD-SNAPSHOT.bar=123</code> becomes <code>--bar=123</code> and is only passed to the 'org.springframework.cloud.stream.module:time-source:1.0.0.BUILD-SNAPSHOT' module.
|
||||
*
|
||||
* @param modules a list of modules
|
||||
* @param args a list of arguments, prefixed with the module name
|
||||
*/
|
||||
public void launch(String[] modules, String[] args) {
|
||||
for (String module : modules) {
|
||||
List<String> moduleArgs = new ArrayList<>();
|
||||
@@ -109,38 +114,4 @@ public class ModuleLauncher {
|
||||
return moduleResolver.resolve(groupId, artifactId, extension, classifier, version);
|
||||
}
|
||||
|
||||
private static String determineLocalRepositoryLocation() {
|
||||
String localRepository = System.getProperty("local.repository");
|
||||
if (localRepository == null) {
|
||||
localRepository = System.getenv("LOCAL_REPOSITORY");
|
||||
}
|
||||
if (localRepository == null) {
|
||||
localRepository = DEFAULT_LOCAL_REPO;
|
||||
}
|
||||
return localRepository;
|
||||
}
|
||||
|
||||
private static String determineRemoteRepositoryLocation() {
|
||||
String remoteRepository = System.getProperty("remote.repository");
|
||||
if (remoteRepository == null) {
|
||||
remoteRepository = System.getenv("REMOTE_REPOSITORY");
|
||||
}
|
||||
if (remoteRepository == null) {
|
||||
remoteRepository = DEFAULT_REMOTE_REPO;
|
||||
}
|
||||
return remoteRepository;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String modules = System.getProperty("modules");
|
||||
if (modules == null) {
|
||||
modules = System.getenv("MODULES");
|
||||
}
|
||||
if (modules == null) {
|
||||
System.err.println("Either the 'modules' system property or 'MODULES' environment variable is required.");
|
||||
System.exit(1);
|
||||
}
|
||||
ModuleLauncher launcher = new ModuleLauncher();
|
||||
launcher.launch(modules.split(","), args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2015 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.stream.module.launcher;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* Bootstrap for launching one or more modules, provided via the "modules" system property or "MODULES" environment variable as a comma-delimited list, with the arguments provided at
|
||||
* launch.
|
||||
*
|
||||
* @see ModuleLauncher#launch(String[], String[]) for module and argument structure and format
|
||||
*
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackageClasses = ModuleLauncherApplication.class)
|
||||
public class ModuleLauncherApplication {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ModuleLauncherApplication.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
SpringApplication.run(ModuleLauncherApplication.class, args);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Failed to launch module ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2015 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.stream.module.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.stream.module.resolver.AetherModuleResolver;
|
||||
import org.springframework.cloud.stream.module.resolver.ModuleResolver;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties
|
||||
public class ModuleLauncherConfiguration {
|
||||
|
||||
public static final String DEFAULT_LOCAL_REPO =
|
||||
System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository";
|
||||
|
||||
public static final String DEFAULT_REMOTE_REPO = "https://repo.spring.io/libs-snapshot";
|
||||
|
||||
private File localRepository = new File(DEFAULT_LOCAL_REPO);
|
||||
|
||||
private String remoteRepository = DEFAULT_REMOTE_REPO;
|
||||
|
||||
public void setLocalRepository(File localRepository) {
|
||||
this.localRepository = localRepository;
|
||||
}
|
||||
|
||||
public void setRemoteRepository(String remoteRepository) {
|
||||
this.remoteRepository = remoteRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the default Aether-based module resolver, unless overridden
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ModuleResolver.class)
|
||||
public ModuleResolver moduleResolver() {
|
||||
return new AetherModuleResolver(localRepository, Collections.singletonMap("remoteRepository", remoteRepository));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ModuleLauncher moduleLauncher(ModuleResolver moduleResolver) {
|
||||
return new ModuleLauncher(moduleResolver);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2015 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.stream.module.launcher;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties
|
||||
public class ModuleLauncherRunner implements ApplicationRunner, InitializingBean {
|
||||
|
||||
private final static Log log = LogFactory.getLog(ModuleLauncherRunner.class);
|
||||
|
||||
@Autowired
|
||||
private ModuleLauncher moduleLauncher;
|
||||
|
||||
private String modules;
|
||||
|
||||
public void setModules(String modules) {
|
||||
this.modules = modules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasText(modules, "A list of modules must be specified");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments applicationArguments) throws Exception {
|
||||
String[] launchedModules = modules.split(",");
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Launching: " + modules + " with arguments: "
|
||||
+ StringUtils.arrayToCommaDelimitedString(applicationArguments.getSourceArgs()));
|
||||
}
|
||||
moduleLauncher.launch(launchedModules, applicationArguments.getSourceArgs());
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
@@ -42,6 +44,7 @@ import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* An implementation of ModuleResolver using <a href="http://www.eclipse.org/aether/>aether</a> to resolve the module
|
||||
@@ -50,9 +53,12 @@ import org.springframework.util.CollectionUtils;
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class AetherModuleResolver implements ModuleResolver {
|
||||
|
||||
private static final Log log = LogFactory.getLog(AetherModuleResolver.class);
|
||||
|
||||
private static final String DEFAULT_CONTENT_TYPE = "default";
|
||||
|
||||
private final File localRepository;
|
||||
@@ -68,6 +74,14 @@ public class AetherModuleResolver implements ModuleResolver {
|
||||
* may be null or empty if the local repository is off line.
|
||||
*/
|
||||
public AetherModuleResolver(File localRepository, Map<String, String> remoteRepositories) {
|
||||
Assert.notNull(localRepository, "Local repository path cannot be null");
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Local repository: " + localRepository);
|
||||
if (!CollectionUtils.isEmpty(remoteRepositories)) {
|
||||
// just listing the values, ids are simply informative
|
||||
log.debug("Remote repositories: " + StringUtils.collectionToCommaDelimitedString(remoteRepositories.values()));
|
||||
}
|
||||
}
|
||||
if (!localRepository.exists()) {
|
||||
Assert.isTrue(localRepository.mkdirs(),
|
||||
"Unable to create directory for local repository: " + localRepository);
|
||||
|
||||
Reference in New Issue
Block a user