cancel
Showing results for 
Search instead for 
Did you mean: 

Using Error Events as general shortcutting solution

ekolesnikov
Champ in-the-making
Champ in-the-making
Hi guys,

Been a while since I last visited forums.

We have quite interesting approval process - the "manager" does not just approves or rejects, but also have an option to "escalate" the request (business case being "I have no objections, but I'm not comfortable authorising this on my own") to one or two nominated approvers.
In addition to that, if both approvers are nominated, the approvals have to go through in particular order (A -> B, not the other way around).

At the end of the whole thing, the "Your request has been approved" or "Your request has been rejected" email generation routine is triggered by the Service task.

My problem is - there are way too many references to process completion and it kind of messes up the whole BPMN diagram.

I.e. the "rejected" path is triggered when a "manager" rejects, when approver "A" rejects, or when approver "B" rejects. The "Approved" path is triggered when a "manager" approves, or approves and escalates to "A" or "B" alone and they approve, or to both "A" and "B" together and they both approve. Additionally, after "A" approves, there is another decision making path testing if "B" approval is also required.

Just imagine how messed up the whole thing is when drawn straight away. So my idea was to simplify the diagram by externalising "Approved" and "Rejected" paths from the main process and calling them when needed.

My issue here is that the only appropriate throw-catch solution that only operates within the scope of the current execution is an Error events and event sub-processes.

Frankly, using "Error" events to follow the "successful" path does not look appropriate at all - I'd say the "Signal" event is the right one, but the problem is that it triggers ALL process definitions out there which is definitely not something I desire.

Here goes the question - is it even a proper use case for the "Error" event? If not, is there anything more appropriate for my case?

Many thanks in advance.
15 REPLIES 15

trademak
Star Contributor
Star Contributor
Hi,

So why are you not using the RuntimeService getVariable method to get the approverFullName variable? You can first try via the sub process id and then via the parent process id. That should work, or doesn't it?

Best regards,

ekolesnikov
Champ in-the-making
Champ in-the-making
Yeah, I ended up mapping parent->child variables through IN parameters of the Call Activity task. Appears to be doing what I want. Thanks a lot!

bardioc
Champ in-the-making
Champ in-the-making
Hello,

just my two cents here, but have you tried to query the variables via execution.getSuperExecution().getProcessInstance().getId()

We've learned the hard way that in case you have a process started via CallActivity, any execution within the called process has a parentId of null, though a super execution that is present and is the execution of the call activity itself. You can then directly cast this super execution to VariableScope to get the process variables from the super process OR us the above mentioned call to get the super process Id and query the variables directly via Runtime Service.

Regards,

Heiko

ekolesnikov
Champ in-the-making
Champ in-the-making
Hi Heiko

getSuperExecution() is private API and therefore can not be used in production.

bardioc
Champ in-the-making
Champ in-the-making
That is your decision of what can be used in production or not. Just because the Activiti developers did not add this to public API, it does not mean it may make sense to do so. You have described yourself how you suffer from the lack of features like this. What you did is (from my perspective) just a workaround for the problem of a too restrictively handled "public" API.

Sometimes you need to use things like that. We have to use it too, because there is actually no other known way to have the same business key available in a process called via call activity as the "parent" (or "super" or how you would like to call it) process has. More importantly, for call activities, there is no parent process, which is indeed odd, cause thats how I (and others too I suppose) understand it. I might be wrong here.

Regards,

Heiko

ekolesnikov
Champ in-the-making
Champ in-the-making
Hi Heiko

There are two issues discussed in this topic.
First, general ability to access parent process instance and its variables from within call activity listeners and service tasks. This can be achieved by using subProcessInstanceId query which is a proper (although sub-optimal, in my personal opinion) way of doing this.

Second, ability to resolve expressions against parent process. After having internal architecture discussion, we decided this was a bad idea anyway - too many assumptions on what has to be included in the parent process and generally as bad as using un-encapsulated global variables in programming languages. Using IN parameters is the right (and documented) way of doing this - i.e. parent process decides what goes into reusable call activity task.

I can agree on the part that public Activiti APIs appear to be quite restrictive, however, since we are committed to using Activiti as our workflow engine, we have to deal with what we have. It may look appealing to hack one's way by creating implementation-specific code, however, this creates maintainability risk that can cause severe impact on projects' schedules and budgets in future.