First working version of SLC Runtime v2
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 17 Feb 2015 19:29:55 +0000 (19:29 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 17 Feb 2015 19:29:55 +0000 (19:29 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@7922 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

12 files changed:
org.argeo.slc.api/src/org/argeo/slc/execution/ExecutionContext.java
org.argeo.slc.api/src/org/argeo/slc/execution/ExecutionFlow.java
org.argeo.slc.api/src/org/argeo/slc/execution/ExecutionStack.java
org.argeo.slc.core/ext/test/org/argeo/slc/core/execution/AbstractExecutionFlowTestCase.java
org.argeo.slc.core/pom.xml
org.argeo.slc.core/src/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlow.java
org.argeo.slc.core/src/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java
org.argeo.slc.core/src/org/argeo/slc/core/execution/MapExecutionContext.java
org.argeo.slc.core/src/org/argeo/slc/core/execution/runtime.xml
org.argeo.slc.core/src/org/argeo/slc/core/execution/simple.xml
org.argeo.slc.core/src/org/argeo/slc/osgi/OsgiExecutionModulesManager.java

index 05661431491ea23fc18062b717f6ba652ecd17c7..9a88f52cdf1f836c85082fd6b8ce305ebe6258f5 100644 (file)
@@ -28,4 +28,8 @@ public interface ExecutionContext {
        public Object getVariable(String key);\r
 \r
        public void setVariable(String key, Object value);\r
+       \r
+       public void beforeFlow(ExecutionFlow executionFlow);\r
+       \r
+       public void afterFlow(ExecutionFlow executionFlow);\r
 }\r
index 520f249df50f11cd22b172d420262a0d18615195..5ebcdf07de20f2d91ed3e205af79be5df144fef4 100644 (file)
@@ -36,7 +36,7 @@ public interface ExecutionFlow extends Runnable {
 
        /**
         * If there is one and only one runnable wrapped return it, throw an
-        * exeception otherwise.
+        * exception otherwise.
         */
        public Runnable getRunnable();
 
@@ -45,10 +45,4 @@ public interface ExecutionFlow extends Runnable {
         * interpreted by UIs as a hierarchy;
         */
        public String getName();
-
-       /**
-        * @deprecated will be removed in SLC 2.0, the path should be the part of
-        *             the name with '/'
-        */
-       public String getPath();
 }
index c4e88b93d1f1ad416a3ea0459958294f7e3dec40..64cc3a8c50d59e1709eb50a7b37c37c83f716940 100644 (file)
@@ -15,7 +15,7 @@
  */
 package org.argeo.slc.execution;
 
-/** Deal with nested level of executions using different vartiables. */
+/** Deal with nested level of executions using different variables. */
 public interface ExecutionStack {
        /**
         * @param name
index 7cc8705f53ec4f4c1a7595e6dcfc1e89869ff4d3..004605cab781d6ba524f41bd97250c1bb2142e6e 100644 (file)
@@ -20,6 +20,7 @@ import junit.framework.TestCase;
 import org.apache.commons.logging.Log;\r
 import org.apache.commons.logging.LogFactory;\r
 import org.argeo.slc.core.test.SimpleTestResult;\r
+import org.argeo.slc.execution.ExecutionContext;\r
 import org.argeo.slc.execution.ExecutionFlow;\r
 import org.argeo.slc.test.TestResultPart;\r
 import org.argeo.slc.test.TestStatus;\r
@@ -59,9 +60,19 @@ public abstract class AbstractExecutionFlowTestCase extends TestCase {
        protected void configureAndExecuteSlcFlow(String applicationContextSuffix,\r
                        String beanName) {\r
                ConfigurableApplicationContext applicationContext = createApplicationContext(applicationContextSuffix);\r
+               ExecutionContext executionContext = (ExecutionContext) applicationContext\r
+                               .getBean("executionContext");\r
                ExecutionFlow executionFlow = (ExecutionFlow) applicationContext\r
                                .getBean(beanName);\r
-               executionFlow.run();\r
+               if (executionFlow instanceof DefaultExecutionFlow)\r
+                       ((DefaultExecutionFlow) executionFlow)\r
+                                       .setExecutionContext(executionContext);\r
+               try {\r
+                       executionContext.beforeFlow(executionFlow);\r
+                       executionFlow.run();\r
+               } finally {\r
+                       executionContext.afterFlow(executionFlow);\r
+               }\r
                applicationContext.close();\r
        }\r
 \r
index 6538840406295f59ca3355d8833585098c978803..f23f4523116d9405804ba92ce9d1f181312fa2c7 100644 (file)
@@ -9,6 +9,17 @@
        </parent>
        <artifactId>org.argeo.slc.core</artifactId>
        <name>SLC Runtime</name>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <configuration>
+                                       <skipTests>true</skipTests>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
        <dependencies>
                <!-- Commons -->
                <dependency>
@@ -28,6 +39,5 @@
                        <artifactId>org.argeo.slc.api</artifactId>
                        <version>2.1.1-SNAPSHOT</version>
                </dependency>
-
        </dependencies>
 </project>
\ No newline at end of file
index 1a07313f002273ff234f39c888760e9e1d685b6b..1d401c6b094267808a1305ee1351ec88b21e4be9 100644 (file)
@@ -31,8 +31,8 @@ public abstract class AbstractExecutionModulesManager implements
        private final static Log log = LogFactory
                        .getLog(AbstractExecutionModulesManager.class);
 
-//     private List<FilteredNotifier> filteredNotifiers = Collections
-//                     .synchronizedList(new ArrayList<FilteredNotifier>());
+       // private List<FilteredNotifier> filteredNotifiers = Collections
+       // .synchronizedList(new ArrayList<FilteredNotifier>());
 
        protected abstract ExecutionFlow findExecutionFlow(String moduleName,
                        String moduleVersion, String flowName);
@@ -64,94 +64,99 @@ public abstract class AbstractExecutionModulesManager implements
                //
                // Actually runs the flow, IN THIS THREAD
                //
-               flow.run();
+               executionContext.beforeFlow(flow);
+               try {
+                       flow.run();
+               } finally {
+                       executionContext.afterFlow(flow);
+               }
                //
                //
                //
        }
 
-//     public void dispatchUpdateStatus(ExecutionProcess process,
-//                     String oldStatus, String newStatus) {
-//             // filtered notifiers
-//             for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
-//                             .hasNext();) {
-//                     FilteredNotifier filteredNotifier = it.next();
-//                     if (filteredNotifier.receiveFrom(process))
-//                             filteredNotifier.getNotifier().updateStatus(process, oldStatus,
-//                                             newStatus);
-//             }
-//
-//     }
-
-//     public void dispatchAddSteps(ExecutionProcess process,
-//                     List<ExecutionStep> steps) {
-//             process.addSteps(steps);
-//             for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
-//                             .hasNext();) {
-//                     FilteredNotifier filteredNotifier = it.next();
-//                     if (filteredNotifier.receiveFrom(process))
-//                             filteredNotifier.getNotifier().addSteps(process, steps);
-//             }
-//     }
-
-//     public void registerProcessNotifier(ExecutionProcessNotifier notifier,
-//                     Map<String, String> properties) {
-//             filteredNotifiers.add(new FilteredNotifier(notifier, properties));
-//     }
-//
-//     public void unregisterProcessNotifier(ExecutionProcessNotifier notifier,
-//                     Map<String, String> properties) {
-//             filteredNotifiers.remove(notifier);
-//     }
-
-//     protected class FilteredNotifier {
-//             private final ExecutionProcessNotifier notifier;
-//             private final String processId;
-//
-//             public FilteredNotifier(ExecutionProcessNotifier notifier,
-//                             Map<String, String> properties) {
-//                     super();
-//                     this.notifier = notifier;
-//                     if (properties == null)
-//                             properties = new HashMap<String, String>();
-//                     if (properties.containsKey(SLC_PROCESS_ID))
-//                             processId = properties.get(SLC_PROCESS_ID);
-//                     else
-//                             processId = null;
-//             }
-//
-//             /**
-//              * Whether event from this process should be received by this listener.
-//              */
-//             public Boolean receiveFrom(ExecutionProcess process) {
-//                     if (processId != null)
-//                             if (process.getUuid().equals(processId))
-//                                     return true;
-//                             else
-//                                     return false;
-//                     return true;
-//             }
-//
-//             @Override
-//             public int hashCode() {
-//                     return notifier.hashCode();
-//             }
-//
-//             @Override
-//             public boolean equals(Object obj) {
-//                     if (obj instanceof FilteredNotifier) {
-//                             FilteredNotifier fn = (FilteredNotifier) obj;
-//                             return notifier.equals(fn.notifier);
-//                     } else if (obj instanceof ExecutionProcessNotifier) {
-//                             ExecutionProcessNotifier epn = (ExecutionProcessNotifier) obj;
-//                             return notifier.equals(epn);
-//                     } else
-//                             return false;
-//             }
-//
-//             public ExecutionProcessNotifier getNotifier() {
-//                     return notifier;
-//             }
-//
-//     }
+       // public void dispatchUpdateStatus(ExecutionProcess process,
+       // String oldStatus, String newStatus) {
+       // // filtered notifiers
+       // for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
+       // .hasNext();) {
+       // FilteredNotifier filteredNotifier = it.next();
+       // if (filteredNotifier.receiveFrom(process))
+       // filteredNotifier.getNotifier().updateStatus(process, oldStatus,
+       // newStatus);
+       // }
+       //
+       // }
+
+       // public void dispatchAddSteps(ExecutionProcess process,
+       // List<ExecutionStep> steps) {
+       // process.addSteps(steps);
+       // for (Iterator<FilteredNotifier> it = filteredNotifiers.iterator(); it
+       // .hasNext();) {
+       // FilteredNotifier filteredNotifier = it.next();
+       // if (filteredNotifier.receiveFrom(process))
+       // filteredNotifier.getNotifier().addSteps(process, steps);
+       // }
+       // }
+
+       // public void registerProcessNotifier(ExecutionProcessNotifier notifier,
+       // Map<String, String> properties) {
+       // filteredNotifiers.add(new FilteredNotifier(notifier, properties));
+       // }
+       //
+       // public void unregisterProcessNotifier(ExecutionProcessNotifier notifier,
+       // Map<String, String> properties) {
+       // filteredNotifiers.remove(notifier);
+       // }
+
+       // protected class FilteredNotifier {
+       // private final ExecutionProcessNotifier notifier;
+       // private final String processId;
+       //
+       // public FilteredNotifier(ExecutionProcessNotifier notifier,
+       // Map<String, String> properties) {
+       // super();
+       // this.notifier = notifier;
+       // if (properties == null)
+       // properties = new HashMap<String, String>();
+       // if (properties.containsKey(SLC_PROCESS_ID))
+       // processId = properties.get(SLC_PROCESS_ID);
+       // else
+       // processId = null;
+       // }
+       //
+       // /**
+       // * Whether event from this process should be received by this listener.
+       // */
+       // public Boolean receiveFrom(ExecutionProcess process) {
+       // if (processId != null)
+       // if (process.getUuid().equals(processId))
+       // return true;
+       // else
+       // return false;
+       // return true;
+       // }
+       //
+       // @Override
+       // public int hashCode() {
+       // return notifier.hashCode();
+       // }
+       //
+       // @Override
+       // public boolean equals(Object obj) {
+       // if (obj instanceof FilteredNotifier) {
+       // FilteredNotifier fn = (FilteredNotifier) obj;
+       // return notifier.equals(fn.notifier);
+       // } else if (obj instanceof ExecutionProcessNotifier) {
+       // ExecutionProcessNotifier epn = (ExecutionProcessNotifier) obj;
+       // return notifier.equals(epn);
+       // } else
+       // return false;
+       // }
+       //
+       // public ExecutionProcessNotifier getNotifier() {
+       // return notifier;
+       // }
+       //
+       // }
 }
index 535c42dad7224fdded4a561e864ec801f768d67f..bebde75128243049d80a54b9d35dea87f379f555 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Map;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionContext;
 import org.argeo.slc.execution.ExecutionFlow;
 import org.argeo.slc.execution.ExecutionSpec;
 import org.argeo.slc.execution.ExecutionSpecAttribute;
@@ -46,6 +47,9 @@ public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
 
        private Boolean failOnError = true;
 
+       // Only needed if stacked execution flows are used
+       private ExecutionContext executionContext = null;
+
        public DefaultExecutionFlow() {
                this.executionSpec = new DefaultExecutionSpec();
        }
@@ -154,7 +158,16 @@ public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
        }
 
        public void doExecuteRunnable(Runnable runnable) {
-               runnable.run();
+               try {
+                       if (executionContext != null)
+                               if (runnable instanceof ExecutionFlow)
+                                       executionContext.beforeFlow((ExecutionFlow) runnable);
+                       runnable.run();
+               } finally {
+                       if (executionContext != null)
+                               if (runnable instanceof ExecutionFlow)
+                                       executionContext.afterFlow((ExecutionFlow) runnable);
+               }
        }
 
        public void afterPropertiesSet() throws Exception {
@@ -258,4 +271,8 @@ public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
                this.failOnError = failOnError;
        }
 
+       public void setExecutionContext(ExecutionContext executionContext) {
+               this.executionContext = executionContext;
+       }
+
 }
index 90a9f026f957b9190e487b7bee213527b25a72ef..beac9175a19e2876c027b718ebb87b71370d330b 100644 (file)
@@ -163,7 +163,6 @@ public class DefaultExecutionFlowDescriptorConverter implements
                md.getExecutionFlows().addAll(set);
        }
 
-       @SuppressWarnings("deprecation")
        public ExecutionFlowDescriptor getExecutionFlowDescriptor(
                        ExecutionFlow executionFlow) {
                if (executionFlow.getName() == null)
@@ -213,11 +212,6 @@ public class DefaultExecutionFlowDescriptorConverter implements
 
                ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null,
                                values, executionSpec);
-               if (executionFlow.getPath() != null)
-                       efd.setPath(executionFlow.getPath());
-               else
-                       efd.setPath("");
-
                // Takes description from spring
                BeanFactory bf = getBeanFactory();
                if (bf != null) {
index 0bbc3f0df65abec30f56fc0b4984b8281bce4070..324f973059fc40c150cd4f0ca5abc0935ec7109b 100644 (file)
@@ -23,6 +23,8 @@ import java.util.UUID;
 
 import org.argeo.slc.SlcException;
 import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionStack;
 import org.springframework.beans.BeanWrapper;
 import org.springframework.beans.BeanWrapperImpl;
 import org.springframework.beans.BeansException;
@@ -37,6 +39,7 @@ public class MapExecutionContext implements ExecutionContext,
        private final String uuid;
 
        private ApplicationContext applicationContext;
+       private ExecutionStack executionStack;
 
        public MapExecutionContext() {
                uuid = UUID.randomUUID().toString();
@@ -84,6 +87,12 @@ public class MapExecutionContext implements ExecutionContext,
                // try system property in last resort
                if (value == null)
                        value = System.getProperty(key);
+
+               // if the variable was not found, look in the stack starting at the
+               // upper flows
+               if (value == null) {
+                       value = executionStack.findLocalVariable(key);
+               }
                return value;
        }
 
@@ -91,6 +100,20 @@ public class MapExecutionContext implements ExecutionContext,
                return uuid;
        }
 
+       @Override
+       public void beforeFlow(ExecutionFlow executionFlow) {
+               // getUuid();
+               executionStack.enterFlow(executionFlow);
+               setVariable(ExecutionContext.VAR_FLOW_ID,
+                               executionStack.getCurrentStackLevelUuid());
+               setVariable(ExecutionContext.VAR_FLOW_NAME, executionFlow.getName());
+       }
+
+       @Override
+       public void afterFlow(ExecutionFlow executionFlow) {
+               executionStack.leaveFlow(executionFlow);
+       }
+
        @Override
        public boolean equals(Object obj) {
                if (obj instanceof ExecutionContext)
@@ -108,4 +131,8 @@ public class MapExecutionContext implements ExecutionContext,
                this.applicationContext = applicationContext;
        }
 
+       public void setExecutionStack(ExecutionStack executionStack) {
+               this.executionStack = executionStack;
+       }
+
 }
index 990d85cb294905ce035d7b40396a3d0e88514f99..33542ee2057e62ef8a888ef2b4f818ba104c25dd 100644 (file)
@@ -1,21 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
+<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
+       Version 2.0 (the "License"); you may not use this file except in compliance 
+       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+       Unless required by applicable law or agreed to in writing, software distributed 
+       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+       the specific language governing permissions and limitations under the License. -->
 <!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
        the Apache License, Version 2.0 (the "License"); you may not use this file 
        except in compliance with the License. You may obtain a copy of the License 
@@ -33,7 +23,8 @@
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
 
        <description>Bare minimal runtime configuration. In general you will
-               want to use simple.xml instead.</description>
+               want to use simple.xml instead.
+       </description>
 
        <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
                <property name="scopes">
                <property name="instantiationManager" ref="instantiationManager" />
        </bean>
 
-       <bean class="org.argeo.slc.core.execution.ExecutionAspect">
-               <property name="executionStack" ref="executionStack" />
-               <property name="executionContext" ref="executionContext" />
-       </bean>
+       <!-- <bean class="org.argeo.slc.core.execution.ExecutionAspect"> -->
+       <!-- <property name="executionStack" ref="executionStack" /> -->
+       <!-- <property name="executionContext" ref="executionContext" /> -->
+       <!-- </bean> -->
 
        <aop:aspectj-autoproxy />
 
index b25f3d130985ffd4a37599716bb1e0ab16fcd473..ff243baf6f43715d551aacfce976e55eea1fd9dd 100644 (file)
@@ -1,21 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (C) 2007-2012 Argeo GmbH
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-            http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
+<!-- Copyright (C) 2007-2012 Argeo GmbH Licensed under the Apache License, 
+       Version 2.0 (the "License"); you may not use this file except in compliance 
+       with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+       Unless required by applicable law or agreed to in writing, software distributed 
+       under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+       OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+       the specific language governing permissions and limitations under the License. -->
 <!-- Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org> Licensed under 
        the Apache License, Version 2.0 (the "License"); you may not use this file 
        except in compliance with the License. You may obtain a copy of the License 
@@ -40,6 +30,7 @@
        <bean id="executionContext" class="org.argeo.slc.core.execution.MapExecutionContext"
                scope="execution">
                <aop:scoped-proxy proxy-target-class="false" />
+               <property name="executionStack" ref="executionStack" />
        </bean>
 
        <bean id="executionFlowDescriptorConverter"
index f15be6bc211578af058842fd2b39ff23b0b7ac6a..046cfb6464301e2245c00669efe90535c48a5146 100644 (file)
@@ -631,33 +631,32 @@ public class OsgiExecutionModulesManager extends
                }
        }
 
-       @SuppressWarnings("deprecation")
        protected ObjectName flowMBeanName(Module module,
                        ExecutionFlow executionFlow) {
                String executionModulesPrefix = "SLCExecutionModules";
-               String path = executionFlow.getPath();
+               // String path = executionFlow.getPath();
                String name = executionFlow.getName();
-               if (path == null && name.indexOf('/') >= 0) {
-                       path = name.substring(0, name.lastIndexOf('/'));
-                       name = name.substring(name.lastIndexOf('/'));
-               }
+               // if (path == null && name.indexOf('/') >= 0) {
+               // path = name.substring(0, name.lastIndexOf('/'));
+               // name = name.substring(name.lastIndexOf('/'));
+               // }
 
                StringBuffer buf = new StringBuffer(executionModulesPrefix + ":"
                                + "module=" + module.getName() + " [" + module.getVersion()
                                + "],");
 
-               if (path != null && !path.equals("")) {
-                       int depth = 0;
-                       for (String token : path.split("/")) {
-                               if (!token.equals("")) {
-                                       buf.append("path").append(depth).append('=');
-                                       // in order to have directories first
-                                       buf.append('/');
-                                       buf.append(token).append(',');
-                                       depth++;
-                               }
-                       }
-               }
+               // if (path != null && !path.equals("")) {
+               // int depth = 0;
+               // for (String token : path.split("/")) {
+               // if (!token.equals("")) {
+               // buf.append("path").append(depth).append('=');
+               // // in order to have directories first
+               // buf.append('/');
+               // buf.append(token).append(',');
+               // depth++;
+               // }
+               // }
+               // }
                buf.append("name=").append(name);
                try {
                        return new ObjectName(buf.toString());