From dfdce3de968e09ed7d4cf443a6bfcbc9c5e819f2 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 21 Feb 2009 13:03:28 +0000 Subject: [PATCH] Move SLC Execution to runtime git-svn-id: https://svn.argeo.org/slc/trunk@2159 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- runtime/org.argeo.slc.execution/.classpath | 7 + runtime/org.argeo.slc.execution/.project | 29 +++ runtime/org.argeo.slc.execution/.springBeans | 19 ++ runtime/org.argeo.slc.execution/pom.xml | 56 +++++ .../slc/execution/AbstractSpecAttribute.java | 14 ++ .../execution/ConsoleContextDescriber.java | 39 ++++ .../argeo/slc/execution/ContextDescriber.java | 9 + .../org/argeo/slc/execution/EfLauncher.java | 120 +++++++++++ .../argeo/slc/execution/ExecutionAspect.java | 37 ++++ .../argeo/slc/execution/ExecutionContext.java | 195 ++++++++++++++++++ .../slc/execution/ExecutionFinishedEvent.java | 19 ++ .../argeo/slc/execution/ExecutionFlow.java | 11 + .../slc/execution/ExecutionFlowFactory.java | 25 +++ .../ExecutionParameterPostProcessor.java | 120 +++++++++++ .../slc/execution/ExecutionRegister.java | 47 +++++ .../argeo/slc/execution/ExecutionScope.java | 47 +++++ .../argeo/slc/execution/ExecutionSpec.java | 7 + .../slc/execution/ExecutionSpecAttribute.java | 6 + .../slc/execution/ExecutionTargetSource.java | 44 ++++ .../org/argeo/slc/execution/Executor.java | 70 +++++++ .../execution/InstantiationPostProcessor.java | 29 +++ .../slc/execution/NewExecutionEvent.java | 20 ++ .../argeo/slc/execution/RefSpecAttribute.java | 23 +++ .../slc/execution/SimpleExecutionFlow.java | 114 ++++++++++ .../slc/execution/SimpleExecutionSpec.java | 74 +++++++ .../slc/execution/SimpleSpecAttribute.java | 13 ++ .../org/argeo/slc/execution/tasks/Echo.java | 29 +++ .../src/slc/conf/BasicExecutionFlow.groovy | 12 ++ .../src/slc/conf/basic.xml | 78 +++++++ .../src/slc/conf/common.xml | 19 ++ .../src/slc/conf/main.xml | 68 ++++++ .../src/slc/conf/slc.properties | 16 ++ .../src/slc/conf/test.xml | 105 ++++++++++ .../src/slc/conf/testCases/basic-001.xml | 37 ++++ .../src/slc/conf/testCases/basic-002.xml | 27 +++ 35 files changed, 1585 insertions(+) create mode 100644 runtime/org.argeo.slc.execution/.classpath create mode 100644 runtime/org.argeo.slc.execution/.project create mode 100644 runtime/org.argeo.slc.execution/.springBeans create mode 100644 runtime/org.argeo.slc.execution/pom.xml create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/AbstractSpecAttribute.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ConsoleContextDescriber.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ContextDescriber.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/EfLauncher.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionAspect.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionContext.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFinishedEvent.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlow.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlowFactory.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionParameterPostProcessor.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionRegister.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionScope.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpec.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionTargetSource.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/Executor.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/InstantiationPostProcessor.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/NewExecutionEvent.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/RefSpecAttribute.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionFlow.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionSpec.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleSpecAttribute.java create mode 100644 runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/tasks/Echo.java create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/BasicExecutionFlow.groovy create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/basic.xml create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/common.xml create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/main.xml create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/slc.properties create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/test.xml create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-001.xml create mode 100644 runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-002.xml diff --git a/runtime/org.argeo.slc.execution/.classpath b/runtime/org.argeo.slc.execution/.classpath new file mode 100644 index 000000000..16f01e2ee --- /dev/null +++ b/runtime/org.argeo.slc.execution/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/runtime/org.argeo.slc.execution/.project b/runtime/org.argeo.slc.execution/.project new file mode 100644 index 000000000..63e0d7408 --- /dev/null +++ b/runtime/org.argeo.slc.execution/.project @@ -0,0 +1,29 @@ + + + argeo.slc.executionflow + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + + org.springframework.ide.eclipse.core.springnature + org.maven.ide.eclipse.maven2Nature + org.eclipse.jdt.core.javanature + + diff --git a/runtime/org.argeo.slc.execution/.springBeans b/runtime/org.argeo.slc.execution/.springBeans new file mode 100644 index 000000000..07dddcb58 --- /dev/null +++ b/runtime/org.argeo.slc.execution/.springBeans @@ -0,0 +1,19 @@ + + + 1 + + + + + + + src/slc/conf/main.xml + src/slc/conf/testCases/basic-001.xml + src/slc/conf/testCases/basic-002.xml + src/slc/conf/basic.xml + src/slc/conf/common.xml + src/slc/conf/test.xml + + + + diff --git a/runtime/org.argeo.slc.execution/pom.xml b/runtime/org.argeo.slc.execution/pom.xml new file mode 100644 index 000000000..1025a48ce --- /dev/null +++ b/runtime/org.argeo.slc.execution/pom.xml @@ -0,0 +1,56 @@ + + 4.0.0 + + org.argeo.slc + argeo-slc + 0.11.3-SNAPSHOT + ../../org.argeo.slc + + org.argeo.slc.sandbox + org.argeo.slc.sandbox.executionflow + SLC Sandbox Execution Flow + jar + + + + + maven-jar-plugin + + + + + + + + org.argeo.slc.runtime + org.argeo.slc.support.simple + + + + org.aspectj + com.springsource.org.aspectj.runtime + 1.6.2.RELEASE + + + org.aspectj + com.springsource.org.aspectj.weaver + 1.6.2.RELEASE + + + org.codehaus.groovy + com.springsource.org.codehaus.groovy + 1.5.7 + + + org.beanshell + com.springsource.bsh + 2.0.0.b4 + + + net.sourceforge.cglib + com.springsource.net.sf.cglib + 2.1.3 + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/AbstractSpecAttribute.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/AbstractSpecAttribute.java new file mode 100644 index 000000000..74c2a6bef --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/AbstractSpecAttribute.java @@ -0,0 +1,14 @@ +package org.argeo.slc.execution; + +public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute { + private Boolean isParameter = true; + + public Boolean getIsParameter() { + return isParameter; + } + + public void setIsParameter(Boolean isParameter) { + this.isParameter = isParameter; + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ConsoleContextDescriber.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ConsoleContextDescriber.java new file mode 100644 index 000000000..43f544351 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ConsoleContextDescriber.java @@ -0,0 +1,39 @@ +package org.argeo.slc.execution; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; + +public class ConsoleContextDescriber implements ContextDescriber { + private final static Log log = LogFactory + .getLog(ConsoleContextDescriber.class); + + public void describeContext(BeanDefinitionRegistry registry) { + String[] beanNames = registry.getBeanDefinitionNames(); + for (String beanName : beanNames) { + log("\n## BEAN: " + beanName); + describeBean(registry.getBeanDefinition(beanName)); + } + } + + public void describeBean(BeanDefinition beanDefinition) { + log("BeanDefinition class: "+beanDefinition.getClass()); + log("# ATTRIBUTES"); + for(String attr:beanDefinition.attributeNames()){ + log(attr+"="+beanDefinition.getAttribute(attr)); + } + log("# PROPERTIES"); + MutablePropertyValues pValues = beanDefinition.getPropertyValues(); + for (PropertyValue pv : pValues.getPropertyValues()) { + log(pv.getName() + "= (" + pv.getValue().getClass() + ") " + + pv.getValue()); + } + } + + protected void log(Object obj){ + System.out.println(obj); + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ContextDescriber.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ContextDescriber.java new file mode 100644 index 000000000..289a53769 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ContextDescriber.java @@ -0,0 +1,9 @@ +package org.argeo.slc.execution; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; + +public interface ContextDescriber { + public void describeContext(BeanDefinitionRegistry registry); + public void describeBean(BeanDefinition bd); +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/EfLauncher.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/EfLauncher.java new file mode 100644 index 000000000..56d89ec39 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/EfLauncher.java @@ -0,0 +1,120 @@ +package org.argeo.slc.execution; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.logging.Log4jUtils; +import org.argeo.slc.process.SlcExecution; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry; +import org.springframework.beans.factory.xml.XmlBeanDefinitionParser; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.springframework.context.support.GenericApplicationContext; + +public class EfLauncher implements ApplicationListener { + private final Log log; + + private boolean running = false; + + public EfLauncher() { + Properties userProperties = new Properties(); + FileInputStream in = null; + try { + in = new FileInputStream("src/slc/conf/slc.properties"); + userProperties.load(in); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + } + + // Set as System properties + for (Object obj : userProperties.keySet()) { + String key = obj.toString(); + System.setProperty(key, userProperties.getProperty(key)); + } + + // Logging + System.setProperty("log4j.defaultInitOverride", "true"); + + Log4jUtils.initLog4j(null); + log = LogFactory.getLog(EfLauncher.class); + } + + public void launch(String script) { + // describe(script); + + GenericApplicationContext context = new GenericApplicationContext(); + XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(context); + reader.loadBeanDefinitions(script); + // FileSystemXmlApplicationContext context = new + // FileSystemXmlApplicationContext( + // script); + context.addApplicationListener(this); + context.refresh(); + context.start(); + log.debug("Context initialized"); + + SlcExecution slcExecution = new SlcExecution(); + slcExecution.getAttributes().put("slc.flows", "main"); + + running = true; + context.publishEvent(new NewExecutionEvent(this, slcExecution)); + + synchronized (this) { + while (running) + try { + wait(); + } catch (InterruptedException e) { + // silent + } + } + } + + public synchronized boolean isRunning() { + return running; + } + + public synchronized void setRunning(boolean running) { + this.running = running; + } + + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof ExecutionFinishedEvent) { + ExecutionContext executionContext = ((ExecutionFinishedEvent) event) + .getExecutionContext(); + log.debug("Execution " + executionContext.getUuid() + + " finished, stopping launcher..."); + synchronized (this) { + running = false; + notifyAll(); + } + } + + } + + public static void main(String[] args) { + String script = "file:src/slc/conf/main.xml"; + new EfLauncher().launch(script); + } + + private static void describe(String script) { + SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); + XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry); + reader.loadBeanDefinitions(script); + new ConsoleContextDescriber().describeContext(registry); + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionAspect.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionAspect.java new file mode 100644 index 000000000..5a366cfed --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionAspect.java @@ -0,0 +1,37 @@ +package org.argeo.slc.execution; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; + +@Aspect +public class ExecutionAspect { + private static Log log = LogFactory.getLog(ExecutionAspect.class); + + @Before("flowExecution()") + public void beforeFlow(JoinPoint jp) throws Throwable { + //log.debug("this " + jp.getThis().getClass()); + //log.debug("target " + jp.getTarget().getClass()); + // Thread.dumpStack(); + ExecutionFlow executionFlow = (ExecutionFlow) jp.getTarget(); + ExecutionContext.enterFlow(executionFlow); + } + + @After("flowExecution()") + public void afterFlow(JoinPoint jp) throws Throwable { + //log.debug("this " + jp.getThis().getClass()); + //log.debug("target " + jp.getTarget().getClass()); + ExecutionFlow executionFlow = (ExecutionFlow) jp.getTarget(); + ExecutionContext.leaveFlow(executionFlow); + } + + @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.execute())") + public void flowExecution() { + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionContext.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionContext.java new file mode 100644 index 000000000..db8af23d5 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionContext.java @@ -0,0 +1,195 @@ +package org.argeo.slc.execution; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; +import java.util.UUID; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.process.SlcExecution; +import org.springframework.beans.factory.ObjectFactory; + +public class ExecutionContext { + private final static Log log = LogFactory.getLog(ExecutionContext.class); + + private final static ThreadLocal executionContext = new ThreadLocal(); + + private final Stack stack = new Stack(); + + // TODO: make it thread safe? + private final Map variables = new HashMap(); + + private final String uuid = UUID.randomUUID().toString(); + + public static Map getVariables() { + if (executionContext.get() == null) + return null; + return executionContext.get().variables; + } + + public static ExecutionContext getCurrent() { + return executionContext.get(); + } + + public static String getExecutionUuid() { + if (executionContext.get() == null) + return null; + return executionContext.get().getUuid(); + } + + public static void registerExecutionContext(ExecutionContext context) { + if (executionContext.get() != null) + throw new SlcException("Context #" + executionContext.get().uuid + + " already registered."); + executionContext.set(context); + } + + public static void enterFlow(ExecutionFlow executionFlow) { + Stack stack = executionContext.get().stack; + + ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow); + stack.push(runtime); + + if (log.isTraceEnabled()) + log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #" + + getCurrentStackUuid() + ", depth=" + stack.size()); + + Map specAttrs = executionFlow + .getExecutionSpec().getAttributes(); + for (String key : specAttrs.keySet()) { + ExecutionSpecAttribute esa = specAttrs.get(key); + if (esa.getIsParameter()) { + runtime.getLocalVariables().put(key, + executionFlow.getParameter(key)); + if (log.isTraceEnabled()) + log.trace(depthSpaces(stack.size()) + "Add '" + key + + "' as local variable."); + } + } + + } + + public static Object getVariable(String key) { + Object obj = getWithCheck().findVariable(key); + if (obj == null) + throw new SlcException("Variable '" + key + "' not found."); + return obj; + } + + protected Object findVariable(String key) { + Object obj = null; + for (int i = stack.size() - 1; i >= 0; i--) { + if (stack.get(i).getLocalVariables().containsKey(key)) { + obj = stack.get(i).getLocalVariables().get(key); + break; + } + } + + // Look into global execution variables + if (obj == null) { + if (variables.containsKey(key)) + obj = variables.get(key); + } + + return obj; + } + + private static String depthSpaces(int depth) { + StringBuffer buf = new StringBuffer(depth * 2); + for (int i = 0; i < depth; i++) + buf.append(" "); + return buf.toString(); + } + + public static void leaveFlow(ExecutionFlow executionFlow) { + Stack stack = executionContext.get().stack; + if (log.isTraceEnabled()) + log.debug(depthSpaces(stack.size()) + "<= " + executionFlow + " #" + + getCurrentStackUuid() + ", depth=" + stack.size()); + + ExecutionFlowRuntime leftEf = stack.pop(); + if (!leftEf.getExecutionFlow().getUuid() + .equals(executionFlow.getUuid())) + throw new SlcException("Asked to leave " + executionFlow + + " but last is " + leftEf); + + leftEf.getScopedObjects().clear(); + leftEf.getLocalVariables().clear(); + + } + + public static String getCurrentStackUuid() { + return getWithCheck().stack.peek().uuid; + } + + // public static ExecutionFlow getCurrentFlow() { + // return getWithCheck().stack.peek().executionFlow; + // } + + public static Boolean isExecuting() { + return executionContext.get() != null; + } + + protected static ExecutionContext getWithCheck() { + if (executionContext.get() == null) + throw new SlcException("No execution context"); + return executionContext.get(); + } + + public static Object findOrAddScopedObject(String name, + ObjectFactory objectFactory) { + ExecutionContext executionContext = getWithCheck(); + Object obj = executionContext.findScopedObject(name); + if (obj == null) { + obj = objectFactory.getObject(); + executionContext.stack.peek().getScopedObjects().put(name, obj); + } + return obj; + } + + /** return null if not found */ + protected Object findScopedObject(String key) { + Object obj = null; + for (int i = stack.size() - 1; i >= 0; i--) { + if (stack.get(i).getScopedObjects().containsKey(key)) { + obj = stack.get(i).getScopedObjects().get(key); + break; + } + } + return obj; + } + + public String getUuid() { + return uuid; + } + + private static class ExecutionFlowRuntime { + private final ExecutionFlow executionFlow; + private final Map scopedObjects = new HashMap(); + private final Map localVariables = new HashMap(); + private final String uuid = UUID.randomUUID().toString(); + + public ExecutionFlowRuntime(ExecutionFlow executionFlow) { + this.executionFlow = executionFlow; + } + + public ExecutionFlow getExecutionFlow() { + return executionFlow; + } + + public Map getScopedObjects() { + return scopedObjects; + } + + public String getUuid() { + return uuid; + } + + public Map getLocalVariables() { + return localVariables; + } + + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFinishedEvent.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFinishedEvent.java new file mode 100644 index 000000000..7aacd50b6 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFinishedEvent.java @@ -0,0 +1,19 @@ +package org.argeo.slc.execution; + +import org.springframework.context.ApplicationEvent; + +public class ExecutionFinishedEvent extends ApplicationEvent { + static final long serialVersionUID = 012; + + private final ExecutionContext executionContext; + + public ExecutionFinishedEvent(Object source, ExecutionContext executionContext) { + super(source); + this.executionContext = executionContext; + } + + public ExecutionContext getExecutionContext() { + return executionContext; + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlow.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlow.java new file mode 100644 index 000000000..b0075bf25 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlow.java @@ -0,0 +1,11 @@ +package org.argeo.slc.execution; + +import java.util.Map; + +import org.argeo.slc.process.Executable; + +public interface ExecutionFlow extends Executable{ + public Object getParameter(String name); + public ExecutionSpec getExecutionSpec(); + public String getUuid(); +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlowFactory.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlowFactory.java new file mode 100644 index 000000000..8631ac74f --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionFlowFactory.java @@ -0,0 +1,25 @@ +package org.argeo.slc.execution; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.argeo.slc.process.Executable; + +public class ExecutionFlowFactory { + private List executables = new ArrayList(); + + + public ExecutionFlow createExecutionFlow(Map attributes){ + SimpleExecutionFlow executionFlow = new SimpleExecutionFlow(); + executionFlow.setExecutables(executables); + return executionFlow; + } + + + public void setExecutables(List executables) { + this.executables = executables; + } + + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionParameterPostProcessor.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionParameterPostProcessor.java new file mode 100644 index 000000000..3f741d9a7 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionParameterPostProcessor.java @@ -0,0 +1,120 @@ +package org.argeo.slc.execution; + +import java.beans.PropertyDescriptor; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.springframework.beans.BeansException; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.PropertyValues; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; +import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; +import org.springframework.beans.factory.config.TypedStringValue; + +public class ExecutionParameterPostProcessor extends + InstantiationAwareBeanPostProcessorAdapter { + private final static Log log = LogFactory + .getLog(ExecutionParameterPostProcessor.class); + + private String placeholderPrefix = "@{"; + private String placeholderSuffix = "}"; + private String nullValue; + + @Override + public PropertyValues postProcessPropertyValues(PropertyValues pvs, + PropertyDescriptor[] pds, Object bean, String beanName) + throws BeansException { + if (!ExecutionContext.isExecuting()) + return pvs; + +// ExecutionFlow currentFlow = ExecutionContext.getCurrentFlow(); +// +// Properties props = new Properties(); +// Map attributes = currentFlow.getAttributes(); +// Map specAttributes = currentFlow +// .getExecutionSpec().getAttributes(); +// +// for (String key : specAttributes.keySet()) { +// ExecutionSpecAttribute obj = specAttributes.get(key); +// if (!(obj instanceof RefSpecAttribute)) { +// if (!attributes.containsKey(key)) +// throw new SlcException("Specified attribute " + key +// + " is not set in " + currentFlow); +// +// props.setProperty(key, attributes.get(key).toString()); +// // if (log.isTraceEnabled()) +// // log.trace("Use attribute " + key); +// } +// } + + Properties props = new Properties(); + CustomPpc ppc = new CustomPpc(props); + + for (PropertyValue pv : pvs.getPropertyValues()) { + if (pv.getValue() instanceof TypedStringValue) { + TypedStringValue tsv = (TypedStringValue) pv.getValue(); + String originalValue = tsv.getValue(); + String convertedValue = ppc.process(originalValue); + tsv.setValue(convertedValue); + if (log.isTraceEnabled()) { + if (!originalValue.equals(convertedValue)) + log.trace("Converted field '" + pv.getName() + "': '" + + originalValue + "' to '" + convertedValue + + "' in bean " + beanName); + } + } else { + // if (log.isTraceEnabled()) + // log.trace(beanName + "[" + pv.getName() + "]: " + // + pv.getValue().getClass()); + } + } + + return pvs; + } + + public void setPlaceholderPrefix(String placeholderPrefix) { + this.placeholderPrefix = placeholderPrefix; + } + + public void setPlaceholderSuffix(String placeholderSuffix) { + this.placeholderSuffix = placeholderSuffix; + } + + public void setNullValue(String nullValue) { + this.nullValue = nullValue; + } + + private class CustomPpc extends PropertyPlaceholderConfigurer { + private final Properties props; + + public CustomPpc(Properties props) { + super(); + this.props = props; + setPlaceholderPrefix(placeholderPrefix); + setPlaceholderSuffix(placeholderSuffix); + setSystemPropertiesMode(SYSTEM_PROPERTIES_MODE_NEVER); + } + + public String process(String strVal) { + String value = parseStringValue(strVal, this.props, + new HashSet()); + return (value.equals(nullValue) ? null : value); + } + + @Override + protected String resolvePlaceholder(String placeholder, Properties props) { + if (ExecutionContext.isExecuting()) + return ExecutionContext.getVariable(placeholder).toString(); + else if (SimpleExecutionSpec.isInFlowInitialization()) + return SimpleExecutionSpec.getInitializingFlowParameter( + placeholder).toString(); + else + return super.resolvePlaceholder(placeholder, props); + } + + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionRegister.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionRegister.java new file mode 100644 index 000000000..c4f958e9f --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionRegister.java @@ -0,0 +1,47 @@ +package org.argeo.slc.execution; + +import java.util.Map; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; + +public class ExecutionRegister implements InitializingBean { + private final static Log log = LogFactory.getLog(ExecutionRegister.class); + + @Autowired + private Set executionFlows; + + @Autowired + private Set executionSpecs; + + public void afterPropertiesSet() throws Exception { + log.debug("Register: " + executionSpecs.size() + " specs"); + for (ExecutionSpec spec : executionSpecs) { + log.debug(spec); + Map attributes = spec + .getAttributes(); + log.debug("Spec attributes: "); + for (String key : attributes.keySet()) { + log.debug(" " + key + "\t" + attributes.get(key)); + } + } + + log.debug("Register: " + executionFlows.size() + " flows"); + for (ExecutionFlow flow : executionFlows) { + log.debug(flow); +// Map attributes = flow.getAttributes(); +// log.debug("Specified parameters: "); +// for (String key : flow.getExecutionSpec().getAttributes().keySet()) { +// log.debug(" " +// + key +// + "\t" +// + (attributes.containsKey(key) ? "SPECIFIED" +// : "TO SPECIFY")); +// } + } + + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionScope.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionScope.java new file mode 100644 index 000000000..0970ac853 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionScope.java @@ -0,0 +1,47 @@ +package org.argeo.slc.execution; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.config.Scope; + +public class ExecutionScope implements Scope { + private final static Log log = LogFactory.getLog(ExecutionScope.class); + + public Object get(String name, ObjectFactory objectFactory) { + + if (log.isTraceEnabled()) + log.trace("Getting scoped bean " + name); + return ExecutionContext.findOrAddScopedObject(name, objectFactory); + + // if (ExecutionContext.getScopedObjects().containsKey(name)) { + // // returns cached instance + // Object obj = ExecutionContext.getScopedObjects().get(name); + // if (log.isTraceEnabled()) + // log.trace("Return cached scoped object " + obj); + // return obj; + // } else { + // // creates instance + // Object obj = objectFactory.getObject(); + // ExecutionContext.getScopedObjects().put(name, obj); + // if (log.isTraceEnabled()) + // log.trace("Created regular scoped object " + obj); + // return obj; + // } + } + + public String getConversationId() { + return ExecutionContext.getCurrentStackUuid(); + } + + public void registerDestructionCallback(String name, Runnable callback) { + throw new UnsupportedOperationException(); + } + + public Object remove(String name) { + log.debug("Remove object " + name); + throw new UnsupportedOperationException(); + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpec.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpec.java new file mode 100644 index 000000000..24a3c83a2 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpec.java @@ -0,0 +1,7 @@ +package org.argeo.slc.execution; + +import java.util.Map; + +public interface ExecutionSpec { + public Map getAttributes(); +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java new file mode 100644 index 000000000..582cef99c --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java @@ -0,0 +1,6 @@ +package org.argeo.slc.execution; + +public interface ExecutionSpecAttribute { + public Object getValue(); + public Boolean getIsParameter(); +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionTargetSource.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionTargetSource.java new file mode 100644 index 000000000..422abeca7 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/ExecutionTargetSource.java @@ -0,0 +1,44 @@ +package org.argeo.slc.execution; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.aop.TargetSource; + +public class ExecutionTargetSource implements TargetSource { + private final static Log log = LogFactory + .getLog(ExecutionTargetSource.class); + + private final String name; + private final Class targetClass; + private final ExecutionFlow executionFlow; + + public ExecutionTargetSource(ExecutionFlow executionFlow, + Class targetClass, String name) { + this.executionFlow = executionFlow; + this.targetClass = targetClass; + this.name = name; + } + + public Object getTarget() throws Exception { + if (log.isTraceEnabled()) + log.trace("Getting object " + name); + Object obj = executionFlow.getParameter(name); + if (log.isTraceEnabled()) + log.trace("Target object " + obj); + return obj; + } + + public Class getTargetClass() { + return targetClass; + } + + public boolean isStatic() { + return false; + } + + public void releaseTarget(Object target) throws Exception { + // TODO Auto-generated method stub + + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/Executor.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/Executor.java new file mode 100644 index 000000000..a39480309 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/Executor.java @@ -0,0 +1,70 @@ +package org.argeo.slc.execution; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.process.SlcExecution; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; + +public class Executor implements ApplicationListener, ApplicationContextAware { + private final static Log log = LogFactory.getLog(Executor.class); + + private ApplicationContext applicationContext; + + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof NewExecutionEvent) { + SlcExecution slcExecution = ((NewExecutionEvent) event) + .getSlcExecution(); + ExecutionContext executionContext = new ExecutionContext(); + ExecutionThread thread = new ExecutionThread(executionContext, + slcExecution); + thread.start(); + } + + } + + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + } + + private class ExecutionThread extends Thread { + private final SlcExecution slcExecution; + private final ExecutionContext executionContext; + + public ExecutionThread(ExecutionContext executionContext, + SlcExecution slcExecution) { + super("SLC Execution #" + executionContext.getUuid()); + this.slcExecution = slcExecution; + this.executionContext = executionContext; + } + + public void run() { + // Initialize from SlcExecution + ExecutionContext.registerExecutionContext(executionContext); + ExecutionContext.getVariables() + .putAll(slcExecution.getAttributes()); + + try { + log.info("Start execution #" + + ExecutionContext.getExecutionUuid()); + String executionBean = slcExecution.getAttributes().get( + "slc.flows"); + ExecutionFlow main = (ExecutionFlow) applicationContext + .getBean(executionBean); + main.execute(); + } catch (Exception e) { + log.error("Execution " + executionContext.getUuid() + + " failed.", e); + } finally { + applicationContext.publishEvent(new ExecutionFinishedEvent( + this, executionContext)); + } + + } + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/InstantiationPostProcessor.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/InstantiationPostProcessor.java new file mode 100644 index 000000000..4873c56f7 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/InstantiationPostProcessor.java @@ -0,0 +1,29 @@ +package org.argeo.slc.execution; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; + +public class InstantiationPostProcessor extends + InstantiationAwareBeanPostProcessorAdapter { + private final static Log log = LogFactory + .getLog(InstantiationPostProcessor.class); + + @Override + public boolean postProcessAfterInstantiation(Object bean, String beanName) + throws BeansException { + if (bean instanceof ExecutionFlow) + SimpleExecutionSpec.flowInitializationStarted((ExecutionFlow) bean); + return true; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof ExecutionFlow) + SimpleExecutionSpec + .flowInitializationFinished((ExecutionFlow) bean); + return bean; + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/NewExecutionEvent.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/NewExecutionEvent.java new file mode 100644 index 000000000..ced38a848 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/NewExecutionEvent.java @@ -0,0 +1,20 @@ +package org.argeo.slc.execution; + +import org.argeo.slc.process.SlcExecution; +import org.springframework.context.ApplicationEvent; + +public class NewExecutionEvent extends ApplicationEvent { + static final long serialVersionUID = 012; + + private final SlcExecution slcExecution; + + public NewExecutionEvent(Object source, SlcExecution slcExecution) { + super(source); + this.slcExecution = slcExecution; + } + + public SlcExecution getSlcExecution() { + return slcExecution; + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/RefSpecAttribute.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/RefSpecAttribute.java new file mode 100644 index 000000000..9b0ea6d3c --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/RefSpecAttribute.java @@ -0,0 +1,23 @@ +package org.argeo.slc.execution; + +public class RefSpecAttribute extends AbstractSpecAttribute { + private Class targetClass; + private Object value = null; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public Class getTargetClass() { + return targetClass; + } + + public void setTargetClass(Class targetClass) { + this.targetClass = targetClass; + } + +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionFlow.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionFlow.java new file mode 100644 index 000000000..34018ee9b --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionFlow.java @@ -0,0 +1,114 @@ +package org.argeo.slc.execution; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.lang.math.RandomUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.process.Executable; +import org.argeo.slc.test.ExecutableTestRun; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.validation.MapBindingResult; + +public class SimpleExecutionFlow implements ExecutionFlow, InitializingBean, + BeanNameAware { + private ExecutionSpec executionSpec = new SimpleExecutionSpec(); + private String name = null; + private Map parameters = new HashMap(); + private List executables = new ArrayList(); + + private final String uuid = UUID.randomUUID().toString(); + + public void execute() { + for (Executable executable : executables) { + executable.execute(); + } + } + + public void afterPropertiesSet() throws Exception { + // Validate execution specs + if (executionSpec == null) + return; + + MapBindingResult errors = new MapBindingResult(parameters, "execution#" + + getUuid()); + for (String key : executionSpec.getAttributes().keySet()) { + ExecutionSpecAttribute executionSpecAttr = executionSpec + .getAttributes().get(key); + if (!parameters.containsKey(key)) { + Object defaultValue = executionSpecAttr.getValue(); + if (defaultValue == null) + errors.rejectValue(key, "Not set and no default value"); + else + parameters.put(key, defaultValue); + } else {// contains key + Object obj = parameters.get(key); + if (executionSpecAttr instanceof RefSpecAttribute) { + RefSpecAttribute rsa = (RefSpecAttribute) executionSpecAttr; + Class targetClass = rsa.getTargetClass(); + if (!targetClass.isAssignableFrom(obj.getClass())) { + errors.reject(key + + " not compatible with target class " + + targetClass); + } + } + } + } + + if (errors.hasErrors()) + throw new SlcException("Could not prepare execution flow: " + + errors.toString()); + } + + public void setBeanName(String name) { + this.name = name; + } + + public void setExecutables(List executables) { + this.executables = executables; + } + + public void setExecutionSpec(ExecutionSpec executionSpec) { + this.executionSpec = executionSpec; + } + + public void setParameters(Map attributes) { + this.parameters = attributes; + } + + public String getUuid() { + return uuid; + } + + public ExecutionSpec getExecutionSpec() { + return executionSpec; + } + + public Object getParameter(String name) { + if (parameters.containsKey(name)) { + return parameters.get(name); + } else { + if (executionSpec.getAttributes().containsKey(name)) { + ExecutionSpecAttribute esa = executionSpec.getAttributes().get( + name); + if (esa.getValue() != null) + return esa.getValue(); + } else { + throw new SlcException("Key " + name + + " is not define in the specifications of " + + toString()); + } + } + throw new SlcException("Key " + name + " is not set as parameter in " + + toString()); + } + + public String toString() { + return new StringBuffer("Flow ").append(name).toString();// .append(" [#") + // .append(uuid).append(']').toString(); + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionSpec.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionSpec.java new file mode 100644 index 000000000..8d460ff2c --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleExecutionSpec.java @@ -0,0 +1,74 @@ +package org.argeo.slc.execution; + +import java.util.HashMap; +import java.util.Map; + +import org.argeo.slc.SlcException; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.factory.BeanNameAware; + +public class SimpleExecutionSpec implements ExecutionSpec, BeanNameAware { + private final static ThreadLocal initializingFlow = new ThreadLocal(); + + private Map attributes = new HashMap(); + + private String name = null; + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + public Object createRef(String name) { + ExecutionFlow flow = initializingFlow.get(); + if (flow == null) + throw new SlcException("No flow is currently initializing." + + " Declare flow refs as inner beans or prototypes."); + + RefSpecAttribute refSpecAttribute = (RefSpecAttribute) attributes + .get(name); + Class targetClass = refSpecAttribute.getTargetClass(); + ExecutionTargetSource targetSource = new ExecutionTargetSource(flow, + targetClass, name); + ProxyFactory proxyFactory = new ProxyFactory(); + proxyFactory.setTargetClass(targetClass); + proxyFactory.setProxyTargetClass(true); + proxyFactory.setTargetSource(targetSource); + + return proxyFactory.getProxy(); + } + + public void setBeanName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static void flowInitializationStarted(ExecutionFlow flow) { + initializingFlow.set(flow); + } + + public static void flowInitializationFinished(ExecutionFlow flow) { + ExecutionFlow registeredFlow = initializingFlow.get(); + if (registeredFlow == null) + throw new SlcException("No flow registered"); + if (!flow.getUuid().equals(registeredFlow.getUuid())) + throw new SlcException("Current flow is " + flow); + initializingFlow.set(null); + } + + public static Object getInitializingFlowParameter(String key) { + if (initializingFlow.get() == null) + throw new SlcException("No initializing flow available."); + return initializingFlow.get().getParameter(key); + } + + public static Boolean isInFlowInitialization() { + return initializingFlow.get() != null; + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleSpecAttribute.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleSpecAttribute.java new file mode 100644 index 000000000..75019cb8a --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/SimpleSpecAttribute.java @@ -0,0 +1,13 @@ +package org.argeo.slc.execution; + +public class SimpleSpecAttribute extends AbstractSpecAttribute { + private Object value = null; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } +} diff --git a/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/tasks/Echo.java b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/tasks/Echo.java new file mode 100644 index 000000000..e904153e7 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/main/java/org/argeo/slc/execution/tasks/Echo.java @@ -0,0 +1,29 @@ +package org.argeo.slc.execution.tasks; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.process.Executable; + +public class Echo implements Executable { + private final static Log defaultLog = LogFactory.getLog(Echo.class); + + private Log log; + private String message; + + public void execute() { + log().info(message); + } + + protected Log log() { + return log != null ? log : defaultLog; + } + + public void setLog(Log log) { + this.log = log; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/BasicExecutionFlow.groovy b/runtime/org.argeo.slc.execution/src/slc/conf/BasicExecutionFlow.groovy new file mode 100644 index 000000000..da3926ef8 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/BasicExecutionFlow.groovy @@ -0,0 +1,12 @@ +import org.argeo.slc.test.*; + +public class BasicExecutionFlow implements org.argeo.slc.executionflow.ExecutionFlow { + + ExecutableTestRun firstSubTest = null; + ExecutableTestRun secondSubTest = null; + + void execute(){ + firstSubTest?.execute(); + secondSubTest?.execute(); + } +} diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/basic.xml b/runtime/org.argeo.slc.execution/src/slc/conf/basic.xml new file mode 100644 index 000000000..5e1c46e4f --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/basic.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/common.xml b/runtime/org.argeo.slc.execution/src/slc/conf/common.xml new file mode 100644 index 000000000..4495b2f83 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/common.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/main.xml b/runtime/org.argeo.slc.execution/src/slc/conf/main.xml new file mode 100644 index 000000000..829e6ee5b --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/main.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/slc.properties b/runtime/org.argeo.slc.execution/src/slc/conf/slc.properties new file mode 100644 index 000000000..b18dce171 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/slc.properties @@ -0,0 +1,16 @@ +log4j.rootLogger=WARN, console + +## Levels +log4j.logger.org.argeo=DEBUG +log4j.logger.org.argeo.slc.executionflow.ExecutionParameterPostProcessor=TRACE +log4j.logger.org.argeo.slc.executionflow.ExecutionContext=TRACE + +## Appenders +# console is set to be a ConsoleAppender. +log4j.appender.console=org.apache.log4j.ConsoleAppender + +# console uses PatternLayout. +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n + +testCase=002 \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/test.xml b/runtime/org.argeo.slc.execution/src/slc/conf/test.xml new file mode 100644 index 000000000..6cc40e80e --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/test.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-001.xml b/runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-001.xml new file mode 100644 index 000000000..0131cc273 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-001.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-002.xml b/runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-002.xml new file mode 100644 index 000000000..fc52a03f1 --- /dev/null +++ b/runtime/org.argeo.slc.execution/src/slc/conf/testCases/basic-002.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- 2.39.2