AnsweredAssumed Answered

CallActiviti to select subprocess based upon an expression

Question asked by tdm on Mar 6, 2012
Latest reply on Mar 29, 2012 by tdm
Hello

With activiti 5.9 the possability of using an expression for a calledElemend in a CallActiviti was introduced (ACT-831)
This is a feature, which we could use in a upcoming application, which we are currently planing.

To get a feeling how it works I wrote a test. But it seems I'm doing something wrong.
My problem is, I set the variable which defines the subprocess every time when I complete the user task of the main process.
Once I set the first subprocess and another time the second subprocess. But it always takes the first one I set.

What could be wrong?

Here is what I'm doing:

The main process which is the parent process and it contains the CallActivity

  <process id="mainProcess" name="MainProcess">
    <documentation>Main Process for testing purposes. Contains a call activiti with a place holder as calledElement</documentation>
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="mainProcessUserTask" name="User Task" activiti:candidateGroups="players"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <callActivity id="mainProcessCallActivity" name="Call activity" calledElement="${subProcess}"></callActivity>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="mainProcessUserTask"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="mainProcessUserTask" targetRef="mainProcessCallActivity"></sequenceFlow>
    <sequenceFlow id="flow3" name="" sourceRef="mainProcessCallActivity" targetRef="endevent1"></sequenceFlow>
  </process>

and two sub Processes which are in different files

  <process id="subProcess1" name="SubProcess1">
    <documentation>Subprocess 1</documentation>
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="subProcess1UserTask" name="User Task" activiti:candidateGroups="HeadMembers"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="subProcess1UserTask"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="subProcess1UserTask" targetRef="endevent1"></sequenceFlow>
  </process>


  <process id="subProcess2" name="SubProcess2">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="subProcess2UserTask" name="User Task" activiti:candidateUsers="HumanResources"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="subProcess2UserTask"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="subProcess2UserTask" targetRef="endevent1"></sequenceFlow>
  </process>

my test looks as follows


    @Deployment(resources= {"diagrams/MainProcess.bpmn20.xml", "diagrams/SubProcess1.bpmn20.xml", "diagrams/SubProcess2.bpmn20.xml"})
    public void testSubProcessWithPlaceholder(){
        System.out.println("SubProcessWithPlaceholder");
        // Start the first instance of the main process
        ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey("mainProcess");       
        //Get the user task and check it
        Task task1 = taskService.createTaskQuery().processInstanceId(processInstance1.getId()).singleResult();
        assertNotNull(task1);
        assertEquals("mainProcessUserTask", task1.getTaskDefinitionKey());
       
        // set the variable which subprocess should be started - tis thime subProcess1
        taskService.setVariable(task1.getId(), "subProcess", "subProcess1");     
        taskService.complete(task1.getId());      
       
        // check if process went to subprocess 1 and is currently in subProcess1UserTask
        task1 = taskService.createTaskQuery().taskDefinitionKey("subProcess1UserTask").singleResult();
        assertNotNull(task1);
        taskService.complete(task1.getId());
       
        assertEquals(0, runtimeService.createProcessInstanceQuery().count());
       
        // Start the second instance of the main process
        ProcessInstance processInstance2 = runtimeService.startProcessInstanceByKey("mainProcess");
        //Get the user task and check it
        Task task2 = taskService.createTaskQuery().processInstanceId(processInstance2.getId()).singleResult();
        assertNotNull(task2);
        assertEquals("mainProcessUserTask", task2.getTaskDefinitionKey());
       
        // set the variable which subprocess should be started - this time subProcess2
        taskService.setVariable(task2.getId(), "subProcessPlaceholder", "subProcess2");   
        taskService.complete(task2.getId());
       
        // the process was routed to subProcess1, so subProcess2UserTask is null
        task2 = taskService.createTaskQuery().taskDefinitionKey("subProcess2UserTask").singleResult();
        assertNull(task2);
        // but because the process was routed to SubProcess1 subProcess1UserTask exists
        task2 = taskService.createTaskQuery().taskDefinitionKey("subProcess1UserTask").singleResult();
        assertNotNull(task2);
        taskService.complete(task2.getId());
               
        assertEquals(0, runtimeService.createProcessInstanceQuery().count());
    }

Thanks in advance.

Regards,
Marco

Outcomes