blob: 139ad3552d456bf4363321c29deec56f4c579e1c [file] [log] [blame]
package org.apache.s4.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.s4.comm.DefaultCommModule;
import org.apache.s4.core.util.ParametersInjectionModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.io.Resources;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Bootstrap class for S4. It creates an S4 node.
*
*/
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
/**
* Starts an S4 server.
*
* @param args
*/
public static void main(String[] args) {
MainArgs mainArgs = new MainArgs();
JCommander jc = new JCommander(mainArgs);
try {
jc.parse(args);
} catch (Exception e) {
JCommander.getConsole().println("Cannot parse arguments: " + e.getMessage());
jc.usage();
System.exit(1);
}
startNode(mainArgs);
}
private static void startNode(MainArgs mainArgs) {
try {
Injector injector;
InputStream commConfigFileInputStream;
InputStream coreConfigFileInputStream;
String commConfigString;
if (mainArgs.commConfigFilePath == null) {
commConfigFileInputStream = Resources.getResource("default.s4.comm.properties").openStream();
commConfigString = "default.s4.comm.properties from classpath";
} else {
commConfigFileInputStream = new FileInputStream(new File(mainArgs.commConfigFilePath));
commConfigString = mainArgs.commConfigFilePath;
}
String coreConfigString;
if (mainArgs.coreConfigFilePath == null) {
coreConfigFileInputStream = Resources.getResource("default.s4.core.properties").openStream();
coreConfigString = "default.s4.core.properties from classpath";
} else {
coreConfigFileInputStream = new FileInputStream(new File(mainArgs.coreConfigFilePath));
coreConfigString = mainArgs.coreConfigFilePath;
}
AbstractModule commModule = (AbstractModule) Class.forName(mainArgs.commModuleClass)
.getConstructor(InputStream.class, String.class)
.newInstance(commConfigFileInputStream, mainArgs.clusterName);
AbstractModule coreModule = (AbstractModule) Class.forName(mainArgs.coreModuleClass)
.getConstructor(InputStream.class).newInstance(coreConfigFileInputStream);
List<com.google.inject.Module> extraModules = new ArrayList<com.google.inject.Module>();
for (String moduleClass : mainArgs.extraModulesClasses) {
extraModules.add((com.google.inject.Module) Class.forName(moduleClass).newInstance());
}
List<com.google.inject.Module> modules = new ArrayList<com.google.inject.Module>();
modules.add((com.google.inject.Module) commModule);
modules.add((com.google.inject.Module) coreModule);
modules.addAll(extraModules);
logger.info(
"Initializing S4 node with : \n- comm module class [{}]\n- comm configuration file [{}]\n- core module class [{}]\n- core configuration file[{}]\n-extra modules: "
+ Arrays.toString(mainArgs.extraModulesClasses.toArray(new String[] {})), new String[] {
mainArgs.commModuleClass, commConfigString, mainArgs.coreModuleClass, coreConfigString });
if (!mainArgs.extraNamedParameters.isEmpty()) {
logger.debug("Adding named parameters for injection : {}",
Arrays.toString(mainArgs.extraNamedParameters.toArray(new String[] {})));
Map<String, String> namedParameters = new HashMap<String, String>();
for (String namedParam : mainArgs.extraNamedParameters) {
namedParameters.put(namedParam.split("[:]")[0].trim(),
namedParam.substring(namedParam.indexOf(':') + 1).trim());
}
modules.add(new ParametersInjectionModule(namedParameters));
}
injector = Guice.createInjector(modules);
if (mainArgs.appClass != null) {
logger.info("Starting S4 node with single application from class [{}]", mainArgs.appClass);
App app = (App) injector.getInstance(Class.forName(mainArgs.appClass));
app.init();
app.start();
} else {
logger.info("Starting S4 node. This node will automatically download applications published for the cluster it belongs to");
Server server = injector.getInstance(Server.class);
try {
server.start(injector);
} catch (Exception e) {
logger.error("Failed to start the controller.", e);
}
}
} catch (Exception e) {
logger.error("Cannot start S4 node", e);
}
}
@Parameters(separators = "=")
public static class MainArgs {
@Parameter(names = { "-c", "-cluster" }, description = "cluster name", required = true)
String clusterName = null;
@Parameter(names = "-commModuleClass", description = "configuration module class for the communication layer", required = false)
String commModuleClass = DefaultCommModule.class.getName();
@Parameter(names = "-commConfig", description = "s4 communication layer configuration file", required = false)
String commConfigFilePath;
@Parameter(names = "-coreModuleClass", description = "s4-core configuration module class", required = false)
String coreModuleClass = DefaultCoreModule.class.getName();
@Parameter(names = "-coreConfig", description = "s4 core configuration file", required = false)
String coreConfigFilePath = null;
@Parameter(names = "-appClass", description = "App class to load. This will disable dynamic downloading but allows to start apps directly. These app classes must have been loaded first, usually through a custom module.", required = false, hidden = true)
String appClass = null;
@Parameter(names = "-extraModulesClasses", description = "additional configuration modules (they will be instantiated through their constructor without arguments).", variableArity = true, required = false, hidden = true)
List<String> extraModulesClasses = new ArrayList<String>();
@Parameter(names = "-namedStringParameters", description = "Guice @Named parameters, used when starting in non dynamic mode, for instance for the adapter. Syntax: '-namedStringParameters=name1:value1,name2:value2 etc...'", hidden = true)
List<String> extraNamedParameters = new ArrayList<String>();
@Parameter(names = "-zk", description = "Zookeeper connection string", required = false)
String zkConnectionString = "localhost:2181";
}
}