cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti 5.22: Message-Cancelled Call Activity doesn't fire subprocess PROCESS_CANCELLED

willb
Champ on-the-rise
Champ on-the-rise

(Title originally indicated v5.18, but we are on 5.22).

When a process instance ends via an end event a PROCESS_COMPLETE listener event fires.  If the process hits a terminate end event PROCESS_CANCELLED fires.

When that subprocess is the result of a Call Activity and the Call Activity receives a boundary message, placed on top of the element in the Eclipse designer, the subprocess does indeed get killed off, but as best I can tell, the PROCESS_CANCELLED event doesn't fire.

Has anyone else run into this?  How did you solve it?  The problem for my company is that we have to keep our legacy system in sync with the Activiti workflow and orchestration.  Certain subprocesses are "orders" and when we instantiate those subprocesses, we have a matching task in our legacy system.  That "task" for us isn't a real task, its more of a "task container".  When the order process starts, we go to our internal API, create the matching wrapper, get our unique id, then store that ID as a process variable on the order subprocess.

Whenever that process ends, we have to tell the API "Hey, we're done.  Here's the 'completeTaskEventTrackingId' you gave me earlier...close it."  For us, if the process ends gracefully, we close that task in the legacy system as "Completed".  If it terminates, we marked it as "Cancelled".   This all works just fine, unless the process is terminated by terminating it's parent Call Activity!  Since the listener point doesn't fire...we have no way to know it's over and grab that subprocess variable to handle it.  Interestingly, any open tasks in that subprocess DO fire the ACTIVITY_CANCELLED with a type of userTask.  And so do other callActivity types.  My conclusion is that this is a 5.18 bug.  Unless it's by design?  If so, why?

Let me note here, that this IS indeed a cancel event:

<boundaryEvent id="boundarymessage1" name="Message" attachedToRef="callActivity1" cancelActivity="true">
     <messageEventDefinition messageRef="testKillMessage"></messageEventDefinition>
</boundaryEvent>

After hours of trying to solve this, I came up with another potential solution but, in the end, could not make it work.  Since the ACTIVITY_CANCELLED fires for the Call Activity (element), okay...I'll just grab the process variables from the subprocess that it instantiated.  We know when the subprocess ends, that the Call Activity that fired it is completed and flow moves on to the next element.  Somehow the parent process' Call Activity is linked to the subprocess instantiation to enable this natively.  But, while there are 4000 questions online about how to get the parent process ID from the child process...how do you go the other way?  How does one ask "I have this Call Activity...what was the processInstanceId of the subprocess?"

I've struggled with this for days.  I'm not a Java guy, but a decent programmer.  I can explore Javadocs with the best of us, and using Eclipse really helps me on the object class insights.

I could really use some help.

The end goals are any of the following:

  • How to get the PROCESS_CANCELLED to fire for the subprocess instance when the Call Activity is terminated?
  • How to determine the sub-processInstanceId spawned by the Call Activity in the parent process?

Eagerly awaiting some insight from others.

1 ACCEPTED ANSWER

willb
Champ on-the-rise
Champ on-the-rise

With no response from either Alfresco or the community regarding this question, we did arrive at a solution.  That solution, however, is horribly ugly in my opinion.

What we did was add a manual input variable to every Call Actvity where the subprocess is an "order" and will contain our completeEventTrackingId.   That variable is something like "parentCallActivityElementId" and contains the same ID as that Call Activity element, obviously.  For example, if the element ID is "subCompleteTitleOrder", then we'll have an input variable of parentCallActivityElementId="subCompleteTitleOrder".  This requires all of our BPM developers to perform this extra design step.  (Yes, we could modify the XML at deployment time, but we aren't quite there yet.)

When "PROCESS_START" fires on the subprocess, we look for a process variable named "parentCallActivityElementId".  If it is found, we retrieve the parent process, and create a variable that follows the convention, in this case, of subCompleteTitleOrder_pid and store the subprocess' processInstanceId on it.  Note that the convention is "parent Call Activity element ID" plus underscore plus "pid" to hold that value.

When the parent Call Activity is cancelled (either by a boundary event or by the parent process being canceled), the listener point "ACTIVITY_CANCELLED" does fire for any open, unfinished elements.  We check to see if it's of the Call Activity type and, if so, we grab that element ID, then look for convention-based "thatId_pid" process variable (in this case: "subCompleteTitleOrder_pid") in the containing process.  If it's found, then we can grab (either from live or historical process search) for that sub-processInstanceId, look for the completeEventTrackingId variable on that subprocess... and fire our postProcessEnded() custom function that closes that task ID in the legacy system.

A couple of points here that I can see for improvement for Activiti:

  1. When a process is cancelled, regardless of how it is spawned (Process self-terminates, Call Activiti cancelled, Parent Process is cancelled, boundary events, etc.) that PROCESS_CANCELLED is fired.  In our opinion, this is a bug, that cancelled Call Activities don't fire PROCESS_CANCELLED on their spawned subprocesses.
  2. It would nice if there was a way to be able to configure the input/output variables for a Call Activity at runtime.  If there's a way, we couldn't find it.
  3. We know that when a subprocess ends, that control is returned to the parent process and the Call Activity ends and the flow moves on.  There is obviously a connection between a Call Activity and it's spawned process.  But there seems to be no way at runtime to obtain the spawned sub-processInstanceId.  At least not that is publicly exposed.  Adding the abiltity to ask the Call Activity, when it ends, "what was the processInstanceId of the process you spawned?" would be mighty helpful.  Or even to have access to the sub-process' variables would be even better, without having to specifically create an output variable, which, again, seems impossible to modify at runtime.

View answer in original post

1 REPLY 1

willb
Champ on-the-rise
Champ on-the-rise

With no response from either Alfresco or the community regarding this question, we did arrive at a solution.  That solution, however, is horribly ugly in my opinion.

What we did was add a manual input variable to every Call Actvity where the subprocess is an "order" and will contain our completeEventTrackingId.   That variable is something like "parentCallActivityElementId" and contains the same ID as that Call Activity element, obviously.  For example, if the element ID is "subCompleteTitleOrder", then we'll have an input variable of parentCallActivityElementId="subCompleteTitleOrder".  This requires all of our BPM developers to perform this extra design step.  (Yes, we could modify the XML at deployment time, but we aren't quite there yet.)

When "PROCESS_START" fires on the subprocess, we look for a process variable named "parentCallActivityElementId".  If it is found, we retrieve the parent process, and create a variable that follows the convention, in this case, of subCompleteTitleOrder_pid and store the subprocess' processInstanceId on it.  Note that the convention is "parent Call Activity element ID" plus underscore plus "pid" to hold that value.

When the parent Call Activity is cancelled (either by a boundary event or by the parent process being canceled), the listener point "ACTIVITY_CANCELLED" does fire for any open, unfinished elements.  We check to see if it's of the Call Activity type and, if so, we grab that element ID, then look for convention-based "thatId_pid" process variable (in this case: "subCompleteTitleOrder_pid") in the containing process.  If it's found, then we can grab (either from live or historical process search) for that sub-processInstanceId, look for the completeEventTrackingId variable on that subprocess... and fire our postProcessEnded() custom function that closes that task ID in the legacy system.

A couple of points here that I can see for improvement for Activiti:

  1. When a process is cancelled, regardless of how it is spawned (Process self-terminates, Call Activiti cancelled, Parent Process is cancelled, boundary events, etc.) that PROCESS_CANCELLED is fired.  In our opinion, this is a bug, that cancelled Call Activities don't fire PROCESS_CANCELLED on their spawned subprocesses.
  2. It would nice if there was a way to be able to configure the input/output variables for a Call Activity at runtime.  If there's a way, we couldn't find it.
  3. We know that when a subprocess ends, that control is returned to the parent process and the Call Activity ends and the flow moves on.  There is obviously a connection between a Call Activity and it's spawned process.  But there seems to be no way at runtime to obtain the spawned sub-processInstanceId.  At least not that is publicly exposed.  Adding the abiltity to ask the Call Activity, when it ends, "what was the processInstanceId of the process you spawned?" would be mighty helpful.  Or even to have access to the sub-process' variables would be even better, without having to specifically create an output variable, which, again, seems impossible to modify at runtime.