From 1535eecc68ecbda4e67e158de6bcecd074db2545 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 2 Jul 2009 16:43:16 +0000 Subject: [PATCH] Implement ref spec git-svn-id: https://svn.argeo.org/slc/trunk@2673 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../AbstractExecutionModulesManager.java | 202 +++++++----------- .../execution/DefaultDescriptorConverter.java | 41 ---- ...faultExecutionFlowDescriptorConverter.java | 171 +++++++++++++++ .../core/execution/DefaultExecutionSpec.java | 71 +++++- .../slc/core/execution/RefSpecAttribute.java | 24 ++- .../argeo/slc/core/execution/RefValue.java | 15 +- .../slc/core/execution/RefValueChoice.java | 31 +++ .../execution/internal/ExecutionThread.java | 66 ++++++ .../execution/internal/ProcessThread.java | 85 ++++++++ .../org/argeo/slc/core/execution/spring.xml | 3 + .../org/argeo/slc/deploy/DynamicRuntime.java | 1 - .../slc/deploy/ModularDeployedSystem.java | 1 - .../argeo/slc/deploy/ModuleDescriptor.java | 28 +++ .../org/argeo/slc/deploy/ModulesManager.java | 15 ++ .../execution/ExecutionFlowDescriptor.java | 9 + .../ExecutionFlowDescriptorConverter.java | 3 + .../execution/ExecutionModuleDescriptor.java | 25 +-- .../execution/ExecutionModulesManager.java | 3 +- .../argeo/slc/execution/ExecutionSpec.java | 2 + .../org/argeo/slc/castor/execution.xml | 19 +- .../ExecutionModuleDescriptorCastorTest.java | 5 +- .../slc/osgi/OsgiExecutionModulesManager.java | 98 +++++++-- .../org/argeo/slc/osgi/execution/spring.xml | 2 + .../ExecutionFlowDescriptorTestUtils.java | 13 +- 24 files changed, 709 insertions(+), 224 deletions(-) delete mode 100644 runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java create mode 100644 runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java create mode 100644 runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java create mode 100644 runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java create mode 100644 runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java create mode 100644 runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java create mode 100644 runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java index 4722280d9..5fa0d015f 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java @@ -1,39 +1,22 @@ package org.argeo.slc.core.execution; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.slc.SlcException; -import org.argeo.slc.execution.ExecutionFlow; -import org.argeo.slc.execution.ExecutionFlowDescriptor; -import org.argeo.slc.execution.ExecutionModuleDescriptor; + +import org.argeo.slc.core.execution.internal.ProcessThread; import org.argeo.slc.execution.ExecutionModulesManager; -import org.argeo.slc.execution.ExecutionSpec; -import org.argeo.slc.execution.ExecutionSpecAttribute; -import org.argeo.slc.process.RealizedFlow; import org.argeo.slc.process.SlcExecution; import org.argeo.slc.process.SlcExecutionNotifier; -import org.argeo.slc.process.SlcExecutionStep; -import org.springframework.aop.scope.ScopedObject; -import org.springframework.util.Assert; public abstract class AbstractExecutionModulesManager implements ExecutionModulesManager { - private final static Log log = LogFactory - .getLog(AbstractExecutionModulesManager.class); - private List slcExecutionNotifiers = new ArrayList(); private ThreadGroup processesThreadGroup = new ThreadGroup("Processes"); public void process(SlcExecution slcExecution) { - new ProcessThread(processesThreadGroup, slcExecution).start(); + new ProcessThread(this, slcExecution).start(); } - +/* protected void dispatchUpdateStatus(SlcExecution slcExecution, String oldStatus, String newStatus) { for (Iterator it = slcExecutionNotifiers @@ -51,21 +34,16 @@ public abstract class AbstractExecutionModulesManager implements .iterator(); it.hasNext();) { it.next().addSteps(slcExecution, steps); } - } + }*/ public void setSlcExecutionNotifiers( List slcExecutionNotifiers) { this.slcExecutionNotifiers = slcExecutionNotifiers; } - - protected static ExecutionModuleDescriptor createDescriptor( - String moduleName, String moduleVersion, +/* + protected static void addFlowsToDescriptor(ExecutionModuleDescriptor md, Map executionFlows) { // TODO: put this in a separate configurable object - ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); - md.setName(moduleName); - md.setVersion(moduleVersion); - for (String name : executionFlows.keySet()) { ExecutionFlow executionFlow = executionFlows.get(name); @@ -120,103 +98,81 @@ public abstract class AbstractExecutionModulesManager implements // Add execution flow md.getExecutionFlows().add(efd); } - - return md; } - - /** Thread of the SLC Process, starting the sub executions. */ - private class ProcessThread extends Thread { - private final SlcExecution slcProcess; - private final ThreadGroup processThreadGroup; - private final List flowsToProcess = new ArrayList(); - - public ProcessThread(ThreadGroup processesThreadGroup, - SlcExecution slcExecution) { - super(processesThreadGroup, "SLC Process #" - + slcExecution.getUuid()); - this.slcProcess = slcExecution; - processThreadGroup = new ThreadGroup("SLC Process #" - + slcExecution.getUuid() + " thread group"); - } - - public void run() { - log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n"); - - slcProcess.setStatus(SlcExecution.STATUS_RUNNING); - dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED, - SlcExecution.STATUS_RUNNING); - - flowsToProcess.addAll(slcProcess.getRealizedFlows()); - - while (flowsToProcess.size() > 0) { - RealizedFlow flow = flowsToProcess.remove(0); - ExecutionThread thread = new ExecutionThread(this, flow); - thread.start(); - - synchronized (this) { - try { - wait(); - } catch (InterruptedException e) { - // silent - } - } - } - - slcProcess.setStatus(SlcExecution.STATUS_FINISHED); - dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING, - SlcExecution.STATUS_FINISHED); - } - - public synchronized void flowCompleted() { - notifyAll(); - } - - public SlcExecution getSlcProcess() { - return slcProcess; - } - - public ThreadGroup getProcessThreadGroup() { - return processThreadGroup; - } +*/ + /** + * Thread of the SLC Process, starting the sub executions. private class + * ProcessThread extends Thread { private final SlcExecution slcProcess; + * private final ThreadGroup processThreadGroup; private final + * List flowsToProcess = new ArrayList(); + * + * public ProcessThread(ThreadGroup processesThreadGroup, SlcExecution + * slcExecution) { super(processesThreadGroup, "SLC Process #" + + * slcExecution.getUuid()); this.slcProcess = slcExecution; + * processThreadGroup = new ThreadGroup("SLC Process #" + + * slcExecution.getUuid() + " thread group"); } + * + * public void run() { log.info("\n##\n## Process SLC Execution " + + * slcProcess + "\n##\n"); + * + * slcProcess.setStatus(SlcExecution.STATUS_RUNNING); + * dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED, + * SlcExecution.STATUS_RUNNING); + * + * flowsToProcess.addAll(slcProcess.getRealizedFlows()); + * + * while (flowsToProcess.size() > 0) { RealizedFlow flow = + * flowsToProcess.remove(0); ExecutionThread thread = new + * ExecutionThread(this, flow); thread.start(); + * + * synchronized (this) { try { wait(); } catch (InterruptedException e) { // + * silent } } } + * + * slcProcess.setStatus(SlcExecution.STATUS_FINISHED); + * dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING, + * SlcExecution.STATUS_FINISHED); } + * + * public synchronized void flowCompleted() { notifyAll(); } + * + * public SlcExecution getSlcProcess() { return slcProcess; } + * + * public ThreadGroup getProcessThreadGroup() { return processThreadGroup; } + * } + */ + + /** + * Thread of a single execution private class ExecutionThread extends Thread + * { private final RealizedFlow realizedFlow; private final ProcessThread + * processThread; + * + * public ExecutionThread(ProcessThread processThread, RealizedFlow + * realizedFlow) { super(processThread.getProcessThreadGroup(), "Flow " + + * realizedFlow.getFlowDescriptor().getName()); this.realizedFlow = + * realizedFlow; this.processThread = processThread; } + * + * public void run() { ExecutionFlowDescriptor executionFlowDescriptor = + * realizedFlow .getFlowDescriptor(); String flowName = + * executionFlowDescriptor.getName(); + * + * dispatchAddStep(processThread.getSlcProcess(), new + * SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START, "Flow " + flowName)); + * + * try { execute(realizedFlow); } catch (Exception e) { // TODO: re-throw + * exception ? String msg = "Execution of flow " + flowName + " failed."; + * log.error(msg, e); dispatchAddStep(processThread.getSlcProcess(), new + * SlcExecutionStep(msg + " " + e.getMessage())); } finally { + * processThread.flowCompleted(); + * dispatchAddStep(processThread.getSlcProcess(), new + * SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END, "Flow " + flowName)); } + * } } + */ + + public List getSlcExecutionNotifiers() { + return slcExecutionNotifiers; } - /** Thread of a single execution */ - private class ExecutionThread extends Thread { - private final RealizedFlow realizedFlow; - private final ProcessThread processThread; - - public ExecutionThread(ProcessThread processThread, - RealizedFlow realizedFlow) { - super(processThread.getProcessThreadGroup(), "Flow " - + realizedFlow.getFlowDescriptor().getName()); - this.realizedFlow = realizedFlow; - this.processThread = processThread; - } - - public void run() { - ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow - .getFlowDescriptor(); - String flowName = executionFlowDescriptor.getName(); - - dispatchAddStep(processThread.getSlcProcess(), - new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START, - "Flow " + flowName)); - - try { - execute(realizedFlow); - } catch (Exception e) { - // TODO: re-throw exception ? - String msg = "Execution of flow " + flowName + " failed."; - log.error(msg, e); - dispatchAddStep(processThread.getSlcProcess(), - new SlcExecutionStep(msg + " " + e.getMessage())); - } finally { - processThread.flowCompleted(); - dispatchAddStep(processThread.getSlcProcess(), - new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END, - "Flow " + flowName)); - } - } + public ThreadGroup getProcessesThreadGroup() { + return processesThreadGroup; } } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java deleted file mode 100644 index 2ae1e3639..000000000 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.argeo.slc.core.execution; - -import java.util.HashMap; -import java.util.Map; - -import org.argeo.slc.execution.ExecutionFlowDescriptor; -import org.argeo.slc.execution.ExecutionFlowDescriptorConverter; - -public class DefaultDescriptorConverter implements - ExecutionFlowDescriptorConverter { - - public Map convertValues( - ExecutionFlowDescriptor executionFlowDescriptor) { - // convert the values of flow.getFlowDescriptor() - Map values = executionFlowDescriptor.getValues(); - - Map convertedValues = new HashMap(); - - if (values != null) { - for (String key : values.keySet()) { - Object value = values.get(key); - if (value instanceof PrimitiveValue) { - PrimitiveValue primitiveValue = (PrimitiveValue) value; - - // TODO: check that the class of the the - // primitiveValue.value - // matches - // the primitiveValue.type - convertedValues.put(key, primitiveValue.getValue()); - } else if (value instanceof RefValue) { - // not yet implemented - -// RefValue refValue = (RefValue) value; -// convertedValues.put(key, refValue.getLabel()); - } - } - } - return convertedValues; - } - -} diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java new file mode 100644 index 000000000..2b540f3c8 --- /dev/null +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java @@ -0,0 +1,171 @@ +package org.argeo.slc.core.execution; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.execution.ExecutionFlow; +import org.argeo.slc.execution.ExecutionFlowDescriptor; +import org.argeo.slc.execution.ExecutionFlowDescriptorConverter; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.execution.ExecutionSpec; +import org.argeo.slc.execution.ExecutionSpecAttribute; +import org.springframework.aop.scope.ScopedObject; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.util.Assert; + +public class DefaultExecutionFlowDescriptorConverter implements + ExecutionFlowDescriptorConverter, ApplicationContextAware { + private final static Log log = LogFactory + .getLog(DefaultExecutionFlowDescriptorConverter.class); + + private ApplicationContext applicationContext; + + public Map convertValues( + ExecutionFlowDescriptor executionFlowDescriptor) { + // convert the values of flow.getFlowDescriptor() + Map values = executionFlowDescriptor.getValues(); + + Map convertedValues = new HashMap(); + + if (values != null) { + for (String key : values.keySet()) { + Object value = values.get(key); + if (value instanceof PrimitiveValue) { + PrimitiveValue primitiveValue = (PrimitiveValue) value; + + // TODO: check that the class of the the + // primitiveValue.value + // matches + // the primitiveValue.type + convertedValues.put(key, primitiveValue.getValue()); + } else if (value instanceof RefValue) { + // not yet implemented + + // RefValue refValue = (RefValue) value; + // convertedValues.put(key, refValue.getLabel()); + } + } + } + return convertedValues; + } + + public void addFlowsToDescriptor(ExecutionModuleDescriptor md, + Map executionFlows) { + for (String name : executionFlows.keySet()) { + ExecutionFlow executionFlow = executionFlows.get(name); + + Assert.notNull(executionFlow.getName()); + Assert.state(name.equals(executionFlow.getName())); + + ExecutionSpec executionSpec = executionFlow.getExecutionSpec(); + Assert.notNull(executionSpec); + Assert.notNull(executionSpec.getName()); + + Map values = new TreeMap(); + for (String key : executionSpec.getAttributes().keySet()) { + ExecutionSpecAttribute attribute = executionSpec + .getAttributes().get(key); + + if (attribute instanceof PrimitiveSpecAttribute) { + if (executionFlow.isSetAsParameter(key)) { + Object value = executionFlow.getParameter(key); + PrimitiveValue primitiveValue = new PrimitiveValue(); + primitiveValue + .setType(((PrimitiveSpecAttribute) attribute) + .getType()); + primitiveValue.setValue(value); + values.put(key, primitiveValue); + } else { + // no need to add a primitive value if it is not set, + // all necessary information is in the spec + } + } else if (attribute instanceof RefSpecAttribute) { + values.put(key, buildRefValue((RefSpecAttribute) attribute, + executionFlow, key)); + } else { + throw new SlcException("Unkown spec attribute type " + + attribute.getClass()); + } + + } + + ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, + values, executionSpec); + if (executionFlow.getPath() != null) + efd.setPath(executionFlow.getPath()); + + // Add execution spec if necessary + if (!md.getExecutionSpecs().contains(executionSpec)) + md.getExecutionSpecs().add(executionSpec); + + // Add execution flow + md.getExecutionFlows().add(efd); + } + } + + @SuppressWarnings(value = { "unchecked" }) + protected RefValue buildRefValue(RefSpecAttribute rsa, + ExecutionFlow executionFlow, String key) { + RefValue refValue = new RefValue(); + + if (executionFlow.isSetAsParameter(key)) { + String ref = null; + Object value = executionFlow.getParameter(key); + if (applicationContext == null) { + log + .warn("No application context declared, cannot scan ref value."); + ref = value.toString(); + } else { + + // look for a ref to the value + Map beans = getBeanFactory().getBeansOfType( + rsa.getTargetClass(), false, false); + // TODO: also check scoped beans + beans: for (String beanName : beans.keySet()) { + Object obj = beans.get(beanName); + if (value instanceof ScopedObject) { + // don't call methods of the target of the scope + if (obj instanceof ScopedObject) + if (value == obj) { + ref = beanName; + break beans; + } + } else { + if (obj.equals(value)) { + ref = beanName; + break beans; + } + } + } + } + if (ref == null) + log.warn("Cannot define reference for ref spec attribute " + + key); + refValue.setRef(ref); + } + return refValue; + } + + private ConfigurableListableBeanFactory getBeanFactory() { + return ((ConfigurableApplicationContext) applicationContext) + .getBeanFactory(); + } + + /** Must be use within the execution application context */ + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + } + +} diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionSpec.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionSpec.java index bd4273958..af0afc416 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionSpec.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionSpec.java @@ -1,14 +1,31 @@ package org.argeo.slc.core.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.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.slc.execution.ExecutionSpec; import org.argeo.slc.execution.ExecutionSpecAttribute; import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ConfigurableApplicationContext; -public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware { +public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware, + ApplicationContextAware, InitializingBean { + private final static Log log = LogFactory + .getLog(DefaultExecutionSpec.class); + private ApplicationContext applicationContext; + + private String description; private Map attributes = new HashMap(); private String name = getClass().getName() + "#" + UUID.randomUUID(); @@ -33,4 +50,56 @@ public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware { return ((ExecutionSpec) obj).getName().equals(name); } + public String getDescription() { + return description; + } + + private ConfigurableListableBeanFactory getBeanFactory() { + return ((ConfigurableApplicationContext) applicationContext) + .getBeanFactory(); + } + + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + public void afterPropertiesSet() throws Exception { + if (description == null) { + try { + description = getBeanFactory().getBeanDefinition(name) + .getDescription(); + } catch (NoSuchBeanDefinitionException e) { + // silent + } + } + + for (String key : attributes.keySet()) { + ExecutionSpecAttribute attr = attributes.get(key); + if (attr instanceof RefSpecAttribute) { + RefSpecAttribute rsa = (RefSpecAttribute) attr; + if (rsa.getChoices() == null) { + rsa.setChoices(buildRefValueChoices(rsa)); + } + } + } + } + + protected List buildRefValueChoices(RefSpecAttribute rsa) { + List choices = new ArrayList(); + if (applicationContext == null) { + log.warn("No application context declared," + + " cannot scan ref value choices."); + return choices; + } + + for (String beanName : getBeanFactory().getBeanNamesForType( + rsa.getTargetClass(), true, false)) { + BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName); + RefValueChoice choice = new RefValueChoice(); + choice.setName(beanName); + choice.setDescription(bd.getDescription()); + } + return choices; + } + } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefSpecAttribute.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefSpecAttribute.java index 7cc59f1b9..eebb66040 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefSpecAttribute.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefSpecAttribute.java @@ -1,11 +1,16 @@ package org.argeo.slc.core.execution; -public class RefSpecAttribute extends AbstractSpecAttribute { +import java.util.List; + +public class RefSpecAttribute extends AbstractSpecAttribute implements + Cloneable { private Class targetClass; /** Read only. */ private String targetClassName; private Object value = null; + private List choices = null; + public Object getValue() { return value; } @@ -27,4 +32,21 @@ public class RefSpecAttribute extends AbstractSpecAttribute { return targetClassName; } + /** @return can be null */ + public List getChoices() { + return choices; + } + + public void setChoices(List choices) { + this.choices = choices; + } + + @Override + protected Object clone() throws CloneNotSupportedException { + RefSpecAttribute rsa = new RefSpecAttribute(); + rsa.setTargetClass(targetClass); + rsa.setChoices(choices); + return rsa; + } + } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValue.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValue.java index 516a15e3b..61abcb849 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValue.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValue.java @@ -1,22 +1,23 @@ package org.argeo.slc.core.execution; + public class RefValue extends AbstractExecutionValue { - private String label; + private String ref; public RefValue() { } - public RefValue(String label) { + public RefValue(String ref) { super(); - this.label = label; + this.ref = ref; } - public String getLabel() { - return label; + public String getRef() { + return ref; } - public void setLabel(String label) { - this.label = label; + public void setRef(String ref) { + this.ref = ref; } } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java new file mode 100644 index 000000000..6803a8478 --- /dev/null +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java @@ -0,0 +1,31 @@ +package org.argeo.slc.core.execution; + +public class RefValueChoice { + private String name; + private String description; + + public RefValueChoice() { + } + + public RefValueChoice(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java new file mode 100644 index 000000000..043f74bc7 --- /dev/null +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java @@ -0,0 +1,66 @@ +package org.argeo.slc.core.execution.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.execution.ExecutionFlowDescriptor; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.process.SlcExecutionNotifier; +import org.argeo.slc.process.SlcExecutionStep; + +/** Thread of a single execution */ +public class ExecutionThread extends Thread { + private final static Log log = LogFactory.getLog(ExecutionThread.class); + + private final RealizedFlow realizedFlow; + private final ProcessThread processThread; + + public ExecutionThread(ProcessThread processThread, + RealizedFlow realizedFlow) { + super(processThread.getProcessThreadGroup(), "Flow " + + realizedFlow.getFlowDescriptor().getName()); + this.realizedFlow = realizedFlow; + this.processThread = processThread; + } + + public void run() { + ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow + .getFlowDescriptor(); + String flowName = executionFlowDescriptor.getName(); + + dispatchAddStep(processThread.getSlcProcess(), new SlcExecutionStep( + SlcExecutionStep.TYPE_PHASE_START, "Flow " + flowName)); + + try { + processThread.getExecutionModulesManager().execute(realizedFlow); + } catch (Exception e) { + // TODO: re-throw exception ? + String msg = "Execution of flow " + flowName + " failed."; + log.error(msg, e); + dispatchAddStep(processThread.getSlcProcess(), + new SlcExecutionStep(msg + " " + e.getMessage())); + } finally { + processThread.flowCompleted(); + dispatchAddStep(processThread.getSlcProcess(), + new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END, + "Flow " + flowName)); + } + } + + protected void dispatchAddStep(SlcExecution slcExecution, + SlcExecutionStep step) { + slcExecution.getSteps().add(step); + List steps = new ArrayList(); + steps.add(step); + for (Iterator it = processThread + .getExecutionModulesManager().getSlcExecutionNotifiers() + .iterator(); it.hasNext();) { + it.next().addSteps(slcExecution, steps); + } + } + +} diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java new file mode 100644 index 000000000..0bfca64fc --- /dev/null +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java @@ -0,0 +1,85 @@ +package org.argeo.slc.core.execution.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.core.execution.AbstractExecutionModulesManager; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.process.SlcExecutionNotifier; + +/** Thread of the SLC Process, starting the sub executions. */ +public class ProcessThread extends Thread { + private final static Log log = LogFactory.getLog(ProcessThread.class); + + private final AbstractExecutionModulesManager executionModulesManager; + private final SlcExecution slcProcess; + private final ThreadGroup processThreadGroup; + private final List flowsToProcess = new ArrayList(); + + public ProcessThread( + AbstractExecutionModulesManager executionModulesManager, + SlcExecution slcExecution) { + super(executionModulesManager.getProcessesThreadGroup(), + "SLC Process #" + slcExecution.getUuid()); + this.executionModulesManager = executionModulesManager; + this.slcProcess = slcExecution; + processThreadGroup = new ThreadGroup("SLC Process #" + + slcExecution.getUuid() + " thread group"); + } + + public void run() { + log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n"); + + slcProcess.setStatus(SlcExecution.STATUS_RUNNING); + dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED, + SlcExecution.STATUS_RUNNING); + + flowsToProcess.addAll(slcProcess.getRealizedFlows()); + + while (flowsToProcess.size() > 0) { + RealizedFlow flow = flowsToProcess.remove(0); + ExecutionThread thread = new ExecutionThread(this, flow); + thread.start(); + + synchronized (this) { + try { + wait(); + } catch (InterruptedException e) { + // silent + } + } + } + + slcProcess.setStatus(SlcExecution.STATUS_FINISHED); + dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING, + SlcExecution.STATUS_FINISHED); + } + + protected void dispatchUpdateStatus(SlcExecution slcExecution, + String oldStatus, String newStatus) { + for (Iterator it = executionModulesManager + .getSlcExecutionNotifiers().iterator(); it.hasNext();) { + it.next().updateStatus(slcExecution, oldStatus, newStatus); + } + } + + public synchronized void flowCompleted() { + notifyAll(); + } + + public SlcExecution getSlcProcess() { + return slcProcess; + } + + public ThreadGroup getProcessThreadGroup() { + return processThreadGroup; + } + + public AbstractExecutionModulesManager getExecutionModulesManager() { + return executionModulesManager; + } +} diff --git a/runtime/org.argeo.slc.core/src/main/resources/org/argeo/slc/core/execution/spring.xml b/runtime/org.argeo.slc.core/src/main/resources/org/argeo/slc/core/execution/spring.xml index 6548f8a3c..3188e58fd 100644 --- a/runtime/org.argeo.slc.core/src/main/resources/org/argeo/slc/core/execution/spring.xml +++ b/runtime/org.argeo.slc.core/src/main/resources/org/argeo/slc/core/execution/spring.xml @@ -21,6 +21,9 @@ + + diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/DynamicRuntime.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/DynamicRuntime.java index 16d727a2c..e2552732a 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/DynamicRuntime.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/DynamicRuntime.java @@ -1,6 +1,5 @@ package org.argeo.slc.deploy; -@SuppressWarnings("unchecked") public interface DynamicRuntime extends ModularDeployedSystem { public void shutdown(); diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModularDeployedSystem.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModularDeployedSystem.java index 177fac83d..18fd4fe6d 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModularDeployedSystem.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModularDeployedSystem.java @@ -2,7 +2,6 @@ package org.argeo.slc.deploy; import java.util.List; -@SuppressWarnings("unchecked") public interface ModularDeployedSystem extends DeployedSystem { /** List the underlying deployed modules (in real time) */ public List listModules(); diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java new file mode 100644 index 000000000..a3a101f1e --- /dev/null +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java @@ -0,0 +1,28 @@ +package org.argeo.slc.deploy; + +import java.io.Serializable; + +import org.argeo.slc.build.BasicNameVersion; + +public class ModuleDescriptor extends BasicNameVersion implements Serializable { + private static final long serialVersionUID = 1L; + private String label; + private String description; + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java new file mode 100644 index 000000000..93d325f5f --- /dev/null +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java @@ -0,0 +1,15 @@ +package org.argeo.slc.deploy; + +import java.util.List; + +/** Provides access to modules */ +public interface ModulesManager { + /** @return a full fledged module descriptor. */ + public ModuleDescriptor getModuleDescriptor(String moduleName, + String version); + + /** + * @return a list of minimal module descriptors + */ + public List listModules(); +} diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptor.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptor.java index aeacfca18..f63703c88 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptor.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptor.java @@ -4,6 +4,7 @@ import java.util.Map; public class ExecutionFlowDescriptor { private String name; + private String description; private String path; private Map values; private ExecutionSpec executionSpec; @@ -50,4 +51,12 @@ public class ExecutionFlowDescriptor { this.executionSpec = executionSpec; } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java index 511d9da9b..b33c94cde 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java @@ -5,4 +5,7 @@ import java.util.Map; public interface ExecutionFlowDescriptorConverter { public Map convertValues( ExecutionFlowDescriptor executionFlowDescriptor); + + public void addFlowsToDescriptor(ExecutionModuleDescriptor md, + Map executionFlows); } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModuleDescriptor.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModuleDescriptor.java index 555ef40d7..3aa28e690 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModuleDescriptor.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModuleDescriptor.java @@ -1,15 +1,13 @@ package org.argeo.slc.execution; -import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import org.argeo.slc.SlcException; +import org.argeo.slc.deploy.ModuleDescriptor; -public class ExecutionModuleDescriptor implements Serializable { +public class ExecutionModuleDescriptor extends ModuleDescriptor { private static final long serialVersionUID = 1L; - private String name; - private String version; + private List executionSpecs = new ArrayList(); private List executionFlows = new ArrayList(); @@ -28,21 +26,4 @@ public class ExecutionModuleDescriptor implements Serializable { public void setExecutionFlows(List executionFlows) { this.executionFlows = executionFlows; } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java index 66ddc9cf4..f1155cc8e 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java @@ -2,11 +2,12 @@ package org.argeo.slc.execution; import java.util.List; +import org.argeo.slc.deploy.ModulesManager; import org.argeo.slc.process.RealizedFlow; import org.argeo.slc.process.SlcExecution; /** Provides access to the execution modules */ -public interface ExecutionModulesManager { +public interface ExecutionModulesManager extends ModulesManager { /** @return a full fledged module descriptor. */ public ExecutionModuleDescriptor getExecutionModuleDescriptor( String moduleName, String version); diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpec.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpec.java index 60924768b..c2c61daaf 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpec.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpec.java @@ -6,4 +6,6 @@ public interface ExecutionSpec { public Map getAttributes(); public String getName(); + + public String getDescription(); } diff --git a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/execution.xml b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/execution.xml index 7e903d26f..2fdfb7e4a 100644 --- a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/execution.xml +++ b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/execution.xml @@ -10,6 +10,8 @@ ns-prefix="slc" /> + + @@ -107,6 +109,10 @@ + + + @@ -131,6 +137,17 @@ - + + + + + + + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.castor/src/test/java/org/argeo/slc/castor/ExecutionModuleDescriptorCastorTest.java b/runtime/org.argeo.slc.support.castor/src/test/java/org/argeo/slc/castor/ExecutionModuleDescriptorCastorTest.java index 0ee306256..09c6617eb 100644 --- a/runtime/org.argeo.slc.support.castor/src/test/java/org/argeo/slc/castor/ExecutionModuleDescriptorCastorTest.java +++ b/runtime/org.argeo.slc.support.castor/src/test/java/org/argeo/slc/castor/ExecutionModuleDescriptorCastorTest.java @@ -6,14 +6,15 @@ import java.util.List; import org.argeo.slc.execution.ExecutionFlowDescriptor; import org.argeo.slc.execution.ExecutionModuleDescriptor; import org.argeo.slc.execution.ExecutionSpec; -import org.argeo.slc.msg.ObjectList; import org.argeo.slc.unit.execution.ExecutionFlowDescriptorTestUtils; public class ExecutionModuleDescriptorCastorTest extends AbstractCastorTestCase { public void testMarshUnmarsh() throws Exception { ExecutionModuleDescriptor moduleDescriptor = new ExecutionModuleDescriptor(); - moduleDescriptor.setName("test.moodule"); + moduleDescriptor.setName("test.module"); moduleDescriptor.setVersion("1.0.0"); + moduleDescriptor.setLabel("Test Module"); + moduleDescriptor.setDescription("module descriptor"); ExecutionFlowDescriptor flowDescriptor = ExecutionFlowDescriptorTestUtils .createSimpleExecutionFlowDescriptor(); diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java index 2d3ce0465..5e61ddba0 100644 --- a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java +++ b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java @@ -9,13 +9,16 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; import org.argeo.slc.core.execution.AbstractExecutionModulesManager; -import org.argeo.slc.core.execution.DefaultDescriptorConverter; +import org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter; +import org.argeo.slc.deploy.ModuleDescriptor; import org.argeo.slc.execution.ExecutionContext; import org.argeo.slc.execution.ExecutionFlow; import org.argeo.slc.execution.ExecutionFlowDescriptor; import org.argeo.slc.execution.ExecutionFlowDescriptorConverter; import org.argeo.slc.execution.ExecutionModuleDescriptor; import org.argeo.slc.process.RealizedFlow; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; @@ -30,12 +33,17 @@ public class OsgiExecutionModulesManager extends private BundlesManager bundlesManager; private ServiceTracker executionContexts; - private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultDescriptorConverter(); + private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter(); public ExecutionModuleDescriptor getExecutionModuleDescriptor( String moduleName, String version) { - return createDescriptor(moduleName, version, listFlows(moduleName, - version)); + ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); + md.setName(moduleName); + md.setVersion(version); + setMetadataFromBundle(md, null); + getExecutionFlowDescriptorConverter(moduleName, version) + .addFlowsToDescriptor(md, listFlows(moduleName, version)); + return md; } public List listExecutionModules() { @@ -43,12 +51,8 @@ public class OsgiExecutionModulesManager extends ServiceReference[] srs = executionContexts.getServiceReferences(); for (ServiceReference sr : srs) { - String moduleName = sr.getBundle().getSymbolicName(); - String moduleVersion = sr.getBundle().getHeaders().get( - "Bundle-Version").toString(); ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); - md.setName(moduleName); - md.setVersion(moduleVersion); + setMetadataFromBundle(md, sr.getBundle()); descriptors.add(md); } return descriptors; @@ -164,6 +168,17 @@ public class OsgiExecutionModulesManager extends execute(realizedFlow); } + protected ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter( + String moduleName, String moduleVersion) { + // Check whether a descriptor converter is published by this module + ExecutionFlowDescriptorConverter descriptorConverter = findExecutionFlowDescriptorConverter( + moduleName, moduleVersion); + if (descriptorConverter == null) + return defaultDescriptorConverter; + else + return descriptorConverter; + } + public void execute(RealizedFlow realizedFlow) { if (log.isTraceEnabled()) log.trace("Executing " + realizedFlow); @@ -171,18 +186,9 @@ public class OsgiExecutionModulesManager extends String moduleName = realizedFlow.getModuleName(); String moduleVersion = realizedFlow.getModuleVersion(); - // Check whether a descriptor converter is published by this module - ExecutionFlowDescriptorConverter descriptorConverter = findExecutionFlowDescriptorConverter( - moduleName, moduleVersion); - - final Map variablesToAdd; - if (descriptorConverter != null) - variablesToAdd = descriptorConverter.convertValues(realizedFlow - .getFlowDescriptor()); - else - variablesToAdd = defaultDescriptorConverter - .convertValues(realizedFlow.getFlowDescriptor()); - + Map variablesToAdd = getExecutionFlowDescriptorConverter( + moduleName, moduleVersion).convertValues( + realizedFlow.getFlowDescriptor()); ExecutionContext executionContext = findExecutionContext(moduleName, moduleVersion); for (String key : variablesToAdd.keySet()) @@ -200,4 +206,54 @@ public class OsgiExecutionModulesManager extends // } + public ModuleDescriptor getModuleDescriptor(String moduleName, + String version) { + return getExecutionModuleDescriptor(moduleName, version); + } + + public List listModules() { + Bundle[] bundles = bundlesManager.getBundleContext().getBundles(); + List lst = new ArrayList(); + for (Bundle bundle : bundles) { + ModuleDescriptor moduleDescriptor = new ModuleDescriptor(); + setMetadataFromBundle(moduleDescriptor, bundle); + lst.add(moduleDescriptor); + } + return lst; + } + + protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) { + Bundle bdl = bundle; + if (bdl == null) { + if (md.getName() == null || md.getVersion() == null) + throw new SlcException("Name and version not available."); + + Bundle[] bundles = bundlesManager.getBundleContext().getBundles(); + for (Bundle b : bundles) { + if (b.getSymbolicName().equals(md.getName()) + && md.getVersion().equals( + getHeaderSafe(b, Constants.BUNDLE_VERSION))) { + bdl = b; + break; + } + } + + } + + if (bdl == null) + throw new SlcException("Cannot find bundle."); + + md.setName(bdl.getSymbolicName()); + md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION)); + md.setLabel(getHeaderSafe(bdl, Constants.BUNDLE_NAME)); + md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION)); + } + + private String getHeaderSafe(Bundle bundle, Object key) { + Object obj = bundle.getHeaders().get(key); + if (obj == null) + return null; + else + return obj.toString(); + } } diff --git a/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution/spring.xml b/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution/spring.xml index 32de16750..f64b0abfb 100644 --- a/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution/spring.xml +++ b/runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution/spring.xml @@ -8,6 +8,8 @@ + diff --git a/runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/unit/execution/ExecutionFlowDescriptorTestUtils.java b/runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/unit/execution/ExecutionFlowDescriptorTestUtils.java index 14a34c7fb..d2aaf5810 100644 --- a/runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/unit/execution/ExecutionFlowDescriptorTestUtils.java +++ b/runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/unit/execution/ExecutionFlowDescriptorTestUtils.java @@ -1,14 +1,15 @@ package org.argeo.slc.unit.execution; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import org.argeo.slc.core.deploy.SimpleExecutables; import org.argeo.slc.core.execution.DefaultExecutionSpec; import org.argeo.slc.core.execution.PrimitiveSpecAttribute; import org.argeo.slc.core.execution.PrimitiveValue; import org.argeo.slc.core.execution.RefSpecAttribute; import org.argeo.slc.core.execution.RefValue; +import org.argeo.slc.core.execution.RefValueChoice; import org.argeo.slc.core.test.BasicTestData; import org.argeo.slc.execution.ExecutionFlowDescriptor; import org.argeo.slc.execution.ExecutionSpecAttribute; @@ -17,10 +18,14 @@ public class ExecutionFlowDescriptorTestUtils { public static ExecutionFlowDescriptor createSimpleExecutionFlowDescriptor() { ExecutionFlowDescriptor flowDescriptor = new ExecutionFlowDescriptor(); flowDescriptor.setName("simpleFlow"); + flowDescriptor.setDescription("my description"); + Map values = new HashMap(); values.put("primitiveInteger", new PrimitiveValue( PrimitiveSpecAttribute.TYPE_INTEGER, 100)); - values.put("ref1", new RefValue("Just a label")); + + RefValue refValue = new RefValue("002"); + values.put("ref1", refValue); flowDescriptor.setValues(values); flowDescriptor.setExecutionSpec(createRelatedSimpleSpec()); @@ -39,6 +44,10 @@ public class ExecutionFlowDescriptorTestUtils { RefSpecAttribute ref1 = new RefSpecAttribute(); ref1.setTargetClass(BasicTestData.class); + ref1.setChoices(new ArrayList()); + ref1.getChoices().add(new RefValueChoice("001", "desc")); + ref1.getChoices().add(new RefValueChoice("002", null)); + ref1.getChoices().add(new RefValueChoice("003", null)); attributes.put("ref1", ref1); spec.setAttributes(attributes); -- 2.39.2