Sending message events to a process

cancel
Showing results for 
Search instead for 
Did you mean: 
mprakash
Active Member II

Sending message events to a process

Jump to solution

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.

1 Solution

Accepted Solutions
daisuke-yoshimo
Senior Member

Re: Sending message events to a process

Jump to solution

You need to specify a messageName, not a messageRef.

Activiti User Guide 

runtimeService.messageEventReceived("Hello Event", ex.getId());

View solution in original post

3 Replies
daisuke-yoshimo
Senior Member

Re: Sending message events to a process

Jump to solution

You need to specify a messageName, not a messageRef.

Activiti User Guide 

runtimeService.messageEventReceived("Hello Event", ex.getId());

mprakash
Active Member II

Re: Sending message events to a process

Jump to solution

Thanks. That worked.

I have a couple of more questions though.

  1. Why do I get 2 executions, when I have a single threaded process with no branches?
  2. Why do getId() and getName() return null, and for one execution, even getActivitiId()?
  3. Given this ambiguity, how do I know which is the execution that I want to deliver the event to?

Thanks.

daisuke-yoshimo
Senior Member

Re: Sending message events to a process

Jump to solution

> 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