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
.ExecutionModulesManager
;
26 import org
.argeo
.slc
.execution
.ExecutionStep
;
27 import org
.argeo
.slc
.execution
.RealizedFlow
;
28 import org
.springframework
.security
.core
.Authentication
;
29 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
31 /** Thread of a single execution */
32 public class ExecutionThread
extends Thread
{
33 public final static String SYSPROP_EXECUTION_AUTO_UPGRADE
= "slc.execution.autoupgrade";
34 private final static Log log
= LogFactory
.getLog(ExecutionThread
.class);
36 private ExecutionModulesManager executionModulesManager
;
37 private final RealizedFlow realizedFlow
;
39 private List
<Runnable
> destructionCallbacks
= new ArrayList
<Runnable
>();
41 public ExecutionThread(ProcessThreadGroup processThreadGroup
,
42 ExecutionModulesManager executionModulesManager
,
43 RealizedFlow realizedFlow
) {
44 super(processThreadGroup
, "Flow "
45 + realizedFlow
.getFlowDescriptor().getName());
46 this.realizedFlow
= realizedFlow
;
47 this.executionModulesManager
= executionModulesManager
;
51 // authenticate thread
52 Authentication authentication
= getProcessThreadGroup()
54 if (authentication
== null)
55 throw new SlcException("Can only execute authenticated threads");
56 SecurityContextHolder
.getContext().setAuthentication(authentication
);
58 // Retrieve execution flow descriptor
59 ExecutionFlowDescriptor executionFlowDescriptor
= realizedFlow
61 String flowName
= executionFlowDescriptor
.getName();
63 getProcessThreadGroup().dispatchAddStep(
64 new ExecutionStep(realizedFlow
.getModuleName(),
65 ExecutionStep
.PHASE_START
, "Flow " + flowName
));
68 String autoUpgrade
= System
69 .getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE
);
70 if (autoUpgrade
!= null && autoUpgrade
.equals("true"))
71 executionModulesManager
.upgrade(realizedFlow
72 .getModuleNameVersion());
73 executionModulesManager
.start(realizedFlow
.getModuleNameVersion());
77 executionModulesManager
.execute(realizedFlow
);
79 } catch (FlowConfigurationException e
) {
80 String msg
= "Configuration problem with flow " + flowName
+ ":\n"
83 getProcessThreadGroup().dispatchAddStep(
84 new ExecutionStep(realizedFlow
.getModuleName(),
85 ExecutionStep
.ERROR
, msg
+ " " + e
.getMessage()));
86 } catch (Exception e
) {
87 // TODO: re-throw exception ?
88 String msg
= "Execution of flow " + flowName
+ " failed.";
90 getProcessThreadGroup().dispatchAddStep(
91 new ExecutionStep(realizedFlow
.getModuleName(),
92 ExecutionStep
.ERROR
, msg
+ " " + e
.getMessage()));
94 getProcessThreadGroup().dispatchAddStep(
95 new ExecutionStep(realizedFlow
.getModuleName(),
96 ExecutionStep
.PHASE_END
, "Flow " + flowName
));
97 processDestructionCallbacks();
101 private synchronized void processDestructionCallbacks() {
102 for (int i
= destructionCallbacks
.size() - 1; i
>= 0; i
--) {
104 destructionCallbacks
.get(i
).run();
105 } catch (Exception e
) {
106 log
.warn("Could not process destruction callback " + i
107 + " in thread " + getName(), e
);
113 * Gather object destruction callback to be called in reverse order at the
116 synchronized void registerDestructionCallback(String name
, Runnable callback
) {
117 destructionCallbacks
.add(callback
);
120 protected ProcessThreadGroup
getProcessThreadGroup() {
121 return (ProcessThreadGroup
) getThreadGroup();