How to intercept a Delegate Execution in Camunda BPM
This article shows you how to get variables or other information before invoking the delegate logic in Camunda BPM. This is interesting for invoking logic before a delegate is started, for example login procedures, logging and event generation.
In one of our Camunda BPM projects we had to implement a shared process model for multiple tenants. This is typically no problem. But in this case the invoked services required a dedicated security context for each tenant. This basically came down to the point that the process had to run with three different technical users for authentication. We didn’t want to integrate the login logic into every Java Delegate. Therefore we looked for a spot to hook the logic into. We found a way to intercept the logic before the execution of the delegates.
It is possible to access a delegate execution before the delegate itself will be executed. The engine provides a
@ProcessApplication annotation for the process application startup. This class is the central point for Camunda BPM to load needed resources of the implemented process. It is possible to implement your code during deployment or undeployment.
The following picture shows the invocation of the interceptors during executing the Java Delegates. If you implement the function
execute in the process application, the code will be intercepted before the Java Delegate will be executed. Alternatively, it is possible to integrate a Groovy Script or the Connector API (or other implementation possibilities) instead of a Java Delegate. You don’t need to handle the login mechanism in the specific implementation.
In this example, it will be a login for a technical user within the security environment before the delegate logic will be executed. You can control this function by extending the class
EjbProcessApplications ). For getting the process variables, you have to override the function
public<T>Texecute(Callable<T>callable,InvocationContext invocationContext) and you can get the current execution with
BaseDelegateExecution execution=invocationContext.getExecution(); . There it is possible to manipulate every process variable and you can read some information about this execution. If you want to do further things, you have to inject the
RuntimeService and get the whole process instance via the execution identifier. Then you can manipulate the instance via the Camunda BPM Java API.
I have used this mechanic to get a process variable with a tenant identifier. Then it was possible to identify the technical user for the login logic. In Camunda BPM it is possible to set process variables as needed. In newer Camunda BPM versions (7.5+) you don’t need to use a variable to get the tenant id. You can get this id over the
RuntimeService with the execution id.
On the technical layer the execution runs on a thread. This thread contains the delegation code with all the interceptors. If you call a login function in this thread, all code will be executed with the logged-in user. In this special case, I run the login mechanic of the IBM Websphere Application Server (WAS). Then the WAS adds the needed SOAP security header with a LTPA token to all web service calls. The services are now reachable with the needed security and I don’t have to care about how to add security to my web service calls.
thrownewIllegalStateException("Callable is null");
The possibility to get the variables or other process information on a central position in a process application allows integrating central mechanics, which don’t have to be instantiated on every delegate implementation. This can simplify your application.