05-31-2017 05:50 PM
I am trying to understand the message event catching functionality in Activiti 5.22.
To that end, I created the following process definition:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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://www.activiti.org/test">
<message id="hello" name="Hello Event"></message>
<process id="myProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="start"></sequenceFlow>
<scriptTask id="start" name="Begin Flow" activiti:autoStoreVariables="false">
<documentation>This is the start of the flow.</documentation>
<script>java.lang.System.out.println("Starting ...");</script>
</scriptTask>
<intermediateCatchEvent id="messageintermediatecatchevent1" name="MessageCatchEvent">
<documentation>Here we wait for the event</documentation>
<messageEventDefinition messageRef="hello"></messageEventDefinition>
</intermediateCatchEvent>
<sequenceFlow id="flow2" sourceRef="start" targetRef="messageintermediatecatchevent1"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="messageintermediatecatchevent1" targetRef="scripttask2"></sequenceFlow>
<scriptTask id="scripttask2" name="End Flow" activiti:autoStoreVariables="false">
<documentation>And here we are done</documentation>
<script>java.lang.System.out.println("... received event");</script>
</scriptTask>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow4" sourceRef="scripttask2" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
<bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="80.0" y="140.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="55.0" width="105.0" x="160.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="messageintermediatecatchevent1" id="BPMNShape_messageintermediatecatchevent1">
<omgdc:Bounds height="35.0" width="35.0" x="330.0" y="140.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="scripttask2" id="BPMNShape_scripttask2">
<omgdc:Bounds height="55.0" width="105.0" x="410.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="560.0" y="140.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="115.0" y="157.0"></omgdi:waypoint>
<omgdi:waypoint x="160.0" y="157.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="265.0" y="157.0"></omgdi:waypoint>
<omgdi:waypoint x="330.0" y="157.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="365.0" y="157.0"></omgdi:waypoint>
<omgdi:waypoint x="410.0" y="157.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="515.0" y="157.0"></omgdi:waypoint>
<omgdi:waypoint x="560.0" y="157.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
And the JUnit test case:
package org.activiti.designer.test;
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.FileInputStream;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.query.Query;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ExecutionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.test.ActivitiRule;
import org.junit.Rule;
import org.junit.Test;
public class ProcessTestMyProcess {
private String filename = "/Users/mprakash/projects/Eventing/src/main/resources/diagrams/EventFlow.bpmn";
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test
public void startProcess() throws Exception {
RepositoryService repositoryService = activitiRule.getRepositoryService();
repositoryService.createDeployment().addInputStream("myProcess.bpmn20.xml", new FileInputStream(filename))
.deploy();
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("name", "EventActivity");
String id = "Id" + Math.round(Math.random() * 1000);
variableMap.put("id", id);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess", variableMap);
assertNotNull(processInstance.getId());
System.out.println("id " + processInstance.getId() + " " + processInstance.getProcessDefinitionId());
ExecutionQuery exeQuery = runtimeService.createExecutionQuery().processVariableValueEquals("id", id);
List<Execution> execs = exeQuery.list();
for (Execution ex : execs) {
System.out.println(ex.getActivityId() + " = " + ex.getName() + " : " + ex.getDescription() + " - " + ex.getId());
try {
runtimeService.messageEventReceived("hello", ex.getId());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
When I run it, at line 42, I get two executions, not one, as I expected. At line 46, both executions claim no subscription to the message exists:
May 31, 2017 5:41:13 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [activiti.cfg.xml]
May 31, 2017 5:41:14 PM org.activiti.engine.impl.db.DbSqlSession executeSchemaResource
INFO: performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql
May 31, 2017 5:41:14 PM org.activiti.engine.impl.db.DbSqlSession executeSchemaResource
INFO: performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql
May 31, 2017 5:41:14 PM org.activiti.engine.impl.db.DbSqlSession executeSchemaResource
INFO: performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql
May 31, 2017 5:41:14 PM org.activiti.engine.impl.ProcessEngineImpl <init>
INFO: ProcessEngine default created
May 31, 2017 5:41:14 PM org.activiti.engine.impl.bpmn.deployer.BpmnDeployer deploy
INFO: Processing resource myProcess.bpmn20.xml
id 5 myProcess:1:4
messageintermediatecatchevent1 = null : null - 10
May 31, 2017 5:41:16 PM org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: Execution with id '10' does not have a subscription to a message event with name 'hello'
at org.activiti.engine.impl.cmd.MessageEventReceivedCmd.execute(MessageEventReceivedCmd.java:76)
at org.activiti.engine.impl.cmd.MessageEventReceivedCmd.execute(MessageEventReceivedCmd.java:33)
at org.activiti.engine.impl.cmd.NeedsActiveExecutionCmd.execute(NeedsActiveExecutionCmd.java:55)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.RuntimeServiceImpl.messageEventReceived(RuntimeServiceImpl.java:419)
at org.activiti.designer.test.ProcessTestMyProcess.startProcess(ProcessTestMyProcess.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.activiti.engine.test.ActivitiRule$1.evaluate(ActivitiRule.java:126)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Execution with id '10' does not have a subscription to a message event with name 'hello'
null = null : null - 5
May 31, 2017 5:41:16 PM org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: Execution with id '5' does not have a subscription to a message event with name 'hello'
at org.activiti.engine.impl.cmd.MessageEventReceivedCmd.execute(MessageEventReceivedCmd.java:76)
at org.activiti.engine.impl.cmd.MessageEventReceivedCmd.execute(MessageEventReceivedCmd.java:33)
at org.activiti.engine.impl.cmd.NeedsActiveExecutionCmd.execute(NeedsActiveExecutionCmd.java:55)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.RuntimeServiceImpl.messageEventReceived(RuntimeServiceImpl.java:419)
at org.activiti.designer.test.ProcessTestMyProcess.startProcess(ProcessTestMyProcess.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.activiti.engine.test.ActivitiRule$1.evaluate(ActivitiRule.java:126)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Execution with id '5' does not have a subscription to a message event with name 'hello'
Anyone have an idea what am I doing wrong? I cannot find any documentation on the relationship between message ID, message name, and event subscription.
Thanks.
06-01-2017 03:00 AM
You need to specify a messageName, not a messageRef.
runtimeService.messageEventReceived("Hello Event", ex.getId());
06-01-2017 03:00 AM
You need to specify a messageName, not a messageRef.
runtimeService.messageEventReceived("Hello Event", ex.getId());
06-01-2017 10:08 AM
Thanks. That worked.
I have a couple of more questions though.
Thanks.
06-01-2017 10:34 AM
> 1. Why do I get 2 executions, when I have a single threaded process with no branches?
It is difficult to explain how executions are generated in Activiti.
In this case, it splits into the scope execution of the message intermediate event and the execution of the process instance itself.Execution is not splited only in case of branch or parallel.
> Why do getId() and getName() return null,
Do you mention about getName() and getDescription()?
It will be null if you do not intentionally set it.
> and for one execution, even getActivitiId()?
Because the second execution of your loop is the execution of the process instance itself.
> Given this ambiguity, how do I know which is the execution that I want to deliver the event to?
You should use ExecutionQuery.messageEventSubscriptionName(String messageName).
https://www.activiti.org/javadocs/org/activiti/engine/runtime/ExecutionQuery.html#messageEventSubscr...
Please check the link I uploaded.
https://www.activiti.org/userguide/#bpmnMessageEventDefinition
Explore our Alfresco products with the links below. Use labels to filter content by product module.