cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti and JMS (mapping messages and signals to JMS msgs)

odranoel75
Champ in-the-making
Champ in-the-making
I have two questions about Activiti BPMN:

1) How do I parse message definitions programmatically

2) How do I trap intermediateThrowEvent events programmatically.

I'm working on a project that will use an embedded Activiti BPMN engine (currently version 5.11). The application is currently driven by sending and receiving JMS messages, and I thought it would be a natural fit to expose them as Activiti messages and signals. The application has to enable many separate JVMs each running a single BPMN engine with various processes to both send and receive messages between each other.

I have a few thoughts on how to implement each scenario, but I'm unsure on how to parse the messages from my BPMN process to implement Option 2a, and I'm unsure of how to trap the intermediateThrowEvent to implement Option 1b:

a) Receiving messages:

Option 1a - subscribe to a single topic where all JMS messages arrive, and put the Activiti message or Activiti signal name inside the JMS messages as a payload. When a JMS message arrives, I can then query the engine each to see which current Executions are subscribing to the messages, and which Processes need to be started:

List<ProcessDefinition> pds= repositoryService.createProcessDefinitionQuery()
  .messageEventSubscription("messageNameInsideJMSPayload")
  .list();

for (ProcessDefinition pd: pds)
{
    RunBPMProcess.runtimeService.startProcessInstanceByMessage(messageName,
    di.getId().toString(), processVariables);
}
Option 2a - subscribe to a dynamic topic that maps directly to the Activiti message name or Activity Signal name. The tricky part here is how to parse the message or signal name from the BPMN process. I've managed to parse the message reference by using a custom BpmnParseListener, but I can only get the message reference, and not the message name from within the implementation.

pec = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
  if (pec instanceof ProcessEngineConfigurationImpl)
  {

    List<BpmnParseListener> preParseListeners = new ArrayList <>();

    preParseListeners.add(new BPMNMessageAndSignalParser(pontus));


    ((ProcessEngineConfigurationImpl) pec).setCustomPreBPMNParseListeners(preParseListeners );


  }
b) Sending Messages:

Option 1b) I'd like to ideally trap the intermediateThrowEvent, so I can send the signal as a JMS message, but I'm not sure how to do that.



I'm fairly new to Activiti, so apologies if I've missed anything obvious; also, here's a sample workflow just to help put the issue in context:

<?xml version="1.0" encoding="UTF-8" ?>
<definitions id="definitions"
             targetNamespace="http://activiti.org/bpmn20"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:activiti="http://activiti.org/bpmn">
  <message id="pontusMessage" name="pontusMessage"/>
  <signal id = "pontusSignal" name="pontusSignal"/>
  <process id="test" name="PontusNetworks Test" isExecutable="true">

    <startEvent id="start" />

    <sequenceFlow id="flow1" sourceRef="start" targetRef="messageReceiver" />

    <intermediateCatchEvent id="messageReceiver">
        <messageEventDefinition messageRef="pontusMessage" />
    </intermediateCatchEvent>

    <sequenceFlow id="flow2" sourceRef="messageReceiver" targetRef="signalSender">
    </sequenceFlow>


    <intermediateThrowEvent id="signalSender">
        <signalEventDefinition signalRef="pontusSignal" />
    </intermediateThrowEvent>
    <sequenceFlow id="flow3" sourceRef="messageReceiver" targetRef="theEnd2"/>

    <endEvent id="theEnd2" />

  </process>

</definitions>
Thanks in advance for any ideas.
5 REPLIES 5

jbarrez
Star Contributor
Star Contributor
As a side note: bpmn messages are not external, but are used for communication between pools.

However, JMS could be used to do that, but it's not very easy to do so.
In my opinion, you'd better look into the Camel integration with Activiti, and use Camel to define the routes between all systems involved. Either options you describe will work, Camel is pretty open about that.

odranoel75
Champ in-the-making
Champ in-the-making
Thank you very much for the prompt reply.  Unfortunately, using Camel isn't an option currently. 

By looking at the Camel examples, It looks like the implementation was implemented using Delegates, which ideally I'd like to avoid. 
I've managed to implement my subscription from JMS easily enough (and bumped into a bug in the process –  http://jira.codehaus.org/browse/ACT-1497); now, I'd like to intercept the intermediateThrowEvent command, but so far, I've been unable to do so.

Do you have any pointers on how to do that?  I've tried putting a breakpoint in the actualCommandExecutor to see whether I could do it using CommandInterceptors , but it only seems to capture the StartProcessInstanceCmd, but nothing within the process itself.

Regards,

         Leo.

jbarrez
Star Contributor
Star Contributor
Thank you very much for the prompt reply. Unfortunately, using Camel isn't an option currently.

That's a pity to hear, cause it solves a lot of the issues you will have to code yourself now

By looking at the Camel examples, It looks like the implementation was implemented using Delegates, which ideally I'd like to avoid.

Indeed, it is completely based on the delegate approach.

I've managed to implement my subscription from JMS easily enough (and bumped into a bug in the process – http://jira.codehaus.org/browse/ACT-1497);


Thanks for reporting that! We'll look into it.

now, I'd like to intercept the intermediateThrowEvent command, but so far, I've been unable to do so.
Do you have any pointers on how to do that? I've tried putting a breakpoint in the actualCommandExecutor to see whether I could do it using CommandInterceptors , but it only seems to capture the StartProcessInstanceCmd, but nothing within the process itself.

You will not be able to capture it using a command, for the simple reason that it's not an external 'signal' to the process, rather an internal. Hence, the command chain is never called.

Now that I think of it, there might be a way using the BpmnParseListener. Ie, you listen to the parsing of the process xml, and you swap the ActivityBehavior with your own implementation. I didn't try it, so it might not work as expected, but it is the best solution I see.

odranoel75
Champ in-the-making
Champ in-the-making
Thank you very much for the tip.  That worked like a charm!

jbarrez
Star Contributor
Star Contributor
Great to hear! I knew that it should work (*hum**hum*) 😉