--- /dev/null
+package org.argeo.slc.ant;
+
+import org.apache.tools.ant.Project;
+import org.argeo.slc.core.process.SlcExecution;
+import org.argeo.slc.runtime.SlcExecutionContext;
+import org.springframework.context.ApplicationContext;
+
+public class AntExecutionContext implements SlcExecutionContext {
+ private final Project project;
+
+ public AntExecutionContext(Project project) {
+ this.project = project;
+ }
+
+ public Object getBean(String name) {
+ ApplicationContext context = (ApplicationContext) project
+ .getReference(SlcAntConstants.REF_ROOT_CONTEXT);
+ return context.getBean(name);
+ }
+
+ public SlcExecution getSlcExecution() {
+ return (SlcExecution) project
+ .getReference(SlcAntConstants.REF_SLC_EXECUTION);
+ }
+
+ public Project getProject() {
+ return project;
+ }
+}
import org.argeo.slc.core.structure.StructureRegistry;
import org.argeo.slc.core.structure.tree.TreeSPath;
import org.argeo.slc.core.structure.tree.TreeSRegistry;
+import org.argeo.slc.runtime.SlcExecutionContext;
import org.argeo.slc.runtime.SlcRuntime;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class AntSlcApplication {
private Resource rootDir;
private Resource confDir;
- private Resource workDir;
+ private File workDir;
public void init() {
try {
}
- public void execute(SlcExecution slcExecution, Properties properties,
- Map<String, Object> references) {
+ public SlcExecutionContext execute(SlcExecution slcExecution,
+ Properties properties, Map<String, Object> references) {
if (log.isDebugEnabled()) {
log.debug("### Start SLC execution " + slcExecution.getUuid()
+ " ###");
log.debug("workDir=" + workDir);
}
+ if (rootDir != null)
+ properties.put(SlcAntConstants.ROOT_DIR_PROPERTY, rootDir
+ .toString());
+ if (confDir != null)
+ properties.put(SlcAntConstants.CONF_DIR_PROPERTY, confDir
+ .toString());
+ if (workDir != null)
+ properties.put(SlcAntConstants.WORK_DIR_PROPERTY, workDir
+ .toString());
+
// Ant coordinates
Resource script = findAntScript(slcExecution);
List<String> targets = findAntTargets(slcExecution);
- ConfigurableApplicationContext ctx = createExecutionContext();
+ ConfigurableApplicationContext ctx = createExecutionContext(properties);
Project project = new Project();
+ AntExecutionContext executionContext = new AntExecutionContext(project);
project.addReference(SlcAntConstants.REF_ROOT_CONTEXT, ctx);
project.addReference(SlcAntConstants.REF_SLC_EXECUTION, slcExecution);
initProject(project, properties, references);
initStructure(project, script);
runProject(project, targets);
-
+
ctx.close();
+
+ return executionContext;
}
protected Resource findAntScript(SlcExecution slcExecution) {
log.trace("script(absolute)=" + script);
if (script.exists())
return script;
+
+ script = new FileSystemResource(scriptStr);
+ if (log.isTraceEnabled())
+ log.trace("script(fs)=" + script);
+ if (script.exists())
+ return script;
- throw new SlcAntException("Cannot find Ant script " + scriptStr);
} catch (Exception e) {
throw new SlcAntException("Cannot find Ant script " + scriptStr, e);
}
+
+ throw new SlcAntException("Cannot find Ant script " + scriptStr);
}
protected List<String> findAntTargets(SlcExecution slcExecution) {
return targets;
}
- protected ConfigurableApplicationContext createExecutionContext() {
+ protected ConfigurableApplicationContext createExecutionContext(
+ Properties userProperties) {
+ // Set user properties as system properties so that Spring can access
+ // them
+ for (Object key : userProperties.keySet()) {
+ System.setProperty(key.toString(), userProperties.getProperty(key
+ .toString()));
+ }
+
try {
GenericApplicationContext ctx = new GenericApplicationContext(
context);
this.confDir = confDir;
}
- public void setWorkDir(Resource workDir) {
+ public void setWorkDir(File workDir) {
this.workDir = workDir;
}
+++ /dev/null
-package org.argeo.slc.ant;
-
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-
-public class SlcMain {
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
-
- }
-
- public static Options createOptions(){
- Options options = new Options();
- return options;
- }
-}
--- /dev/null
+package org.argeo.slc.cli;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.ant.AntSlcApplication;
+import org.argeo.slc.ant.SlcAntConstants;
+import org.argeo.slc.ant.SlcAntException;
+import org.argeo.slc.core.SlcException;
+import org.argeo.slc.core.process.SlcExecution;
+import org.argeo.slc.runtime.SimpleSlcRuntime;
+import org.argeo.slc.runtime.SlcExecutionContext;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.Resource;
+
+public class DefaultSlcRuntime extends SimpleSlcRuntime implements
+ BeanFactoryAware {
+ private final static Log log = LogFactory.getLog(DefaultSlcRuntime.class);
+
+ public final static String SLC_ROOT_FILE_NAME = "slcRoot.properties";
+
+ public SlcExecutionContext executeScript(Resource script,
+ Properties properties, Map<String, Object> references) {
+
+ if (runtimeContext == null)
+ runtimeContext = new GenericApplicationContext();
+
+ SlcExecution slcExecution = new SlcExecution();
+ slcExecution.setUuid(UUID.randomUUID().toString());
+ try {
+ slcExecution.setHost(InetAddress.getLocalHost().getHostName());
+ } catch (UnknownHostException e) {
+ slcExecution.setHost(SlcExecution.UNKOWN_HOST);
+ }
+
+ slcExecution.setType(SlcAntConstants.EXECTYPE_SLC_ANT);
+
+ slcExecution.setUser(System.getProperty("user.name"));
+ slcExecution.setStatus(SlcExecution.STATUS_RUNNING);
+ slcExecution.getAttributes().put(SlcAntConstants.EXECATTR_ANT_FILE,
+ script.toString());
+
+ AntSlcApplication application = new AntSlcApplication();
+ prepareApplication(slcExecution, application, script);
+ return application.execute(slcExecution, properties, references);
+ }
+
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ runtimeContext = (ApplicationContext) beanFactory;
+ }
+
+ protected void prepareApplication(SlcExecution slcExecution,
+ AntSlcApplication application, Resource script) {
+ try {
+ final String fileUrlPrefix = "";
+
+ Resource slcRootFile = findSlcRootFile(script);
+
+ // Remove basedir property in order to avoid conflict with Maven
+ // if (all.containsKey("basedir"))
+ // all.remove("basedir");
+
+ InputStream inRootFile = slcRootFile.getInputStream();
+ Properties rootProps = loadFile(inRootFile);
+
+ Resource confDir = null;
+ File workDir = null;
+ // Root dir
+ final Resource rootDir = getParentOfFile(slcRootFile);
+
+ // Conf dir
+ String confDirStr = rootProps
+ .getProperty(SlcAntConstants.CONF_DIR_PROPERTY);
+ if (confDirStr != null)
+ confDir = runtimeContext.getResource(confDirStr);
+
+ if (confDir == null || !confDir.exists()) {
+ confDir = rootDir.createRelative("../conf");
+ }
+
+ // Work dir
+ String workDirStr = rootProps
+ .getProperty(SlcAntConstants.WORK_DIR_PROPERTY);
+ if (workDirStr != null) {
+ workDir = new File(workDirStr);
+ }
+
+ if (workDir == null || !workDir.exists()) {
+ try {
+ File rootDirAsFile = rootDir.getFile();
+ workDir = new File(rootDirAsFile.getParent()
+ + File.separator + "work").getCanonicalFile();
+ } catch (IOException e) {
+ workDir = new File(System.getProperty("java.io.tmpdir")
+ + File.separator + "slcExecutions" + File.separator
+ + slcExecution.getUuid()).getCanonicalFile();
+ log.debug("Root dir is not a file: " + e.getMessage()
+ + ", creating work dir in temp: " + workDir);
+ }
+ }
+
+ application.setConfDir(confDir);
+ application.setRootDir(rootDir);
+ application.setWorkDir(workDir);
+
+ application.setSlcRuntime(this);
+ } catch (IOException e) {
+ throw new SlcException(
+ "Could not prepare SLC application for SLC execution "
+ + slcExecution.getUuid() + " and script " + script,
+ e);
+ }
+
+ // Properties from the conf dir files
+ // Properties properties = new Properties();
+ // StringTokenizer st = new StringTokenizer(rootProps.getProperty(
+ // PROPERTY_FILE_NAMES_PROPERTY, "slc.properties"), ",");
+ // while (st.hasMoreTokens()) {
+ // String fileName = st.nextToken();
+ // properties.putAll(loadFile(confDir.getAbsolutePath()
+ // + File.separator + fileName));
+ // }
+ //
+ // for (Object o : properties.keySet()) {
+ // String key = o.toString();
+ // if (all.getProperty(key) == null) {// not already set
+ // all.setProperty(key, properties.getProperty(key));
+ // }
+ // }
+ //
+ }
+
+ /**
+ * Recursively scans directories downwards until it find a file name as
+ * defined by {@link #SLC_ROOT_FILE_NAME}.
+ */
+ protected Resource findSlcRootFile(Resource currDir) {
+ if (log.isDebugEnabled())
+ log.debug("Look for SLC root file in " + currDir);
+
+ try {
+ Resource slcRootFile = currDir.createRelative(SLC_ROOT_FILE_NAME);
+ if (slcRootFile.exists()) {
+ return slcRootFile;
+ } else {
+ String currPath = currDir.getURL().getPath();
+ if (currPath.equals("/") || currPath.equals("")) {
+ return null;
+ } else {
+ return findSlcRootFile(getParentOfDir(currDir));
+ }
+ // int indx = currPath.lastIndexOf('/',currPath.length()-1);
+
+ }
+ } catch (IOException e) {
+ throw new SlcException("Problem when looking in SLC root file in "
+ + currDir, e);
+ }
+
+ // for (File file : dir.listFiles()) {
+ // if (!file.isDirectory()
+ // && file.getName().equals(SLC_ROOT_FILE_NAME)) {
+ // return file;
+ // }
+ // }
+ //
+ // File parentDir = dir.getParentFile();
+ // if (parentDir == null) {
+ // return null;// stop condition: not found
+ // } else {
+ // return findSlcRootFile(parentDir);
+ // }
+ }
+
+ /** Loads the content of a file as <code>Properties</code>. */
+ private Properties loadFile(InputStream in) {
+ Properties p = new Properties();
+ try {
+ p.load(in);
+ } catch (IOException e) {
+ throw new SlcAntException("Cannot read SLC root file", e);
+ }
+ return p;
+ }
+
+ private Resource getParentOfDir(Resource dir) {
+ try {
+ return dir.createRelative("..");
+ } catch (IOException e) {
+ throw new SlcException("Cannot get parent for resource " + dir, e);
+ }
+ }
+
+ private Resource getParentOfFile(Resource file) {
+ try {
+ return file.createRelative(".");
+ } catch (IOException e) {
+ throw new SlcException("Cannot get parent for resource " + file, e);
+ }
+ }
+}
--- /dev/null
+package org.argeo.slc.cli;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.argeo.slc.core.SlcException;
+import org.springframework.core.io.FileSystemResource;
+
+public class SlcMain {
+ public enum Mode {
+ single, agent
+ }
+
+ public final static String MODE_SINGLE = "single";
+ public final static String MODE_AGENT = "agent";
+
+ private final static Option modeOpt = OptionBuilder.withLongOpt("mode")
+ .withArgName("mode").hasArg().isRequired().withDescription(
+ "SLC execution mode, one of: " + listModeValues()).create(
+ 'm');
+
+ private final static Option propertyOpt = OptionBuilder.withLongOpt(
+ "property").withArgName("prop1=val1,prop2=val2").hasArgs()
+ .withValueSeparator(',').withDescription(
+ "use value for given property").create('p');
+
+ private final static Option scriptOpt = OptionBuilder.withLongOpt("script")
+ .withArgName("script").hasArg().withType(File.class)
+ .withDescription("SLC script to execute").create('s');
+
+ private final static Options options;
+
+ private final static String commandName = "slc";
+
+ static {
+ options = new Options();
+ options.addOption(modeOpt);
+ options.addOption(scriptOpt);
+ options.addOption(propertyOpt);
+ }
+
+ public static void main(String[] args) {
+ Mode mode = null;
+ Properties properties = new Properties();
+ File script = null;
+
+ try {
+ CommandLineParser clParser = new GnuParser();
+ CommandLine cl = clParser.parse(options, args);
+
+ // Mode
+ String modeStr = cl.getOptionValue(modeOpt.getOpt());
+ try {
+ mode = Mode.valueOf(modeStr);
+ } catch (IllegalArgumentException e) {
+ throw new SlcException("Unrecognized mode '" + modeStr + "'", e);
+ }
+ System.out.println("Mode: " + mode);
+
+ // Script
+ if (mode.equals(Mode.single)) {
+ if (!cl.hasOption(scriptOpt.getOpt()))
+ throw new SlcException("Mode " + Mode.single
+ + " requires option '" + scriptOpt.getLongOpt()
+ + "'");
+ script = (File) cl.getOptionObject(scriptOpt.getOpt());
+ }
+ System.out.println("Script: " + script.getAbsolutePath());
+
+ // Properties
+ if (cl.hasOption(propertyOpt.getOpt())) {
+ for (String property : cl.getOptionValues(propertyOpt.getOpt())) {
+ addProperty(properties, property);
+ }
+ }
+ System.out.print("Properties: " + properties);
+ } catch (ParseException e) {
+ System.err.println("Problem with command line arguments. "
+ + e.getMessage());
+ printUsage();
+ } catch (SlcException e) {
+ System.err.println(e.getMessage());
+ printUsage();
+ }
+
+ if (mode.equals(Mode.single)) {
+ DefaultSlcRuntime runtime = new DefaultSlcRuntime();
+ runtime.executeScript(new FileSystemResource(script), properties,
+ null);
+ }
+ }
+
+ public static void printUsage() {
+ new HelpFormatter().printHelp(commandName, options, true);
+ }
+
+ private static String listModeValues() {
+ StringBuffer buf = new StringBuffer("");
+ for (Mode mode : Mode.values()) {
+ buf.append(mode).append(", ");
+ }
+ String str = buf.toString();
+ // unsafe, but there will be at least one value in the enum
+ return str.substring(0, str.length() - 2);
+ }
+
+ private static void addProperty(Properties properties, String property) {
+ int eqIndex = property.indexOf('=');
+ if (eqIndex == 0)
+ throw new SlcException("Badly formatted property " + property);
+
+ if (eqIndex > 0) {
+ String key = property.substring(0, eqIndex);
+ String value = property.substring(eqIndex + 1);
+ properties.setProperty(key, value);
+
+ } else {
+ properties.setProperty(property, "true");
+ }
+
+ }
+}