]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Improve SystemCall
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 10 Jun 2009 15:03:46 +0000 (15:03 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 10 Jun 2009 15:03:46 +0000 (15:03 +0000)
Reactivate SlcExecutionStep

git-svn-id: https://svn.argeo.org/slc/trunk@2524 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

24 files changed:
demo/pom.xml
integration-tests/org.argeo.slc.it.webapp/pom.xml
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/ServiceMsgHandler.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/process/SlcExecutionServiceImpl.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/test/TestManagerServiceImpl.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/process/SlcExecutionService.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/process/NewSlcExecutionController.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionContext.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/process/SlcExecution.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/process/SlcExecutionStep.java
runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsSlcExecutionNotifier.java
runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsTreeTestResultListener.java
runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/msg.xml
runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/process/SlcExecution.hbm.xml
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlow.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultModulesManager.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/FileExecutionResources.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/MapExecutionContext.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/structure/tree/TreeSRelatedHelper.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/process/SlcExecutionStepsRequest.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/unit/process/SlcExecutionTestUtils.java
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.main/META-INF/MANIFEST.MF [new file with mode: 0644]
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.main/META-INF/spring/main.xml [new file with mode: 0644]

index d9d0a0d8dd7f51505ea50b396fa609314fb5a37e..27e7888d0c0b3df08b22024ab2689631e4becd5a 100644 (file)
                                        </plugin>
                                </plugins>
                        </build>
+                       <dependencies>
+                               <dependency>
+                                       <groupId>org.argeo.slc.dep</groupId>
+                                       <artifactId>org.argeo.slc.dep.server</artifactId>
+                                       <version>${project.version}</version>
+                               </dependency>
+                       </dependencies>
                </profile>
                <profile>
                        <id>server_mysql</id>
index ef22873797e2a08bab81fdea3e7934521509cf64..aa25a83be8f26323bc77b3d7f0a33f7d90d3540e 100644 (file)
                                                        ${basedir}/../../server/org.argeo.slc.siteserver/bundles;in=*
                                                                </slc.osgi.bundles>
                                                <slc.osgi.start>
-                                                       org.argeo.dep.osgi.catalina.start,
                                                        org.springframework.osgi.extender,
-                                                       org.springframework.osgi.web.extender,
-                                                       org.springframework.osgi.samples.simplewebapp,
-                                                       org.argeo.slc.server.activemq,
+                                                       org.argeo.slc.server.main,
                                                        org.argeo.slc.server.hsqldb,
-                                                       org.argeo.slc.server.hibernate,
-                                                       org.argeo.slc.server.services,
-                                                       org.argeo.slc.server.jms,
-                                                       org.argeo.slc.webapp,
                                                        org.argeo.slc.ria,
                                                        org.argeo.slc.agent                                                             
-                                                               </slc.osgi.start>
+                                               </slc.osgi.start>
                                        </systemProperties>
                                </configuration>
                                <executions>
index 4bf96d6c1c67693248302decad5607e31c4a602e..2ec8409624e0f080500b4815ed996cf29c19073b 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.slc.services;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.msg.MsgHandler;
 import org.argeo.slc.msg.process.SlcExecutionStatusRequest;
+import org.argeo.slc.msg.process.SlcExecutionStepsRequest;
 import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest;
 import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;
@@ -18,6 +19,8 @@ public class ServiceMsgHandler implements MsgHandler {
        public Object handleMsg(Object msg) {
                if (msg instanceof SlcExecution)
                        slcExecutionService.newExecution((SlcExecution) msg);
+               else if (msg instanceof SlcExecutionStepsRequest)
+                       slcExecutionService.addSteps((SlcExecutionStepsRequest) msg);
                else if (msg instanceof SlcExecutionStatusRequest)
                        slcExecutionService.updateStatus((SlcExecutionStatusRequest) msg);
                else if (msg instanceof CreateTreeTestResultRequest)
index b3c6f71fc52944962d4ac640631107a4d396f4ea..1cb71070f9f28cbcb5ab90f192167d9f96c894dc 100644 (file)
@@ -5,7 +5,9 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.dao.process.SlcExecutionDao;
 import org.argeo.slc.msg.process.SlcExecutionStatusRequest;
+import org.argeo.slc.msg.process.SlcExecutionStepsRequest;
 import org.argeo.slc.process.SlcExecution;
+import org.argeo.slc.process.SlcExecutionStep;
 import org.argeo.slc.services.process.SlcExecutionService;
 
 public class SlcExecutionServiceImpl implements SlcExecutionService {
@@ -27,11 +29,14 @@ public class SlcExecutionServiceImpl implements SlcExecutionService {
 
                        slcExecutionDao.create(slcExecutionMsg);
                } else {
-                       if (log.isTraceEnabled())
-                               log.trace("Updating SLC execution #"
-                                               + slcExecutionMsg.getUuid());
-
-                       slcExecutionDao.merge(slcExecutionMsg);
+                       throw new SlcException(
+                                       "There is already an SlcExecution registered with id "
+                                                       + slcExecutionMsg.getUuid());
+                       // if (log.isTraceEnabled())
+                       // log.trace("Updating SLC execution #"
+                       // + slcExecutionMsg.getUuid());
+                       //
+                       // slcExecutionDao.merge(slcExecutionMsg);
                }
        }
 
@@ -44,10 +49,21 @@ public class SlcExecutionServiceImpl implements SlcExecutionService {
 
                slcExecution.setStatus(msg.getNewStatus());
 
+               if (msg.getNewStatus().equals(SlcExecution.STATUS_FINISHED))
+                       slcExecution.getSteps().add(
+                                       new SlcExecutionStep(SlcExecutionStep.TYPE_END,
+                                                       "Process finished."));
+
                if (log.isTraceEnabled())
                        log.trace("Updating status for SLC execution #"
-                                       + slcExecution.getUuid());
+                                       + slcExecution.getUuid() + " to status "
+                                       + msg.getNewStatus());
 
                slcExecutionDao.update(slcExecution);
        }
+
+       public void addSteps(SlcExecutionStepsRequest msg) {
+               slcExecutionDao.addSteps(msg.getSlcExecutionUuid(), msg.getSteps());
+       }
+
 }
index 7ccc35d11e24c1e2e20e1f2c698ef0f156fd20a2..59b7b37db734b8b1976b27895b5663b63919955a 100644 (file)
@@ -16,7 +16,9 @@ import org.argeo.slc.process.SlcExecution;
 import org.argeo.slc.services.test.TestManagerService;\r
 import org.argeo.slc.test.TestRunDescriptor;\r
 \r
-/** Implementation of complex operations impacting the underlying data. */\r
+/**\r
+ * Implementation of complex operations impacting the underlying data.\r
+ */\r
 public class TestManagerServiceImpl implements TestManagerService {\r
        private Log log = LogFactory.getLog(getClass());\r
 \r
@@ -57,9 +59,9 @@ public class TestManagerServiceImpl implements TestManagerService {
                                                        .getTestResultUuid());\r
                                }\r
                        } else {\r
-                               log\r
-                                               .trace("ResultUUID="\r
-                                                               + testRunDescriptor.getTestResultUuid());\r
+                               if (log.isTraceEnabled())\r
+                                       log.trace("ResultUUID="\r
+                                                       + testRunDescriptor.getTestResultUuid());\r
                                addResultToCollection("default", testRunDescriptor\r
                                                .getTestResultUuid());\r
                        }\r
@@ -67,6 +69,7 @@ public class TestManagerServiceImpl implements TestManagerService {
        }\r
 \r
        public void addResultToCollection(String collectionId, String resultUuid) {\r
+               // TODO: improve collections\r
                TreeTestResultCollection ttrc = treeTestResultCollectionDao\r
                                .getTestResultCollection(collectionId);\r
                if (ttrc == null) {\r
@@ -100,6 +103,11 @@ public class TestManagerServiceImpl implements TestManagerService {
                treeTestResultDao.create(treeTestResult);\r
 \r
                registerTestRunDescriptor(msg.getTestRunDescriptor());\r
+\r
+               // FIXME: temporary hack before better collection management is found\r
+               if (msg.getTestRunDescriptor() == null) {\r
+                       addResultToCollection("default", treeTestResult.getUuid());\r
+               }\r
        }\r
 \r
        public void addResultPart(ResultPartRequest msg) {\r
index 9e617f74397fa590fbb3a5457c6214d7b390c8f5..03afceeaa76aff47fee66e1d415f7bc027cc99eb 100644 (file)
@@ -1,9 +1,13 @@
 package org.argeo.slc.services.process;
 
 import org.argeo.slc.msg.process.SlcExecutionStatusRequest;
+import org.argeo.slc.msg.process.SlcExecutionStepsRequest;
 import org.argeo.slc.process.SlcExecution;
 
 public interface SlcExecutionService {
        public void newExecution(SlcExecution slcExecutionMsg);
+
        public void updateStatus(SlcExecutionStatusRequest msg);
+
+       public void addSteps(SlcExecutionStepsRequest msg);
 }
index 2e6a45cfe535122ffa6eed3cde394b8b0f4b5585..aaa94a9e1f145026b746c2294f2f61b5187f681c 100644 (file)
@@ -9,6 +9,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;\r
 import org.argeo.slc.msg.MsgConstants;\r
 import org.argeo.slc.process.SlcExecution;\r
+import org.argeo.slc.process.SlcExecutionStep;\r
 import org.argeo.slc.runtime.SlcAgent;\r
 import org.argeo.slc.runtime.SlcAgentFactory;\r
 import org.argeo.slc.services.process.SlcExecutionService;\r
@@ -61,6 +62,9 @@ public class NewSlcExecutionController extends AbstractServiceController {
                                .unmarshal(source);\r
 \r
                slcExecution.setStatus(SlcExecution.STATUS_SCHEDULED);\r
+               slcExecution.getSteps().add(\r
+                               new SlcExecutionStep(SlcExecutionStep.TYPE_START,\r
+                                               "Process started from the Web UI"));\r
                slcExecutionService.newExecution(slcExecution);\r
 \r
                SlcAgent agent = agentFactory.getAgent(agentId);\r
index 113755af0de84b65928f5d67861b64b11b5e615a..c23fc363ceaf975f6a77961ae5d903587f23ad49 100644 (file)
@@ -4,6 +4,10 @@ import java.util.Date;
 import java.util.Map;\r
 \r
 public interface ExecutionContext {\r
+       public final static String VAR_PROCESS_ID = "slcVar.process.id";\r
+       public final static String VAR_EXECUTION_CONTEXT_ID = "slcVar.executionContext.id";\r
+       public final static String VAR_FLOW_ID = "slcVar.flow.id";\r
+       public final static String VAR_FLOW_NAME = "slcVar.flow.name";\r
 \r
        /**\r
         * @param name\r
index 0bf52e20054f7892e62e0ad6c503dd9810b3def1..7a81facf612b1c6529ef8a2fdd825d4c9057ef17 100644 (file)
@@ -2,6 +2,7 @@ package org.argeo.slc.process;
 \r
 import java.io.Serializable;\r
 import java.util.ArrayList;\r
+import java.util.Date;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.TreeMap;\r
@@ -24,6 +25,7 @@ public class SlcExecution implements Serializable {
        private String status = STATUS_NONE;\r
        private Map<String, String> attributes = new TreeMap<String, String>();\r
 \r
+       /** TODO: Synchronize */\r
        private List<SlcExecutionStep> steps = new ArrayList<SlcExecutionStep>();\r
        private List<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();\r
 \r
@@ -84,10 +86,12 @@ public class SlcExecution implements Serializable {
        }\r
 \r
        public SlcExecutionStep currentStep() {\r
-               if (steps.size() > 0)\r
-                       return steps.get(steps.size() - 1);\r
-               else\r
-                       return null;\r
+               synchronized (steps) {\r
+                       if (steps.size() > 0)\r
+                               return steps.get(steps.size() - 1);\r
+                       else\r
+                               return null;\r
+               }\r
        }\r
 \r
        @Override\r
@@ -118,4 +122,25 @@ public class SlcExecution implements Serializable {
                buf.append(" attributes=").append(attributes);\r
                return buf.toString();\r
        }\r
+\r
+       public Date getStartDate() {\r
+               synchronized (steps) {\r
+                       if (steps.size() == 0)\r
+                               return null;\r
+                       else\r
+                               return steps.get(0).getBegin();\r
+               }\r
+       }\r
+\r
+       public Date getEndDate() {\r
+               if (!status.equals(STATUS_FINISHED) && !status.equals(STATUS_ERROR))\r
+                       return null;\r
+\r
+               synchronized (steps) {\r
+                       if (steps.size() == 0)\r
+                               return null;\r
+                       else\r
+                               return steps.get(steps.size() - 1).getBegin();\r
+               }\r
+       }\r
 }\r
index 54e363efbbe8d50bb97682eb9594297392032346..5c54b2c6d9c5a0c8498a918fdeb4553917e0cad9 100644 (file)
@@ -2,7 +2,6 @@ package org.argeo.slc.process;
 \r
 import java.io.IOException;\r
 import java.io.StringReader;\r
-import java.io.StringWriter;\r
 import java.util.ArrayList;\r
 import java.util.Date;\r
 import java.util.List;\r
@@ -11,21 +10,29 @@ import java.util.UUID;
 import org.apache.commons.io.IOUtils;\r
 \r
 public class SlcExecutionStep {\r
+       public final static String TYPE_START = "START";\r
+       public final static String TYPE_END = "END";\r
+       public final static String TYPE_PHASE_START = "PHASE_START";\r
+       public final static String TYPE_PHASE_END = "PHASE_END";\r
        public final static String TYPE_LOG = "LOG";\r
 \r
-       private String uuid;\r
+       private String uuid = UUID.randomUUID().toString();\r
        private String type;\r
-       private Date begin;\r
+       private Date begin = new Date();\r
        private List<String> logLines = new ArrayList<String>();\r
 \r
        /** Empty constructor */\r
        public SlcExecutionStep() {\r
        }\r
 \r
+       /** Creates a step of type LOG. */\r
        public SlcExecutionStep(String log) {\r
-               this.type = TYPE_LOG;\r
-               this.begin = new Date();\r
-               this.uuid = UUID.randomUUID().toString();\r
+               this(TYPE_LOG, log);\r
+       }\r
+\r
+       /** Creates a step of the given type. */\r
+       public SlcExecutionStep(String type, String log) {\r
+               this.type = type;\r
                addLog(log);\r
        }\r
 \r
@@ -61,13 +68,7 @@ public class SlcExecutionStep {
                this.logLines = logLines;\r
        }\r
 \r
-       public String logAsString() {\r
-               StringWriter writer = new StringWriter();\r
-               String log = writer.toString();\r
-               IOUtils.closeQuietly(writer);\r
-               return log;\r
-       }\r
-\r
+       @SuppressWarnings(value = { "unchecked" })\r
        public void addLog(String log) {\r
                if (log == null)\r
                        return;\r
index 801c6fae32a730fc9204dde886ec931f8e8b9cf5..256e837abf11c67897c38daf2c3976496a6eb4dc 100644 (file)
@@ -4,31 +4,39 @@ import java.util.List;
 
 import javax.jms.Destination;
 
-import org.argeo.slc.SlcException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.UnsupportedException;
 import org.argeo.slc.msg.process.SlcExecutionStatusRequest;
+import org.argeo.slc.msg.process.SlcExecutionStepsRequest;
 import org.argeo.slc.process.SlcExecution;
 import org.argeo.slc.process.SlcExecutionNotifier;
 import org.argeo.slc.process.SlcExecutionStep;
+import org.springframework.jms.JmsException;
 import org.springframework.jms.core.JmsTemplate;
 
 public class JmsSlcExecutionNotifier implements SlcExecutionNotifier {
+       private final static Log log = LogFactory
+                       .getLog(JmsSlcExecutionNotifier.class);
 
        private JmsTemplate jmsTemplate;
 
        private Destination executionEventDestination;
-       //private Destination updateStatusDestination;
+
+       // private Destination updateStatusDestination;
 
        public void updateStatus(SlcExecution slcExecution, String oldStatus,
                        String newStatus) {
                SlcExecutionStatusRequest req = new SlcExecutionStatusRequest(
                                slcExecution.getUuid(), newStatus);
-               jmsTemplate.convertAndSend(executionEventDestination, req);
+               convertAndSend(req);
        }
 
        public void addSteps(SlcExecution slcExecution,
                        List<SlcExecutionStep> additionalSteps) {
-               throw new UnsupportedException();
+               SlcExecutionStepsRequest req = new SlcExecutionStepsRequest(
+                               slcExecution.getUuid(), additionalSteps);
+               convertAndSend(req);
        }
 
        public void newExecution(SlcExecution slcExecution) {
@@ -43,14 +51,19 @@ public class JmsSlcExecutionNotifier implements SlcExecutionNotifier {
                this.jmsTemplate = jmsTemplate;
        }
 
-       public void setExecutionEventDestination(Destination executionEventDestination) {
+       public void setExecutionEventDestination(
+                       Destination executionEventDestination) {
                this.executionEventDestination = executionEventDestination;
        }
 
-       
-       
-//     public void setUpdateStatusDestination(Destination updateStatusDestination) {
-//             this.updateStatusDestination = updateStatusDestination;
-//     }
-
+       protected void convertAndSend(Object req) {
+               try {
+                       jmsTemplate.convertAndSend(executionEventDestination, req);
+               } catch (JmsException e) {
+                       log.warn("Send request " + req.getClass() + " to server: "
+                                       + e.getMessage());
+                       if (log.isTraceEnabled())
+                               log.debug("Original error.", e);
+               }
+       }
 }
index 7da976a4de3d7bbe9f222ab4b9409f3ba9f48a72..7807b4219655c7152939b2bd00858b97b27c631f 100644 (file)
@@ -13,8 +13,8 @@ import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest;
 import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.ResultPartRequest;
-import org.argeo.slc.test.TestResultListener;
 import org.argeo.slc.test.TestResultPart;
+import org.springframework.jms.JmsException;
 import org.springframework.jms.core.JmsTemplate;
 
 public class JmsTreeTestResultListener implements TreeTestResultListener {
@@ -25,10 +25,6 @@ public class JmsTreeTestResultListener implements TreeTestResultListener {
 
        private Destination executionEventDestination;
 
-       // private Destination createDestination;
-       // private Destination addResultPartDestination;
-       // private Destination closeDestination;
-
        public void resultPartAdded(TreeTestResult testResult,
                        TestResultPart testResultPart) {
                if (onlyOnClose)
@@ -55,6 +51,11 @@ public class JmsTreeTestResultListener implements TreeTestResultListener {
 
                                jmsTemplate.convertAndSend(executionEventDestination, req);
                        }
+               } catch (JmsException e) {
+                       log.warn("Could not notify result part to server: "
+                                       + e.getMessage());
+                       if (log.isTraceEnabled())
+                               log.debug("Original error.", e);
                } catch (Exception e) {
                        throw new SlcException("Could not notify to JMS", e);
                }
@@ -82,6 +83,11 @@ public class JmsTreeTestResultListener implements TreeTestResultListener {
                                jmsTemplate.convertAndSend(executionEventDestination, req);
 
                        }
+               } catch (JmsException e) {
+                       log.warn("Could not notify result close to server: "
+                                       + e.getMessage());
+                       if (log.isTraceEnabled())
+                               log.debug("Original error.", e);
                } catch (Exception e) {
                        throw new SlcException("Could not notify to JMS", e);
                }
@@ -94,6 +100,12 @@ public class JmsTreeTestResultListener implements TreeTestResultListener {
                        req.setAttachment((SimpleAttachment) attachment);
                        jmsTemplate.convertAndSend(executionEventDestination, req);
 
+               } catch (JmsException e) {
+                       log
+                                       .warn("Could not notify attachment to server: "
+                                                       + e.getMessage());
+                       if (log.isTraceEnabled())
+                               log.debug("Original error.", e);
                } catch (Exception e) {
                        throw new SlcException("Could not notify to JMS", e);
                }
index b295a610f0dd00e615eb05a879b0ab5189315c96..b5246c47c8e4703f56695ca2872c7403570be77d 100644 (file)
                <map-to ns-uri="http://argeo.org/projects/slc/schemas"
                        ns-prefix="slc" />
                <field name="slcExecutionUuid" />
-               <field name="steps" collection="vector"
+               <field name="steps" collection="arraylist"
                        type="org.argeo.slc.process.SlcExecutionStep">
                        <bind-xml auto-naming="deriveByClass" location="steps" />
                </field>
index edc0f735a0f5cd01b7ed0404e28c3327c96c77d4..6eb4c08c0de6c538d3f94755820bf8f03cccc60a 100644 (file)
                <property name="type" column="TYPE" />\r
                <property name="status" column="STATUS" />\r
 \r
-               <list name="steps" cascade="all" table="SLC_EXECUTIONS_STEPS">\r
+               <list name="steps" cascade="all" table="SLC_EXECUTIONS_STEPS"\r
+                       lazy="false">\r
                        <cache usage="read-write" />\r
                        <key column="SLC_EXECUTION_ID" />\r
                        <list-index column="INDX" />\r
-                       <one-to-many
-                               class="org.argeo.slc.process.SlcExecutionStep" />
+                       <one-to-many class="org.argeo.slc.process.SlcExecutionStep" />
                </list>
 
                <map name="attributes" table="SLC_EXEC_ATTRS_MAP" cascade="all"
index 16105e241ef0e4ea10a14270831d500bf9550a3d..d5c1b19da234d2382b6eaa108788047f73cd19ed 100644 (file)
@@ -5,8 +5,6 @@ import java.util.HashMap;
 import java.util.List;
 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.core.structure.tree.TreeSPath;
 import org.argeo.slc.core.structure.tree.TreeSRegistry;
@@ -25,9 +23,6 @@ import org.springframework.validation.MapBindingResult;
 public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean,
                BeanNameAware, StructureAware<TreeSPath>, ResourceLoaderAware {
 
-       private final static Log log = LogFactory
-                       .getLog(DefaultExecutionFlow.class);
-
        private final ExecutionSpec executionSpec;
        private String name = null;
        private Map<String, Object> parameters = new HashMap<String, Object>();
index 05a0e8daef263a5936a22b2d2ad43da7bfac2699..b843c4ff0b83aff31a2185656003320af0db661d 100644 (file)
@@ -14,7 +14,7 @@ import org.argeo.slc.execution.ExecutionModulesManager;
 import org.argeo.slc.process.RealizedFlow;
 import org.argeo.slc.process.SlcExecution;
 import org.argeo.slc.process.SlcExecutionNotifier;
-import org.springframework.util.Assert;
+import org.argeo.slc.process.SlcExecutionStep;
 
 public class DefaultModulesManager implements ExecutionModulesManager {
        private final static Log log = LogFactory
@@ -22,6 +22,7 @@ public class DefaultModulesManager implements ExecutionModulesManager {
 
        private List<ExecutionModule> executionModules = new ArrayList<ExecutionModule>();
        private List<SlcExecutionNotifier> slcExecutionNotifiers = new ArrayList<SlcExecutionNotifier>();
+       private ThreadGroup processesThreadGroup = new ThreadGroup("Processes");
 
        protected ExecutionModule getExecutionModule(String moduleName,
                        String version) {
@@ -39,8 +40,9 @@ public class DefaultModulesManager implements ExecutionModulesManager {
                        String moduleName, String version) {
                ExecutionModule module = getExecutionModule(moduleName, version);
 
-               if(module==null)
-                       throw new SlcException("Module "+moduleName+" ("+version+") not found");
+               if (module == null)
+                       throw new SlcException("Module " + moduleName + " (" + version
+                                       + ") not found");
 
                return module.getDescriptor();
        }
@@ -54,7 +56,7 @@ public class DefaultModulesManager implements ExecutionModulesManager {
        }
 
        public void process(SlcExecution slcExecution) {
-               new ProcessThread(slcExecution).start();
+               new ProcessThread(processesThreadGroup, slcExecution).start();
        }
 
        protected void dispatchUpdateStatus(SlcExecution slcExecution,
@@ -65,22 +67,39 @@ public class DefaultModulesManager implements ExecutionModulesManager {
                }
        }
 
+       protected synchronized void dispatchAddStep(SlcExecution slcExecution,
+                       SlcExecutionStep step) {
+               slcExecution.getSteps().add(step);
+               List<SlcExecutionStep> steps = new ArrayList<SlcExecutionStep>();
+               steps.add(step);
+               for (Iterator<SlcExecutionNotifier> it = slcExecutionNotifiers
+                               .iterator(); it.hasNext();) {
+                       it.next().addSteps(slcExecution, steps);
+               }
+       }
+
        public void setSlcExecutionNotifiers(
                        List<SlcExecutionNotifier> slcExecutionNotifiers) {
                this.slcExecutionNotifiers = slcExecutionNotifiers;
        }
 
+       /** Thread of the SLC Process, starting the sub executions. */
        private class ProcessThread extends Thread {
-               private final SlcExecution slcExecution;
+               private final SlcExecution slcProcess;
+               private final ThreadGroup processThreadGroup;
                private final List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
 
-               public ProcessThread(SlcExecution slcExecution) {
-                       this.slcExecution = slcExecution;
+               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 " + slcExecution
-                                       + "\n##\n");
+                       log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n");
 
                        // FIXME: hack to let the SlcExecution be registered on server
                        try {
@@ -89,11 +108,11 @@ public class DefaultModulesManager implements ExecutionModulesManager {
                                // silent
                        }
 
-                       slcExecution.setStatus(SlcExecution.STATUS_RUNNING);
-                       dispatchUpdateStatus(slcExecution, SlcExecution.STATUS_SCHEDULED,
+                       slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
+                       dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED,
                                        SlcExecution.STATUS_RUNNING);
 
-                       flowsToProcess.addAll(slcExecution.getRealizedFlows());
+                       flowsToProcess.addAll(slcProcess.getRealizedFlows());
 
                        while (flowsToProcess.size() > 0) {
                                RealizedFlow flow = flowsToProcess.remove(0);
@@ -118,25 +137,25 @@ public class DefaultModulesManager implements ExecutionModulesManager {
                                }
                        }
 
-                       slcExecution.setStatus(SlcExecution.STATUS_RUNNING);
-                       dispatchUpdateStatus(slcExecution, SlcExecution.STATUS_RUNNING,
+                       slcProcess.setStatus(SlcExecution.STATUS_FINISHED);
+                       dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING,
                                        SlcExecution.STATUS_FINISHED);
-                       /*
-                        * for (RealizedFlow flow : slcExecution.getRealizedFlows()) {
-                        * ExecutionModule module = getExecutionModule(flow.getModuleName(),
-                        * flow.getModuleVersion()); if (module != null) { ExecutionThread
-                        * thread = new ExecutionThread(flow .getFlowDescriptor(), module);
-                        * thread.start(); } else { throw new
-                        * SlcException("ExecutionModule " + flow.getModuleName() +
-                        * ", version " + flow.getModuleVersion() + " not found."); } }
-                        */
                }
 
                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 ExecutionFlowDescriptor executionFlowDescriptor;
                private final ExecutionModule executionModule;
@@ -145,21 +164,32 @@ public class DefaultModulesManager implements ExecutionModulesManager {
                public ExecutionThread(ProcessThread processThread,
                                ExecutionFlowDescriptor executionFlowDescriptor,
                                ExecutionModule executionModule) {
-                       super("SLC Execution #" /* + executionContext.getUuid() */);
+                       super(processThread.getProcessThreadGroup(), "Flow "
+                                       + executionFlowDescriptor.getName());
                        this.executionFlowDescriptor = executionFlowDescriptor;
                        this.executionModule = executionModule;
                        this.processThread = processThread;
                }
 
                public void run() {
+                       dispatchAddStep(processThread.getSlcProcess(),
+                                       new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START,
+                                                       "Flow " + executionFlowDescriptor.getName()));
+
                        try {
                                executionModule.execute(executionFlowDescriptor);
                        } catch (Exception e) {
                                // TODO: re-throw exception ?
-                               log.error("Execution "/* + executionContext.getUuid() */
-                                               + " failed.", e);
+                               String msg = "Execution of flow "
+                                               + executionFlowDescriptor.getName() + " 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 " + executionFlowDescriptor.getName()));
                        }
                }
        }
index e032e6a0c3f69c0efc9426c21b98e7eabf7e4cc9..361cede76ee3e17979433316a748e0495e056ef6 100644 (file)
@@ -39,7 +39,6 @@ public class FileExecutionResources implements ExecutionResources {
                String osgiInstanceArea = System.getProperty("osgi.instance.area");
                String osgiInstanceAreaDefault = System
                                .getProperty("osgi.instance.area.default");
-               String tempDir = System.getProperty("java.io.tmpdir");
 
                if (osgiInstanceArea != null) {
                        // within OSGi with -data specified
@@ -118,9 +117,9 @@ public class FileExecutionResources implements ExecutionResources {
        }
 
        public File getFile(String relativePath) {
-               Assert.notNull(executionContext, "execution context is null");
 
                if (withExecutionSubdirectory) {
+                       Assert.notNull(executionContext, "execution context is null");
                        String path = baseDir.getPath() + File.separator
                                        + sdf().format(executionContext.getCreationDate())
                                        + executionContext.getUuid();
@@ -167,6 +166,7 @@ public class FileExecutionResources implements ExecutionResources {
                return prefixDatePattern;
        }
 
+       /** Default is true. */
        public void setWithExecutionSubdirectory(Boolean withExecutionSubdirectory) {
                this.withExecutionSubdirectory = withExecutionSubdirectory;
        }
index 9e6c2b5bd89736cc0ea64c879e40ba1f264bdf15..2dc9b867c01595d5aa90b69dce60f3a48b3bead2 100644 (file)
@@ -14,6 +14,7 @@ import org.argeo.slc.execution.ExecutionFlow;
 import org.argeo.slc.execution.ExecutionSpecAttribute;
 
 public class MapExecutionContext implements ExecutionContext {
+
        private final static Log log = LogFactory.getLog(MapExecutionContext.class);
 
        private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
@@ -27,6 +28,7 @@ public class MapExecutionContext implements ExecutionContext {
 
        public MapExecutionContext() {
                uuid = UUID.randomUUID().toString();
+               variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
        }
 
        public void addVariables(
@@ -37,6 +39,8 @@ public class MapExecutionContext implements ExecutionContext {
        public void enterFlow(ExecutionFlow executionFlow) {
                ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
                stack.push(runtime);
+               variables.put(VAR_FLOW_ID, runtime.getUuid());
+               variables.put(VAR_FLOW_NAME, runtime.getExecutionFlow().getName());
 
                if (log.isDebugEnabled())
                        log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #"
index 143bded2a904e9bc55a35bf640a3d26f08e7ad1c..0ea1f7beee7fc8848025d3b0cfb38ddd03b94b4c 100644 (file)
@@ -1,6 +1,9 @@
 package org.argeo.slc.core.execution.tasks;
 
 import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -14,13 +17,22 @@ import org.apache.commons.exec.Executor;
 import org.apache.commons.exec.LogOutputStream;
 import org.apache.commons.exec.PumpStreamHandler;
 import org.apache.commons.exec.ShutdownHookProcessDestroyer;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.NotImplementedException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
+import org.argeo.slc.core.structure.tree.TreeSPath;
+import org.argeo.slc.core.structure.tree.TreeSRelatedHelper;
+import org.argeo.slc.core.test.SimpleResultPart;
+import org.argeo.slc.structure.StructureAware;
+import org.argeo.slc.test.TestResult;
+import org.argeo.slc.test.TestStatus;
+import org.springframework.core.io.Resource;
 
 /** Execute and OS system call. */
-public class SystemCall implements Runnable {
+public class SystemCall extends TreeSRelatedHelper implements Runnable,
+               StructureAware<TreeSPath> {
        private final Log log = LogFactory.getLog(getClass());
 
        private String execDir;
@@ -33,13 +45,34 @@ public class SystemCall implements Runnable {
        private String stdErrLogLevel = "ERROR";
        private String stdOutLogLevel = "INFO";
 
+       private Resource stdOutFile = null;
+       private Resource stdErrFile = null;
+
        private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
        private Map<String, String> osCmds = new HashMap<String, String>();
        private Map<String, String> environmentVariables = new HashMap<String, String>();
 
        private Long watchdogTimeout = 24 * 60 * 60 * 1000l;
 
+       private TestResult testResult;
+
        public void run() {
+               // Log writers
+               final Writer stdOutWriter;
+               final Writer stdErrWriter;
+               if (stdOutFile != null) {
+                       stdOutWriter = createWriter(stdOutFile);
+               } else
+                       stdOutWriter = null;
+               if (stdErrFile != null) {
+                       stdErrWriter = createWriter(stdErrFile);
+               } else {
+                       if (stdOutFile != null) {
+                               stdErrWriter = createWriter(stdOutFile);
+                       } else
+                               stdErrWriter = null;
+               }
+
                try {
                        if (log.isTraceEnabled()) {
                                log.debug("os.name=" + System.getProperty("os.name"));
@@ -76,14 +109,19 @@ public class SystemCall implements Runnable {
 
                        Executor executor = new DefaultExecutor();
                        executor.setWatchdog(new ExecuteWatchdog(watchdogTimeout));
+
                        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(
                                        new LogOutputStream() {
                                                protected void processLine(String line, int level) {
                                                        log(stdOutLogLevel, line);
+                                                       if (stdOutWriter != null)
+                                                               appendLineToFile(stdOutWriter, line);
                                                }
                                        }, new LogOutputStream() {
                                                protected void processLine(String line, int level) {
                                                        log(stdErrLogLevel, line);
+                                                       if (stdErrWriter != null)
+                                                               appendLineToFile(stdErrWriter, line);
                                                }
                                        }, null);
                        executor.setStreamHandler(pumpStreamHandler);
@@ -129,11 +167,24 @@ public class SystemCall implements Runnable {
                                        if (log.isDebugEnabled())
                                                log.debug("Process " + commandLine
                                                                + " properly completed.");
+                                       if (testResult != null) {
+                                               forwardPath(testResult, null);
+                                               testResult.addResultPart(new SimpleResultPart(
+                                                               TestStatus.PASSED, "Process " + commandLine
+                                                                               + " properly completed."));
+                                       }
                                }
 
                                public void onProcessFailed(ExecuteException e) {
-                                       throw new SlcException("Process " + commandLine
-                                                       + " failed.", e);
+                                       if (testResult != null) {
+                                               forwardPath(testResult, null);
+                                               testResult.addResultPart(new SimpleResultPart(
+                                                               TestStatus.ERROR, "Process " + commandLine
+                                                                               + " failed.", e));
+                                       } else {
+                                               throw new SlcException("Process " + commandLine
+                                                               + " failed.", e);
+                                       }
                                }
                        };
 
@@ -150,6 +201,9 @@ public class SystemCall implements Runnable {
                                                executeResultHandler);
                } catch (Exception e) {
                        throw new SlcException("Could not execute command " + cmd, e);
+               } finally {
+                       IOUtils.closeQuietly(stdOutWriter);
+                       IOUtils.closeQuietly(stdErrWriter);
                }
 
        }
@@ -180,6 +234,26 @@ public class SystemCall implements Runnable {
                        throw new SlcException("Unknown log level " + logLevel);
        }
 
+       protected void appendLineToFile(Writer writer, String line) {
+               try {
+                       writer.append(line).append('\n');
+               } catch (IOException e) {
+                       log.error("Cannot write to log file", e);
+               }
+       }
+
+       protected Writer createWriter(Resource target) {
+               FileWriter writer = null;
+               try {
+                       File file = target.getFile();
+                       writer = new FileWriter(file, true);
+               } catch (IOException e) {
+                       log.error("Cannot create log file " + target, e);
+                       IOUtils.closeQuietly(writer);
+               }
+               return writer;
+       }
+
        public void setCmd(String command) {
                this.cmd = command;
        }
@@ -220,4 +294,16 @@ public class SystemCall implements Runnable {
                this.watchdogTimeout = watchdogTimeout;
        }
 
+       public void setStdOutFile(Resource stdOutFile) {
+               this.stdOutFile = stdOutFile;
+       }
+
+       public void setStdErrFile(Resource stdErrFile) {
+               this.stdErrFile = stdErrFile;
+       }
+
+       public void setTestResult(TestResult testResult) {
+               this.testResult = testResult;
+       }
+
 }
index 8dc00784e8dfc7ba5e97d5834016fd02f1192d19..b0cc87bf9c8a6d96b7f930455c44dba31504fb30 100644 (file)
@@ -1,16 +1,22 @@
 package org.argeo.slc.core.structure.tree;\r
 \r
 import org.argeo.slc.core.structure.SimpleSElement;\r
+import org.argeo.slc.structure.StructureAware;\r
 import org.argeo.slc.structure.StructureElement;\r
 import org.argeo.slc.structure.StructureRegistry;\r
 \r
 /**\r
- * Provides default implementations of some methods of <code>TreeSRelated</code>.\r
+ * Provides default implementations of some methods of <code>TreeSRelated</code>\r
+ * .\r
  */\r
 public abstract class TreeSRelatedHelper implements TreeSRelated {\r
        private TreeSPath basePath;\r
        private StructureRegistry<TreeSPath> registry;\r
 \r
+       // private ThreadLocal<TreeSPath> basePath = new ThreadLocal<TreeSPath>();\r
+       // private ThreadLocal<StructureRegistry<TreeSPath>> registry = new\r
+       // ThreadLocal<StructureRegistry<TreeSPath>>();\r
+\r
        public TreeSPath getBasePath() {\r
                return basePath;\r
        }\r
@@ -21,7 +27,7 @@ public abstract class TreeSRelatedHelper implements TreeSRelated {
 \r
        public void notifyCurrentPath(StructureRegistry<TreeSPath> registry,\r
                        TreeSPath path) {\r
-               basePath = path;\r
+               this.basePath = path;\r
                this.registry = registry;\r
        }\r
 \r
@@ -29,4 +35,24 @@ public abstract class TreeSRelatedHelper implements TreeSRelated {
                return new SimpleSElement(key);\r
        }\r
 \r
+       /**\r
+        * Checks wether the object is {@link StructureAware} and forward path and\r
+        * registry. null safe for both arguments.\r
+        */\r
+       @SuppressWarnings(value = { "unchecked" })\r
+       protected void forwardPath(Object obj, String childName) {\r
+               if (obj == null)\r
+                       return;\r
+\r
+               if (obj instanceof StructureAware && basePath != null) {\r
+                       TreeSPath path;\r
+                       if (childName != null)\r
+                               path = basePath.createChild(childName);\r
+                       else\r
+                               path = basePath;\r
+\r
+                       ((StructureAware<TreeSPath>) obj).notifyCurrentPath(registry, path);\r
+               }\r
+       }\r
+\r
 }\r
index c7cdc604d1fe7f5019b388ec3d0f4a86a07e69ce..56feca86c96f058ccdfa130443920edd737fb3b8 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.slc.msg.process;\r
 \r
+import java.util.ArrayList;\r
 import java.util.List;\r
 import java.util.Vector;\r
 \r
@@ -7,7 +8,7 @@ import org.argeo.slc.process.SlcExecutionStep;
 \r
 public class SlcExecutionStepsRequest {\r
        private String slcExecutionUuid;\r
-       private List<SlcExecutionStep> steps = new Vector<SlcExecutionStep>();\r
+       private List<SlcExecutionStep> steps = new ArrayList<SlcExecutionStep>();\r
 \r
        public SlcExecutionStepsRequest() {\r
 \r
index bbea1bb2570be6a2e05c11dca96a2e2935b95817..8bf94160175e87784f2ed313bda2c8582b90af3f 100644 (file)
@@ -53,7 +53,6 @@ public abstract class SlcExecutionTestUtils {
                assertNotNull(reached);\r
                assertEquals(expected.getUuid(), reached.getUuid());\r
                assertEquals(expected.getType(), reached.getType());\r
-               assertEquals(expected.logAsString(), reached.logAsString());\r
                assertDateSec(expected.getBegin(), reached.getBegin());\r
        }\r
 \r
diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.main/META-INF/MANIFEST.MF b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.main/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..d3ec3e1
--- /dev/null
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0\r
+Bundle-SymbolicName: org.argeo.slc.server.main\r
+Bundle-Version: 0.11.4.SNAPSHOT\r
+Bundle-Name: SLC Server Main\r
+Require-Bundle: org.argeo.slc.server,\r
+ org.argeo.slc.specs,\r
+ org.argeo.slc.support.simple\r
diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.main/META-INF/spring/main.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.main/META-INF/spring/main.xml
new file mode 100644 (file)
index 0000000..6c4b88f
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/osgi  
+       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd
+       http://www.springframework.org/schema/beans   
+       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+       <bundle id="spring.osgi.web.extender" symbolic-name="org.springframework.osgi.web.extender"
+               action="start" />
+       <bundle id="catalina" symbolic-name="org.argeo.dep.osgi.catalina.start"
+               action="start" />
+       <bundle id="activemq" symbolic-name="org.argeo.slc.server.activemq"
+               action="start" />
+       <bundle id="hibernate" symbolic-name="org.argeo.slc.server.hibernate"
+               action="start" />
+       <bundle id="services" symbolic-name="org.argeo.slc.server.services"
+               action="start" />
+       <bundle id="jms" symbolic-name="org.argeo.slc.server.jms"
+               action="start" />
+       <bundle id="webapp" symbolic-name="org.argeo.slc.webapp" action="start" />
+</beans:beans>
\ No newline at end of file