Variable missing in assignment handler
lpiccoli Jul 14, 2009 5:39 AMhi all,
my swimlane assignment handler is unable to retrieve variables that have been previous set in both root token and local token.
the test involves a forkhandler, sub process and swimlane assignment handler.
When inside the SwimlaneAssignmentHandler getVariable() returns null which is not what i was expecting
public void assign(Assignable assignable, ExecutionContext executionContext) { assertNotNull("shouldnt be null", executionContext.getVariable(IDENTIFIER)); String expression = (String)executionContext.getVariable(EXPRESSION); assertNotNull( "shouldnt be null", expression );
as it was set in the previous ActivityForkActionHandler.execute()
public void execute(final ExecutionContext executionContext) throws Exception { .....stuff Token(rootToken, "ITP" + item.getId()); //TODO -lp newToken.setTerminationImplicit(true); executionContext.getJbpmContext().getSession().save(newToken); final ExecutionContext newExecutionContext = new ExecutionContext(newToken); newExecutionContext.getContextInstance().createVariable( EXPRESSION, item.getResponsibleExpression(), newToken);
I am not sure if the problem is with my process definition of the swimlan assignment
<swimlane name='responsible' > <assignment class='com.asteriski.itpflow.action.ActivityForkActionHandlerTest$SwimlaneAssignmentHandler'/> </swimlane>
or with how i am setting the local variables against token in the forkHandler above
i have a attached the entire test case below. It is a bit tedious but i needed to include all the handler code.
any help is most appreciated.
public class ActivityForkActionHandlerTest extends AbstractJbpmTestCase { static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance("jbpm.test.cfg.xml"); public void testForkHandlerAndSubProcess() throws Exception { JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext(); ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlString( "<process-definition name='sub'>" + " <start-state>" + " <transition to='wait' />" + " </start-state>" + " <swimlane name='responsible' >" + " <assignment class='com.asteriski.itpflow.action.ActivityForkActionHandlerTest$SwimlaneAssignmentHandler' />" + " </swimlane>" + " <task-node name='wait' >" + " <description>'just waiting'</description>" + " <task name='task-waiting' signal='block' swimlane='responsible'>"+ " </task>" + " <transition to='end_sub'></transition>" + " </task-node>" + " <end-state name='end_sub' />" + "</process-definition>" ); jbpmContext.deployProcessDefinition(subProcessDefinition); ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString( "<process-definition" + " name='super'>" + "<start-state name='start'> " + "<transition name='to_state' to='forkActivities'>" + "</transition>" + "</start-state>" + " <node name='forkActivities'>" + " <action class='com.asteriski.itpflow.action.ActivityForkActionHandlerTest$ActivityForkActionHandler' config-type='bean' name='ActivityForkActionHandler'></action>" + " <description>" + " find all activities that have no blocking state and generate a testign request"+ " </description>" + " <transition to='Sub Process'></transition>" + " </node>" + "<process-state name='Sub Process'>" + "<sub-process name='sub'/>" + "<transition to='task-node1'></transition>" + "</process-state>" + "<task-node name='task-node1'> " + " <task name='task1'>" + " </task>" + " <transition to='end' name='to_end'> " + " </transition>" + "</task-node>" + "<end-state name='end'></end-state> " + "</process-definition>"); jbpmContext.deployProcessDefinition(superProcessDefinition); ProcessInstance processInstance = jbpmContext.newProcessInstance("super"); ProcessState processState = (ProcessState) superProcessDefinition.getNode("Sub Process"); processState.setSubProcessDefinition(subProcessDefinition); processInstance.getContextInstance().createVariable(Constant.ITP_ID_JBPM_CONTEXT_IDENTIFIER, 1); // After construction, the process execution has one main path // of execution (=the root token). Token rootToken = processInstance.getRootToken(); assertEquals( "start", rootToken.getNode().getName()); // Move the process instance to the task rootToken.signal(); assertEquals( "Sub Process", rootToken.getNode().getName()); //get the sub process ProcessInstance subProcessInstance = rootToken.getSubProcessInstance(); assertSame(subProcessDefinition, subProcessInstance.getProcessDefinition()); Token subToken = subProcessInstance.getRootToken(); // Move the process instance to the task subToken.signal(); assertEquals( "end_sub", subToken.getNode().getName()); } public static class SwimlaneAssignmentHandler implements AssignmentHandler { Logger log = Logger.getLogger(ResponsibleSwimlaneAssignmentHandler.class); private static final long serialVersionUID = 1L; public void assign(Assignable assignable, ExecutionContext executionContext) { assertNotNull("shouldnt be null", executionContext.getVariable(Constant.ITP_ID_JBPM_CONTEXT_IDENTIFIER)); String expression = (String)executionContext.getVariable(Constant.ASSIGNMENT_RESPONSIBLE_EXPRESSION_JBPM_CONTEXT_IDENTIFIER); assertNotNull( "shouldnt be null", expression ); assignable.setPooledActors( expression ); } } public static class ActivityForkActionHandler implements ActionHandler, Constant { Logger log = Logger.getLogger( ActivityForkActionHandler.class ); /** * Create a new child token for each item in list. * * @param executionContext * @throws Exception */ @SuppressWarnings("unchecked") public void execute(final ExecutionContext executionContext) throws Exception { log.debug("execute"); long id =Long.valueOf( executionContext.getContextInstance().getVariable(ITP_ID_JBPM_CONTEXT_IDENTIFIER).toString() ); log.debug("execute itp d:" + id); Collection<ITPItem> activities = getActivities( id ); if( activities != null ){ final Token rootToken = executionContext.getToken(); final Node node = executionContext.getNode(); log.debug( "node name:" + node.getName() ); log.debug( "node getDescription:" + node.getDescription() ); log.debug( "node getDefaultLeavingTransition:" + node.getDefaultLeavingTransition().getName() ); final Transition transition = (Transition) node.getLeavingTransitions().get(0); //TODO must work out which transition to use log.debug( "transition name:" + transition.getName() ); Collection<ExecutionContext> newContextList = new ArrayList<ExecutionContext>(); //newExecutionContext.getContextInstance().createVariable(as, item, newToken); // for (Iterator iterator = activities.iterator(); iterator.hasNext();) { ITPItem item = (ITPItem) iterator.next(); log.debug( "item id:" + item.getId() ); final Token newToken = new Token(rootToken, "ITP" + item.getId()); //TODO -lp newToken.setTerminationImplicit(true); executionContext.getJbpmContext().getSession().save(newToken); final ExecutionContext newExecutionContext = new ExecutionContext(newToken); newExecutionContext.getContextInstance().createVariable( ASSIGNMENT_RESPONSIBLE_EXPRESSION_JBPM_CONTEXT_IDENTIFIER, item.getResponsibleExpression(), newToken); log.debug("execute getVariable:" + newExecutionContext.getVariable(ASSIGNMENT_RESPONSIBLE_EXPRESSION_JBPM_CONTEXT_IDENTIFIER)); newContextList.add(newExecutionContext); } // Now, let each new token leave the node. // for (Iterator<ExecutionContext> iterator = newContextList.iterator(); iterator.hasNext();) { ExecutionContext context = iterator.next(); //go via transition node.leave(context, transition); } } log.debug("leaving node" ); executionContext.leaveNode(); } /** * TODO the test version needs to be mocked somehow * @param id * @return */ public Collection<ITPItem> getActivities( long id) { log.trace("getActivities"); Collection<ITPItem> items = new ArrayList<ITPItem>(); ITPItem itp1 = new ITPItem(); itp1.setId(1); itp1.setResponsibleExpression("hello1"); ITPItem itp2 = new ITPItem(); itp2.setId(2); itp2.setResponsibleExpression("hello2"); ITPItem itp3 = new ITPItem(); itp3.setId(3); itp3.setResponsibleExpression("hello3"); items.add(itp1); items.add(itp2); items.add(itp3); return items; } } }
-lp