2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.core
.execution
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
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
;
30 /** Thread of a single execution */
31 public class ExecutionThread
extends Thread
{
32 public final static String SYSPROP_EXECUTION_AUTO_UPGRADE
= "slc.execution.autoupgrade";
34 private final static Log log
= LogFactory
.getLog(ExecutionThread
.class);
36 private final RealizedFlow realizedFlow
;
37 private final ProcessThread processThread
;
39 private List
<Runnable
> destructionCallbacks
= new ArrayList
<Runnable
>();
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
;
50 // authenticate thread
51 Authentication authentication
= getProcessThreadGroup()
53 if (authentication
== null)
54 throw new SlcException("Can only execute authenticated threads");
55 SecurityContextHolder
.getContext().setAuthentication(authentication
);
57 // Retrieve execution flow descriptor
58 ExecutionFlowDescriptor executionFlowDescriptor
= realizedFlow
60 String flowName
= executionFlowDescriptor
.getName();
62 dispatchAddStep(new ExecutionStep(realizedFlow
.getModuleName(),
63 ExecutionStep
.PHASE_START
, "Flow " + flowName
));
66 String autoUpgrade
= System
67 .getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE
);
68 if (autoUpgrade
!= null && autoUpgrade
.equals("true"))
69 processThread
.getExecutionModulesManager().upgrade(
70 realizedFlow
.getModuleNameVersion());
73 processThread
.getExecutionModulesManager().execute(realizedFlow
);
75 } catch (Exception e
) {
76 // TODO: re-throw exception ?
77 String msg
= "Execution of flow " + flowName
+ " failed.";
79 dispatchAddStep(new ExecutionStep(realizedFlow
.getModuleName(),
80 ExecutionStep
.ERROR
, msg
+ " " + e
.getMessage()));
81 processThread
.notifyError();
83 processThread
.flowCompleted();
84 dispatchAddStep(new ExecutionStep(realizedFlow
.getModuleName(),
85 ExecutionStep
.PHASE_END
, "Flow " + flowName
));
86 processDestructionCallbacks();
90 private void dispatchAddStep(ExecutionStep step
) {
91 processThread
.getProcessThreadGroup().dispatchAddStep(step
);
94 private synchronized void processDestructionCallbacks() {
95 for (int i
= destructionCallbacks
.size() - 1; i
>= 0; i
--) {
97 destructionCallbacks
.get(i
).run();
98 } catch (Exception e
) {
99 log
.warn("Could not process destruction callback " + i
100 + " in thread " + getName(), e
);
106 * Gather object destruction callback to be called in reverse order at the
109 synchronized void registerDestructionCallback(String name
, Runnable callback
) {
110 destructionCallbacks
.add(callback
);
113 protected ProcessThreadGroup
getProcessThreadGroup() {
114 return processThread
.getProcessThreadGroup();
117 public RealizedFlow
getRealizedFlow() {