]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionThread.java
ec69c68d7f1ab103c87132c74ea147be692759e4
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / ExecutionThread.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.core.execution;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.slc.SlcException;
24 import org.argeo.slc.execution.ExecutionFlowDescriptor;
25 import org.argeo.slc.execution.ExecutionStep;
26 import org.argeo.slc.execution.RealizedFlow;
27 import org.springframework.security.Authentication;
28 import org.springframework.security.context.SecurityContextHolder;
29
30 /** Thread of a single execution */
31 public class ExecutionThread extends Thread {
32 public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade";
33
34 private final static Log log = LogFactory.getLog(ExecutionThread.class);
35
36 private final RealizedFlow realizedFlow;
37 private final ProcessThread processThread;
38
39 private List<Runnable> destructionCallbacks = new ArrayList<Runnable>();
40
41 public ExecutionThread(ProcessThread processThread,
42 RealizedFlow realizedFlow) {
43 super(processThread.getProcessThreadGroup(), "Flow "
44 + realizedFlow.getFlowDescriptor().getName());
45 this.realizedFlow = realizedFlow;
46 this.processThread = processThread;
47 }
48
49 public void run() {
50 // authenticate thread
51 Authentication authentication = getProcessThreadGroup()
52 .getAuthentication();
53 if (authentication == null)
54 throw new SlcException("Can only execute authenticated threads");
55 SecurityContextHolder.getContext().setAuthentication(authentication);
56
57 // Retrieve execution flow descriptor
58 ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow
59 .getFlowDescriptor();
60 String flowName = executionFlowDescriptor.getName();
61
62 dispatchAddStep(new ExecutionStep(realizedFlow.getModuleName(),
63 ExecutionStep.PHASE_START, "Flow " + flowName));
64
65 try {
66 String autoUpgrade = System
67 .getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE);
68 if (autoUpgrade != null && autoUpgrade.equals("true"))
69 processThread.getExecutionModulesManager().upgrade(
70 realizedFlow.getModuleNameVersion());
71
72 // START FLOW
73 processThread.getExecutionModulesManager().execute(realizedFlow);
74 // END FLOW
75 } catch (Exception e) {
76 // TODO: re-throw exception ?
77 String msg = "Execution of flow " + flowName + " failed.";
78 log.error(msg, e);
79 dispatchAddStep(new ExecutionStep(realizedFlow.getModuleName(),
80 ExecutionStep.ERROR, msg + " " + e.getMessage()));
81 processThread.notifyError();
82 } finally {
83 processThread.flowCompleted();
84 dispatchAddStep(new ExecutionStep(realizedFlow.getModuleName(),
85 ExecutionStep.PHASE_END, "Flow " + flowName));
86 processDestructionCallbacks();
87 }
88 }
89
90 private void dispatchAddStep(ExecutionStep step) {
91 processThread.getProcessThreadGroup().dispatchAddStep(step);
92 }
93
94 private synchronized void processDestructionCallbacks() {
95 for (int i = destructionCallbacks.size() - 1; i >= 0; i--) {
96 try {
97 destructionCallbacks.get(i).run();
98 } catch (Exception e) {
99 log.warn("Could not process destruction callback " + i
100 + " in thread " + getName(), e);
101 }
102 }
103 }
104
105 /**
106 * Gather object destruction callback to be called in reverse order at the
107 * end of the thread
108 */
109 synchronized void registerDestructionCallback(String name, Runnable callback) {
110 destructionCallbacks.add(callback);
111 }
112
113 protected ProcessThreadGroup getProcessThreadGroup() {
114 return processThread.getProcessThreadGroup();
115 }
116
117 public RealizedFlow getRealizedFlow() {
118 return realizedFlow;
119 }
120
121 }