Query for boundary message event does not work

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-29-2013 07:37 PM
Hi,
I am using activiti currently in the test setup to get acquainted. The out of the box config has been set to the H2 in memory database.
I have created a message boundary event for one of my subprocesses. In BPMN it is defined as:
[java]
RuntimeService runtimeService = execution.getEngineServices().getRuntimeService();
String executionId = runtimeService.createExecutionQuery().messageEventSubscriptionName("cancelRenewal").singleResult().getId();
[/java]
Unfortunately I get a nullpointerException because
[java]
runtimeService.createExecutionQuery().messageEventSubscriptionName("cancelRenewal").singleResult()
[/java] returns null.
Any idea if I am doing something wrong here? or is it a bug?
Thanks!
kiyer
I am using activiti currently in the test setup to get acquainted. The out of the box config has been set to the H2 in memory database.
I have created a message boundary event for one of my subprocesses. In BPMN it is defined as:
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://activiti.org/bpmn20"> … <message id="cancelRenewal" name="cancelRenewal"></message> <process id="signupWorkflow" name="Sugarsync Signup Process" isExecutable="true">… <boundaryEvent id="boundarymessage1" name="Message" attachedToRef="subprocess1" cancelActivity="true"> <messageEventDefinition messageRef="cancelRenewal"></messageEventDefinition> </boundaryEvent> </process></definitions>
I have plugged in a java service task where i wish to send a message to cancel this process:[java]
RuntimeService runtimeService = execution.getEngineServices().getRuntimeService();
String executionId = runtimeService.createExecutionQuery().messageEventSubscriptionName("cancelRenewal").singleResult().getId();
[/java]
Unfortunately I get a nullpointerException because
[java]
runtimeService.createExecutionQuery().messageEventSubscriptionName("cancelRenewal").singleResult()
[/java] returns null.
Any idea if I am doing something wrong here? or is it a bug?
Thanks!
kiyer
Labels:
- Labels:
-
Archive
8 REPLIES 8
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2013 08:00 AM
Where is this service task in the process? Could it be that the boundary event is not yet persisted to the database because the service task is part of the same transaction?

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2013 08:27 PM
Interesting point regarding the transaction. I am building off of the unit test examples in Activiti user guide. here is the process fragment of interest: [img]https://docs.google.com/drawings/d/1zIjv90Sc0dauUHRfRjQCBsXlBZMGzMqxsPU9bxgobMA/pub?w=960&h=720[/img]
The subprocess for renew subscription has a boundary message event to cancel on receiving the message (See the xml posted earlier). The message is sent by the script task "Send cancel renewal message". It has the following groovy script in it [java]
processId = execution.processInstanceId;
org.activiti.engine.RuntimeService runtimeServiceVar = execution.engineServices.runtimeService;
println "Current processId: ${processId}";
executionId=runtimeServiceVar.createExecutionQuery().signalEventSubscriptionName("cancelRenewal").singleResult().id;
println "Sending cancel Renewal message to executionId: ${executionId}";
runtimeServiceVar.messageEventReceived("cancelRenewal",executionId);
[/java]
The following expression in the code above is null and hence I get a NullPointerException
[java]
runtimeServiceVar.createExecutionQuery().signalEventSubscriptionName("cancelRenewal").singleResult()
[/java]
They run as part of a single test method execution:
[java]
@Test
public void testSignupWorkflow() throws Exception {
runtimeService.startProcessInstanceByKey("signupWorkflow");
Task task = taskService.createTaskQuery()
.taskCandidateGroup("anonymous").singleResult();
String procId = task.getProcessInstanceId();
assertEquals("User enters email address", task.getName());
Map<String, Object> taskVariables = new HashMap<String, Object>();
taskVariables.put("emailAddress", "kiyer@yopmail.com");
taskService.complete(task.getId(), taskVariables);
//Wait for timer task to fire
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery().processInstanceId(procId)
.singleResult();
while(historicProcessInstance.getEndActivityId()==null){
historicProcessInstance = historyService
.createHistoricProcessInstanceQuery().processInstanceId(procId)
.singleResult();
System.out.println("Process has not ended yet. Trying again after 2 seconds");
Thread.sleep(2000);
}
assertNotNull("Process should have ended by now!", historicProcessInstance.getEndActivityId());
System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
assertEquals(0, runtimeService.createProcessInstanceQuery().count());
[/java]
Is it failing to get any results because they are part of the same transaction? If yes, then I suppose this issue will not happen in a prod environment (which is a good thing). But then the question still remains, how can I unit test this workflow if the transactions mask the data about event subscritptions in the workflow?
Thanks for your help!
The subprocess for renew subscription has a boundary message event to cancel on receiving the message (See the xml posted earlier). The message is sent by the script task "Send cancel renewal message". It has the following groovy script in it [java]
processId = execution.processInstanceId;
org.activiti.engine.RuntimeService runtimeServiceVar = execution.engineServices.runtimeService;
println "Current processId: ${processId}";
executionId=runtimeServiceVar.createExecutionQuery().signalEventSubscriptionName("cancelRenewal").singleResult().id;
println "Sending cancel Renewal message to executionId: ${executionId}";
runtimeServiceVar.messageEventReceived("cancelRenewal",executionId);
[/java]
The following expression in the code above is null and hence I get a NullPointerException
[java]
runtimeServiceVar.createExecutionQuery().signalEventSubscriptionName("cancelRenewal").singleResult()
[/java]
They run as part of a single test method execution:
[java]
@Test
public void testSignupWorkflow() throws Exception {
runtimeService.startProcessInstanceByKey("signupWorkflow");
Task task = taskService.createTaskQuery()
.taskCandidateGroup("anonymous").singleResult();
String procId = task.getProcessInstanceId();
assertEquals("User enters email address", task.getName());
Map<String, Object> taskVariables = new HashMap<String, Object>();
taskVariables.put("emailAddress", "kiyer@yopmail.com");
taskService.complete(task.getId(), taskVariables);
//Wait for timer task to fire
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery().processInstanceId(procId)
.singleResult();
while(historicProcessInstance.getEndActivityId()==null){
historicProcessInstance = historyService
.createHistoricProcessInstanceQuery().processInstanceId(procId)
.singleResult();
System.out.println("Process has not ended yet. Trying again after 2 seconds");
Thread.sleep(2000);
}
assertNotNull("Process should have ended by now!", historicProcessInstance.getEndActivityId());
System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
assertEquals(0, runtimeService.createProcessInstanceQuery().count());
[/java]
Is it failing to get any results because they are part of the same transaction? If yes, then I suppose this issue will not happen in a prod environment (which is a good thing). But then the question still remains, how can I unit test this workflow if the transactions mask the data about event subscritptions in the workflow?
Thanks for your help!

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-03-2013 09:51 PM
Just an update: I noticed in the documentation that there is no way to query for boundary message events. Can such an example be please posted? In the user guide section titled "Querying for Message Event subscriptions", there is no example of how boundary message events can be queried.
If a unit test which shows the working of such a query be posted, I would really appreciate it.
Thanks!
kiyer
If a unit test which shows the working of such a query be posted, I would really appreciate it.
Thanks!
kiyer
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2013 10:37 AM
/**
* Only select executions which have a message event subscription
* for the given messageName.
*
* (The messageName is specified using the 'name' attribute of the message element
* in the BPMN 2.0 XML.)
*
* @param messageName the name of the message the execution has subscribed to
*/
ExecutionQuery messageEventSubscriptionName(String messageName);
Is that what you're looking for? See org.activiti.engine.test.bpmn.event.message.MessageBoundaryEventTest for test

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-04-2013 05:15 PM
Hello Frederik,
Thanks for the pointers. I checked out the unit test you mentioned. The scenario in the test is a user task with a boundary message event. I tried it out in my project and it worked just fine. However what doesnt work is a boundary message event attached to a sub-process. If you see the image in Post#3 the renewal sub process has a boundary message attached to it with message ref:cancelRenewal.
When I try to query as:
[java]
runtimeService.createExecutionQuery().messageEventSubscriptionName("cancelRenewal").singleResult()
[/java]
I get a null. Please let me know if you need a unit test to verify this and I will be happy to set it up.
Thanks!
Karthik
Thanks for the pointers. I checked out the unit test you mentioned. The scenario in the test is a user task with a boundary message event. I tried it out in my project and it worked just fine. However what doesnt work is a boundary message event attached to a sub-process. If you see the image in Post#3 the renewal sub process has a boundary message attached to it with message ref:cancelRenewal.
When I try to query as:
[java]
runtimeService.createExecutionQuery().messageEventSubscriptionName("cancelRenewal").singleResult()
[/java]
I get a null. Please let me know if you need a unit test to verify this and I will be happy to set it up.
Thanks!
Karthik
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-06-2013 08:47 AM
Yes, a unit-test for this would be great!

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-07-2013 04:27 PM
Thanks for responding. It looks like I can't upload the unit test project directly to this forum. So please download the failing test case maven project from here: https://www.sugarsync.com/pf/D6473659_753_6781691378
It looks like the core of the issue is how the perpetual timers are modeled. (No necessarily an issue with boundary message event). Looking forward to your analysis…
Thanks!
It looks like the core of the issue is how the perpetual timers are modeled. (No necessarily an issue with boundary message event). Looking forward to your analysis…
Thanks!
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-10-2013 11:33 AM
Once the timer has fired, it moves on to the script-task. if that's finished, the subprocess ends (there is no outgoing from the script-task) so the scope is destroyed. Any boundary-events attached to this scope, will be removed.
Since that's the last active execution, your whole process ends as well… You should re-model the process if you want to have the script-task executed 3 times (eg. boundary-event with cancelActiviti="false" on a subprocess which triggers the scriptTask to run but doesn't cause the subprocess to end because of the timer firing.)
Since that's the last active execution, your whole process ends as well… You should re-model the process if you want to have the script-task executed 3 times (eg. boundary-event with cancelActiviti="false" on a subprocess which triggers the scriptTask to run but doesn't cause the subprocess to end because of the timer firing.)
