1 package org
.argeo
.slc
.runtime
;
3 import java
.security
.AccessControlContext
;
4 import java
.security
.AccessController
;
5 import java
.security
.PrivilegedActionException
;
6 import java
.security
.PrivilegedExceptionAction
;
7 import java
.util
.ArrayList
;
10 import javax
.security
.auth
.Subject
;
12 import org
.argeo
.api
.cms
.CmsLog
;
13 import org
.argeo
.slc
.execution
.ExecutionFlowDescriptor
;
14 import org
.argeo
.slc
.execution
.ExecutionModulesManager
;
15 import org
.argeo
.slc
.execution
.ExecutionStep
;
16 import org
.argeo
.slc
.execution
.FlowConfigurationException
;
17 import org
.argeo
.slc
.execution
.RealizedFlow
;
19 /** Thread of a single execution */
20 public class ExecutionThread
extends Thread
{
21 public final static String SYSPROP_EXECUTION_AUTO_UPGRADE
= "slc.execution.autoupgrade";
22 private final static CmsLog log
= CmsLog
.getLog(ExecutionThread
.class);
24 private ExecutionModulesManager executionModulesManager
;
25 private final RealizedFlow realizedFlow
;
26 private final AccessControlContext accessControlContext
;
28 private List
<Runnable
> destructionCallbacks
= new ArrayList
<Runnable
>();
30 public ExecutionThread(ProcessThreadGroup processThreadGroup
, ExecutionModulesManager executionModulesManager
,
31 RealizedFlow realizedFlow
) {
32 super(processThreadGroup
, "Flow " + realizedFlow
.getFlowDescriptor().getName());
33 this.realizedFlow
= realizedFlow
;
34 this.executionModulesManager
= executionModulesManager
;
35 accessControlContext
= AccessController
.getContext();
39 // authenticate thread
40 // Authentication authentication = getProcessThreadGroup()
41 // .getAuthentication();
42 // if (authentication == null)
43 // throw new SlcException("Can only execute authenticated threads");
44 // SecurityContextHolder.getContext().setAuthentication(authentication);
46 // Retrieve execution flow descriptor
47 ExecutionFlowDescriptor executionFlowDescriptor
= realizedFlow
.getFlowDescriptor();
48 String flowName
= executionFlowDescriptor
.getName();
50 getProcessThreadGroup().dispatchAddStep(
51 new ExecutionStep(realizedFlow
.getModuleName(), ExecutionStep
.PHASE_START
, "Flow " + flowName
));
54 Subject subject
= Subject
.getSubject(accessControlContext
);
56 Subject
.doAs(subject
, new PrivilegedExceptionAction
<Void
>() {
59 public Void
run() throws Exception
{
60 String autoUpgrade
= System
.getProperty(SYSPROP_EXECUTION_AUTO_UPGRADE
);
61 if (autoUpgrade
!= null && autoUpgrade
.equals("true"))
62 executionModulesManager
.upgrade(realizedFlow
.getModuleNameVersion());
63 executionModulesManager
.start(realizedFlow
.getModuleNameVersion());
67 executionModulesManager
.execute(realizedFlow
);
73 } catch (PrivilegedActionException privilegedActionException
) {
74 throw (Exception
) privilegedActionException
.getCause();
76 } catch (FlowConfigurationException e
) {
77 String msg
= "Configuration problem with flow " + flowName
+ ":\n" + e
.getMessage();
79 getProcessThreadGroup().dispatchAddStep(
80 new ExecutionStep(realizedFlow
.getModuleName(), ExecutionStep
.ERROR
, msg
+ " " + e
.getMessage()));
81 } catch (Exception e
) {
82 // TODO: re-throw exception ?
83 String msg
= "Execution of flow " + flowName
+ " failed.";
85 getProcessThreadGroup().dispatchAddStep(
86 new ExecutionStep(realizedFlow
.getModuleName(), ExecutionStep
.ERROR
, msg
+ " " + e
.getMessage()));
88 getProcessThreadGroup().dispatchAddStep(
89 new ExecutionStep(realizedFlow
.getModuleName(), ExecutionStep
.PHASE_END
, "Flow " + flowName
));
90 processDestructionCallbacks();
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
+ " in thread " + getName(), e
);
105 * Gather object destruction callback to be called in reverse order at the
108 public synchronized void registerDestructionCallback(String name
, Runnable callback
) {
109 destructionCallbacks
.add(callback
);
112 protected ProcessThreadGroup
getProcessThreadGroup() {
113 return (ProcessThreadGroup
) getThreadGroup();