From 45788cedce74d877422a5aaea446f6c949bbbfb8 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 9 Jun 2009 13:00:16 +0000 Subject: [PATCH] @update:81; Ability to copy the content of resources locally, thus enabling launchying of scripts stored within the bundles. git-svn-id: https://svn.argeo.org/slc/trunk@2519 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../core/execution/ExecutionResources.java | 2 + .../execution/FileExecutionResources.java | 43 ++++++ .../core/execution/MapExecutionContext.java | 10 +- .../slc/core/execution/OsFileFactoryBean.java | 48 ++++++ .../core/execution/ResourceSpecAttribute.java | 13 +- .../slc/core/execution/tasks/SystemCall.java | 139 ++---------------- .../org/argeo/slc/core/execution/defaults.xml | 20 +++ .../org/argeo/slc/core/execution/spring.xml | 1 + .../argeo/slc/core/execution/templates.xml | 8 +- 9 files changed, 152 insertions(+), 132 deletions(-) create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/OsFileFactoryBean.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/defaults.xml diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java index f10de57dd..53f5af79a 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionResources.java @@ -4,4 +4,6 @@ import org.springframework.core.io.Resource; public interface ExecutionResources { public Resource getWritableResource(String relativePath); + + public String getAsOsPath(Resource resource, Boolean overwrite); } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java index a023fc7f5..e032e6a0c 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java @@ -1,10 +1,16 @@ package org.argeo.slc.core.execution; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.text.SimpleDateFormat; +import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; import org.argeo.slc.execution.ExecutionContext; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; @@ -74,6 +80,43 @@ public class FileExecutionResources implements ExecutionResources { return resource; } + public String getAsOsPath(Resource resource, Boolean overwrite) { + File file = null; + try { + file = resource.getFile(); + return file.getCanonicalPath(); + } catch (IOException e) { + if (log.isTraceEnabled()) + log + .trace("Resource " + + resource + + " is not available on the file system. Retrieving it..."); + } + + InputStream in = null; + OutputStream out = null; + try { + String path = resource.getURL().getPath(); + file = getFile(path); + if (file.exists() && !overwrite) + return file.getCanonicalPath(); + + file.getParentFile().mkdirs(); + in = resource.getInputStream(); + out = new FileOutputStream(file); + IOUtils.copy(in, out); + if (log.isDebugEnabled()) + log.debug("Retrieved " + resource + " to OS file " + file); + return file.getCanonicalPath(); + } catch (IOException e) { + throw new SlcException("Could not make resource " + resource + + " an OS file.", e); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } + } + public File getFile(String relativePath) { Assert.notNull(executionContext, "execution context is null"); diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/MapExecutionContext.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/MapExecutionContext.java index 5d26c52b4..f38342662 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/MapExecutionContext.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/MapExecutionContext.java @@ -12,8 +12,6 @@ import org.argeo.slc.SlcException; import org.argeo.slc.execution.ExecutionContext; import org.argeo.slc.execution.ExecutionFlow; import org.argeo.slc.execution.ExecutionSpecAttribute; -import org.argeo.slc.process.SlcExecution; -import org.springframework.beans.factory.ObjectFactory; public class MapExecutionContext implements ExecutionContext { private final static Log log = LogFactory.getLog(MapExecutionContext.class); @@ -23,10 +21,16 @@ public class MapExecutionContext implements ExecutionContext { // TODO: make it thread safe? private final Map variables = new HashMap(); - private final String uuid = UUID.randomUUID().toString(); + private final String uuid; private final Date creationDate = new Date(); + public MapExecutionContext() { + uuid = UUID.randomUUID().toString(); + if (log.isDebugEnabled()) + log.debug("Execution context #" + uuid + " instantiated."); + } + public void addVariables( Map variablesToAdd) { variables.putAll(variablesToAdd); diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/OsFileFactoryBean.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/OsFileFactoryBean.java new file mode 100644 index 000000000..b566e5742 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/OsFileFactoryBean.java @@ -0,0 +1,48 @@ +package org.argeo.slc.core.execution; + +import java.io.File; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.core.io.Resource; +import org.springframework.util.Assert; + +/** Workaround when execution placedholders needs to be passed. */ +public class OsFileFactoryBean implements FactoryBean { + private ExecutionResources executionResources; + private Resource resource; + private Boolean overwrite = false; + + /** Return an existing file on the fiel system. */ + public Object getObject() throws Exception { + Assert.notNull(executionResources, "executionResources is null"); + Assert.notNull(resource, "relativePath is null"); + return executionResources.getAsOsPath(resource, overwrite); + } + + public Class getObjectType() { + return File.class; + } + + public boolean isSingleton() { + return true; + } + + /** The execution resources object. */ + public void setExecutionResources(ExecutionResources executionResources) { + this.executionResources = executionResources; + } + + /** The resource to access. */ + public void setResource(Resource resource) { + this.resource = resource; + } + + /** + * Whether to overwrite the resource if it already exists. Default is + * false. + */ + public void setOverwrite(Boolean overwrite) { + this.overwrite = overwrite; + } + +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java index 572665dd5..8eecc0b47 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java @@ -2,10 +2,12 @@ package org.argeo.slc.core.execution; import java.io.IOException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; import org.springframework.core.io.Resource; -// TODO: offer the ability to read the resource +/** @deprecated */ public class ResourceSpecAttribute extends AbstractSpecAttribute { public final static String TYPE_PATH = "path"; public final static String TYPE_URL = "url"; @@ -14,6 +16,15 @@ public class ResourceSpecAttribute extends AbstractSpecAttribute { private Resource resource; private String type = TYPE_PATH; + private final static Log log = LogFactory + .getLog(ResourceSpecAttribute.class); + + public ResourceSpecAttribute() { + log + .warn(getClass() + + " is deprecated and will soon be removed. Please use slcDefault.executionResources instead."); + } + public Object getValue() { return convertResource(resource); } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java index 988b6b853..2bb835b24 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java @@ -1,13 +1,6 @@ package org.argeo.slc.core.execution.tasks; -import java.io.BufferedReader; import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -21,17 +14,13 @@ import org.apache.commons.exec.Executor; import org.apache.commons.exec.LogOutputStream; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.exec.ShutdownHookProcessDestroyer; -import org.apache.commons.exec.launcher.CommandLauncher; -import org.apache.commons.exec.launcher.CommandLauncherFactory; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.NotImplementedException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; +/** Execute and OS system call. */ public class SystemCall implements Runnable { - // TODO: specify environment variables - private final Log log = LogFactory.getLog(getClass()); private String execDir; @@ -40,7 +29,6 @@ public class SystemCall implements Runnable { private List command = null; private Boolean synchronous = true; - // private Boolean captureStdIn = false; private String stdErrLogLevel = "ERROR"; private String stdOutLogLevel = "INFO"; @@ -67,8 +55,6 @@ public class SystemCall implements Runnable { dir = new File(execDir).getCanonicalFile(); } - // Process process = null; - // Check if an OS specific command overrides String osName = System.getProperty("os.name"); List commandToUse = null; @@ -117,7 +103,6 @@ public class SystemCall implements Runnable { + getUsedDir(dir)); commandLine = CommandLine.parse(cmdToUse); - // process = Runtime.getRuntime().exec(cmdToUse, null, dir); } else if (commandToUse != null) { if (log.isTraceEnabled()) log.trace("Execute '" + commandToUse + "' in " @@ -128,10 +113,6 @@ public class SystemCall implements Runnable { commandLine = new CommandLine(commandToUse.get(0)); for (int i = 1; i < commandToUse.size(); i++) commandLine.addArgument(commandToUse.get(i)); - // ProcessBuilder processBuilder = new - // ProcessBuilder(commandToUse); - // processBuilder.directory(dir); - // process = processBuilder.start(); } else { // all cases covered previously throw new NotImplementedException(); @@ -145,7 +126,9 @@ public class SystemCall implements Runnable { ExecuteResultHandler executeResultHandler = new ExecuteResultHandler() { public void onProcessComplete(int exitValue) { - log.info("Process " + commandLine + " properly completed."); + if (log.isDebugEnabled()) + log.debug("Process " + commandLine + + " properly completed."); } public void onProcessFailed(ExecuteException e) { @@ -165,35 +148,6 @@ public class SystemCall implements Runnable { else executor.execute(commandLine, environmentVariablesToUse, executeResultHandler); - - // Manage standard streams - // StreamReaderThread stdOutThread = new StreamReaderThread(process - // .getInputStream()) { - // protected void callback(String line) { - // stdOutCallback(line); - // } - // }; - // stdOutThread.start(); - // StreamReaderThread stdErrThread = new StreamReaderThread(process - // .getErrorStream()) { - // protected void callback(String line) { - // stdErrCallback(line); - // } - // }; - // stdErrThread.start(); - // if (captureStdIn) - // new StdInThread(process.getOutputStream()).start(); - // - // // Wait for the end of the process - // if (synchronous) { - // Integer exitCode = process.waitFor(); - // if (exitCode != 0) { - // Thread.sleep(5000);// leave the process a chance to log - // log.warn("Process return exit code " + exitCode); - // } - // } else { - // // asynchronous: return - // } } catch (Exception e) { throw new SlcException("Could not execute command " + cmd, e); } @@ -211,14 +165,6 @@ public class SystemCall implements Runnable { return dir.getPath(); } - // protected void stdOutCallback(String line) { - // log(stdOutLogLevel, line); - // } - // - // protected void stdErrCallback(String line) { - // log(stdErrLogLevel, line); - // } - // protected void log(String logLevel, String line) { if ("ERROR".equals(logLevel)) log.error(line); @@ -254,10 +200,6 @@ public class SystemCall implements Runnable { this.synchronous = synchronous; } - // public void setCaptureStdIn(Boolean captureStdIn) { - // this.captureStdIn = captureStdIn; - // } - public void setCommand(List command) { this.command = command; } @@ -270,69 +212,12 @@ public class SystemCall implements Runnable { this.osCmds = osCmds; } - // protected abstract class StreamReaderThread extends Thread { - // private final InputStream stream; - // - // public StreamReaderThread(InputStream stream) { - // this.stream = stream; - // } - // - // @Override - // public void run() { - // BufferedReader in = null; - // try { - // in = new BufferedReader(new InputStreamReader(stream)); - // String line = null; - // while ((line = in.readLine()) != null) { - // stdOutCallback(line); - // } - // } catch (IOException e) { - // if (log.isTraceEnabled()) { - // log.trace("Could not read stream", e); - // // catch silently - // // because the other methods - // // to check whether the stream - // // is closed would probably - // // be to costly - // } - // } finally { - // if (synchronous) - // IOUtils.closeQuietly(in); - // } - // } - // - // protected abstract void callback(String line); - // } - // - // protected class StdInThread extends Thread { - // private final OutputStream stream; - // - // public StdInThread(OutputStream stream) { - // this.stream = stream; - // } - // - // @Override - // public void run() { - // BufferedReader in = null; - // Writer out = null; - // try { - // out = new OutputStreamWriter(stream); - // in = new BufferedReader(new InputStreamReader(System.in)); - // String line = null; - // while ((line = in.readLine()) != null) { - // out.write(line); - // out.write("\n"); - // out.flush(); - // } - // } catch (IOException e) { - // throw new SlcException("Could not write to stdin stream", e); - // } finally { - // if (synchronous) { - // IOUtils.closeQuietly(in); - // IOUtils.closeQuietly(out); - // } - // } - // } - // - // } + public void setEnvironmentVariables(Map environmentVariables) { + this.environmentVariables = environmentVariables; + } + + public void setWatchdogTimeout(Long watchdogTimeout) { + this.watchdogTimeout = watchdogTimeout; + } + } diff --git a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/defaults.xml b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/defaults.xml new file mode 100644 index 000000000..09e7a5c1d --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/defaults.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/spring.xml b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/spring.xml index 663ea3cb5..3cfac026b 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/spring.xml +++ b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/spring.xml @@ -9,6 +9,7 @@ + diff --git a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/templates.xml b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/templates.xml index 5f022268d..4566adf62 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/templates.xml +++ b/runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/templates.xml @@ -7,8 +7,14 @@ - + + + + \ No newline at end of file -- 2.39.2