Set variables on task in camunda

knobli picture knobli · Aug 28, 2014 · Viewed 9.2k times · Source

Is it possible to set variables to an user task in the camunda definition xml?

I would like to set a variable (deletable), that changes from task to task.

Instance of Task 1: deletable = true
Instance of Task 2: deletable = true
Instance of Task 3: deletable = false
Instance of Task 4: deletable = false

This is the actual task configuration:

<bpmn2:userTask id="createtrunkdoc" camunda:candidateUsers="${candidateUser}" camunda:candidateGroups="provisioning" camunda:assignee="${candidateUser}" name="Create New&#xD;&#xA;Trunk Request">
  <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
  <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
</bpmn2:userTask>

Test case (camunda: 7.1.0-Final)

@RunWith(MockitoJUnitRunner.class)
public class testTest {

    @Rule
    public ProcessEngineRule processEngineRule = new ProcessEngineRule();

    @Test
    @Deployment(resources = { "test.bpmn20.xml" })
    public void testHappyPath() {
        ProcessInstance processInstance = runtimeService().startProcessInstanceByKey("nipa-createsipinterconnect");

        assertThat(processInstance).isStarted().isNotEnded().task().hasDefinitionKey("reviewnewtrunk");

        Task task = taskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        assertEquals(true, taskService().getVariable(task.getId(), "deletable"));
    }

}

The full XML:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://activiti.org/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_1RW-0F22EeOq-_ehbw1S0Q" exporter="camunda modeler" exporterVersion="2.5.0" targetNamespace="http://activiti.org/bpmn">
  <bpmn2:collaboration id="_Collaboration_8">
    <bpmn2:participant id="nipacreatesipinterconnect" name="Create new SIP Interconnect" processRef="nipa-createsipinterconnect"/>
  </bpmn2:collaboration>
  <bpmn2:process id="nipa-createsipinterconnect" name="Create new SIP Interconnect" isExecutable="true">
    <bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
      <bpmn2:lane id="Lane_1" name="Lane 1">
        <bpmn2:flowNodeRef>reviewnewtrunk</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>StartCreateSIPInterconnect</bpmn2:flowNodeRef>
      </bpmn2:lane>
    </bpmn2:laneSet>
    <bpmn2:userTask id="reviewnewtrunk" camunda:candidateGroups="management" camunda:candidateUsers="" name="Review New &#xD;&#xA;Trunk Request">
      <bpmn2:extensionElements>
        <camunda:inputOutput>
            <camunda:inputParameter name="deletable">${true}</camunda:inputParameter>
         </camunda:inputOutput>
      </bpmn2:extensionElements>
      <bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
    </bpmn2:userTask>
    <bpmn2:startEvent id="StartCreateSIPInterconnect" name="Describe New &#xD;&#xA;SIP Interconnect &#xD;&#xA;Request">
      <bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="StartCreateSIPInterconnect" targetRef="reviewnewtrunk"/>
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_8">
      <bpmndi:BPMNShape id="_BPMNShape_Participant_12" bpmnElement="nipacreatesipinterconnect" isHorizontal="true">
        <dc:Bounds height="333.0" width="1381.0" x="48.0" y="16.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_9" bpmnElement="StartCreateSIPInterconnect">
        <dc:Bounds height="36.0" width="36.0" x="228.0" y="154.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="54.0" width="116.0" x="188.0" y="195.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_UserTask_22" bpmnElement="reviewnewtrunk">
        <dc:Bounds height="80.0" width="157.0" x="516.0" y="132.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_Lane_7" bpmnElement="Lane_1" isHorizontal="true">
        <dc:Bounds height="333.0" width="1351.0" x="78.0" y="16.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_5" sourceElement="_BPMNShape_StartEvent_9" targetElement="_BPMNShape_UserTask_22">
        <di:waypoint xsi:type="dc:Point" x="264.0" y="172.0"/>
        <di:waypoint xsi:type="dc:Point" x="516.0" y="172.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="6.0" width="6.0" x="291.0" y="172.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>

Answer

thorben picture thorben · Aug 28, 2014

On versions >= 7.2.0-alpha2

You could use an inputOuput extension element

So something like

<bpmn2:userTask id="createtrunkdoc" camunda:candidateUsers="${candidateUser}"  camunda:candidateGroups="provisioning" camunda:assignee="${candidateUser}" name="Create New&#xD;&#xA;Trunk Request">
  <extensionElements>
    <camunda:inputOutput>
      <camunda:inputParameter name="deletable">${true}</camunda:inputParameter>
    </camunda:inputOutput>
  </extensionElements>
  <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
  <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>      
</bpmn2:userTask>

edit:

Assuming you have a process where this is the only task, the following works for me:

ProcessInstance pi = runtimeService.startProcessInstanceByKey("processKey");
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
assertEquals(true, taskService.getVariable(task.getId(), "deletable"));

Just make sure the task id is correct and be aware that this sets a Boolean value not a String.

On versions < 7.2.0-alpha2

There is no out-of-the-box support for this but you can achive it in the following way:

Create a custom extension element that defines the variable and value to set (or reuse the camunda extension elements like above). Then create a parse listener that parses these extension elements for every task and adds an execution listener to every task that listens for the "start" event. The execution listener can then set the variable that the parse listener provided it with.

For an example of the mechanism of combining parse and execution listener, see https://github.com/camunda/camunda-bpm-examples/tree/master/process-engine-plugin/bpmn-parse-listener