From: Mathieu Baudier Date: Thu, 19 Jun 2008 11:53:29 +0000 (+0000) Subject: New runtime end to end (not yet working) X-Git-Tag: argeo-slc-2.1.7~2789 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;ds=inline;h=48d35a213a2b0d792b11b5df276158159105043b;p=gpl%2Fargeo-slc.git New runtime end to end (not yet working) git-svn-id: https://svn.argeo.org/slc/trunk@1253 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntExecutionContext.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntExecutionContext.java new file mode 100644 index 000000000..11487717c --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntExecutionContext.java @@ -0,0 +1,29 @@ +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; + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java index 79f325a9c..76865aef5 100644 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/AntSlcApplication.java @@ -23,12 +23,14 @@ import org.argeo.slc.core.structure.SimpleSElement; 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 { @@ -41,7 +43,7 @@ public class AntSlcApplication { private Resource rootDir; private Resource confDir; - private Resource workDir; + private File workDir; public void init() { try { @@ -66,8 +68,8 @@ public class AntSlcApplication { } - public void execute(SlcExecution slcExecution, Properties properties, - Map references) { + public SlcExecutionContext execute(SlcExecution slcExecution, + Properties properties, Map references) { if (log.isDebugEnabled()) { log.debug("### Start SLC execution " + slcExecution.getUuid() + " ###"); @@ -76,13 +78,24 @@ public class AntSlcApplication { 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 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); @@ -90,8 +103,10 @@ public class AntSlcApplication { initStructure(project, script); runProject(project, targets); - + ctx.close(); + + return executionContext; } protected Resource findAntScript(SlcExecution slcExecution) { @@ -118,11 +133,18 @@ public class AntSlcApplication { 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 findAntTargets(SlcExecution slcExecution) { @@ -138,7 +160,15 @@ public class AntSlcApplication { 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); @@ -311,7 +341,7 @@ public class AntSlcApplication { this.confDir = confDir; } - public void setWorkDir(Resource workDir) { + public void setWorkDir(File workDir) { this.workDir = workDir; } diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcMain.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcMain.java deleted file mode 100644 index cf737a016..000000000 --- a/org.argeo.slc.agent/src/main/java/org/argeo/slc/ant/SlcMain.java +++ /dev/null @@ -1,20 +0,0 @@ -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; - } -} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/cli/DefaultSlcRuntime.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/cli/DefaultSlcRuntime.java new file mode 100644 index 000000000..15aca3d86 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/cli/DefaultSlcRuntime.java @@ -0,0 +1,215 @@ +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 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 Properties. */ + 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); + } + } +} diff --git a/org.argeo.slc.agent/src/main/java/org/argeo/slc/cli/SlcMain.java b/org.argeo.slc.agent/src/main/java/org/argeo/slc/cli/SlcMain.java new file mode 100644 index 000000000..6184c5a76 --- /dev/null +++ b/org.argeo.slc.agent/src/main/java/org/argeo/slc/cli/SlcMain.java @@ -0,0 +1,130 @@ +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"); + } + + } +}