Exclusive Gateways + Process Variables

1,549 views
Skip to first unread message

mireill...@gmail.com

unread,
Feb 24, 2015, 3:56:54 AM2/24/15
to camunda-...@googlegroups.com
Hallo everyone,

I need your help in order to execute a process which takes three input parameters (personName,
destHoliday1, destHoliday2). It also has a serviceTask that test if the personName is a Manager. If yes,
a serviceTask "Send to destination Holiday 2" will be executes, else the serviceTask "Send to destination Holiday 1"
is executed.

My questions are the following:
Q1) What is the best way to set the input parameter and how to call them in the javadelegate classes attributes to the service Tasks.
Q2) Do we need execution listener for the sequence flow or using the conditionExpression element is better?

An excerpt of the code is the following:

***************testProcess.bpmn*****************
<bpmn2:process id="testProcess" name="Test Process" isExecutable="false">
<bpmn2:startEvent id="StartEvent">
<bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:sequenceFlow id="SequenceFlow_3" name="" sourceRef="StartEvent" targetRef="ServiceTask_1"/>
<bpmn2:serviceTask id="ServiceTask_1" camunda:class="tutorials.camunda.Delegate" name="Is Input Person a Manager?">
<bpmn2:extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="personName">
<camunda:script/>
</camunda:inputParameter>
</camunda:inputOutput>
</bpmn2:extensionElements>
<bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_4</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sequenceFlow id="SequenceFlow_4" name="" sourceRef="ServiceTask_1" targetRef="ExclusiveGateway_1"/>
<bpmn2:exclusiveGateway id="ExclusiveGateway_1" name="Person Manager ?">
<bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:serviceTask id="QueryServiceTask" camunda:class="tutorials.camunda.DelegateHolidayService" name="Send to destination Holiday 2">
<bpmn2:extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="holidayDestination">
<camunda:script/>
</camunda:inputParameter>
</camunda:inputOutput>
</bpmn2:extensionElements>
<bpmn2:incoming>SequenceFlow_7</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="QueryServiceTask" targetRef="EndEvent"/>
<bpmn2:sequenceFlow id="SequenceFlow_6" name="No" sourceRef="ExclusiveGateway_1" targetRef="ServiceTask_2">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${tutorials.camunda.DelegateManagerServices.isManager()}</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_7" name="Yes" sourceRef="ExclusiveGateway_1" targetRef="QueryServiceTask">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${tutorials.camunda.DelegateManagerServices.isManager()}</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:endEvent id="EndEvent">
<bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:endEvent id="EndEvent_1">
<bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:serviceTask id="ServiceTask_2" camunda:class="tutorials.camunda.DelegateHolidayService" name="Send to destination Holiday1">
<bpmn2:extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="holidayDestination">
<camunda:script></camunda:script>
</camunda:inputParameter>
</camunda:inputOutput>
</bpmn2:extensionElements>
<bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="ServiceTask_2" targetRef="EndEvent_1"/>
</bpmn2:process>

************DelegateManagerServices***************

public class DelegateManagerServices implements JavaDelegate {
public boolean manager;

public boolean isManager() {
return manager;
}

public void execute(DelegateExecution execution) throws Exception {

//Method to test if the person name send as input parameter is a manager and set the boolean manager to true or false.
// In order to get the value of the input parameter, is it true that we should call the following??
// String personName = (String) execution.getVariable("personName");
}
}

*******************DelegateHolidayService*********************

public class DelegateHolidayService implements JavaDelegate {
private final static Logger LOGGER = Logger.getLogger("MESSAGE-INFO");

public void execute(DelegateExecution execution) throws Exception {


String holidayDestination = (String) execution.getVariable("holidayDestination");
LOGGER.log(Level.INFO, "The holiday destination is" + holidayDestination);
}

}


Thank you in advance for the help!

thorben....@camunda.com

unread,
Feb 24, 2015, 4:29:15 AM2/24/15
to camunda-...@googlegroups.com, mireill...@gmail.com
Hi,

Q1: The code you have in your JavaDelegate implementations is the recommended way of accessing process variables. How to set input parameters of a process depends on the way you start the process. If you start it via Java API, you can submit a map of variables, cf [1]. If you start it via task list, you would rather use a start form, cf [2].

Q2: Using condition expressions is the recommended way since you can edit these right away in a BPMN modeler like the Camunda modeler.

Best regards,
Thorben

[1] http://docs.camunda.org/latest/api-references/javadoc/org/camunda/bpm/engine/RuntimeService.html#startProcessInstanceByKey%28java.lang.String,%20java.util.Map%29
[2] http://docs.camunda.org/latest/guides/user-guide/#task-forms

mireill...@gmail.com

unread,
Feb 24, 2015, 5:25:11 AM2/24/15
to camunda-...@googlegroups.com, mireill...@gmail.com
Hallo Thorben,

Thank you for your answer. I still have a question concerning Q2): according to the camunda user guide cf [1], the sequence flows referencing the exclusiveGateway as well as the exclusiveGateway shoud look like that:
<bpmn2:exclusiveGateway id="ExclusiveGateway_1" name="Person Manager ?">
<bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
</bpmn2:exclusiveGateway>

<bpmn2:sequenceFlow id="SequenceFlow_6" name="No" sourceRef="ExclusiveGateway_1" targetRef="ServiceTask_2">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${manager == 'false'}</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="SequenceFlow_7" name="Yes" sourceRef="ExclusiveGateway_1" targetRef="QueryServiceTask">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${manager == 'true'}</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>

However in cf[1], the link 'corresponding section' which gives information about the special variables (in my case manager) is broken. So where and how this variable should be defined?

Best Regards

[1] http://docs.camunda.org/latest/guides/user-guide/#process-engine-expression-language-use-expression-language-as-conditions

thorben....@camunda.com

unread,
Feb 24, 2015, 6:04:48 AM2/24/15
to camunda-...@googlegroups.com, mireill...@gmail.com
Hi,

Thanks for pointing out the broken link, I'll make sure to fix that. The correct link would be

http://docs.camunda.org/latest/guides/user-guide/#process-engine-expression-language-variables-and-functions-available-inside-expression-language

Your condition looks good to me though. If you have a boolean process variable called "manager", the expressions should evaluate fine.

Best regards,
Thorben

Mireilla Smith

unread,
Feb 24, 2015, 10:17:22 AM2/24/15
to camunda-...@googlegroups.com
Hi, 
Thank you for your answer once again. I made a maven project and took your suggestions into consideration.
I have tried to set the input parameter in a java class implementing java delegate and I put a service task at the begining of the process that call this class, but I didn't succeed. In addition, I need that these variables are 'Not Local' rather Global in order to be used by all the service tasks of the process.
The second trial was by starting the process instance as described in[1]. Also without success. 

I have attached the code,  I would be really grateful if you can take a look at the code and tell me what I am doing wrong. 
A last request, can you give me an example of on how to set the input parameters of my process by starting it via Java API ?

Thank you loads in advance


--
You received this message because you are subscribed to a topic in the Google Groups "camunda BPM users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/camunda-bpm-users/VjJz4vPmFpA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to camunda-bpm-us...@googlegroups.com.
To post to this group, send email to camunda-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/camunda-bpm-users/2b7ede0c-d4b3-4917-b95b-87b1f9aabb02%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

src.rar

thorben....@camunda.com

unread,
Feb 24, 2015, 12:08:12 PM2/24/15
to camunda-...@googlegroups.com, mireill...@gmail.com
Hi Mireilla,

I'd recommend you write some unit tests. We have some testing infrastructure that simplifies things like process deployment. With unit tests, you get much faster feedback of what's wrong in your process. See [1] for details.

For your concrete process: In DelegateGlobalVariables, you'll have to set the variable "personName", otherwise it cannot be found in DelegateManagerServices. So for example, you could write:

public class DelegateGlobalVariables implements JavaDelegate {

      @Override

      public void execute(DelegateExecution execution) throws Exception {

        execution.setVariable("personName", "Anna");

      }
 }

As an example on how to pass variables via the Java API, have a look at [2], lines 39 to 45. The ProcessEngine object can be accessed in different ways, depending on from where you need it. The example uses the process engine from a unit test.

Cheers,
Thorben

[1] http://docs.camunda.org/latest/guides/user-guide/#testing-unit-testing
[2] https://github.com/camunda/camunda-bpm-examples/blob/master/servicetask/rest-service/src/test/java/org/camunda/bpm/example/servicetask/rest/ServiceTaskRestTest.java#L39

Mireilla Smith

unread,
Feb 25, 2015, 3:10:28 AM2/25/15
to camunda-...@googlegroups.com
Hallo Thorben, 

Thank you for answering all my questions. I have succeded to deploy my process and start it from tasklist. My next step is create an EjbProcessStarterclass that depends on DefaultEjbProcessApplication, which creates a new process instance with global variables. If I am not mistaken it should look like that isn't it?
@Startup
@Singleton
@DependsOn("DefaultEjbProcessApplication")
public class EjbProcessStarter {

  @Inject
  private RuntimeService runtimeService;

  public void startProcessInstance() {
    Map<String, Object> variables = new HashMap<String,Object>();
variables.put("manager", "false");
variables.put("personName", "Mireilla");
    runtimeService.startProcessInstanceByKey("testProcess", variables);
  }

}

and I will try to use Event Timer with the hope that it will work.

Best Reagrds,

Mireilla

Reply all
Reply to author
Forward
0 new messages