What can and what can not be called from the execute() of an Event Handler?
When we create an Event Handler, what are the limitations of the business logic that will be triggered by the execute() method?
- Can the engine API be used? All of it (i.e. any class and method)?
- If so, how can one get hold of the API accessors?
- Can the ProcessAPI be used?
- If the ProcessAPI can not be used (because that would open a transaction inside the existing transaction), what method can be called to interact with:
- the current process instance's elements (e.g. process variables, tasks, ...)?
- other processes/process instances?
- Can the BDM be accessed (using the DAO, for example):
- for read operations?
- for update (add/modify/delete) operations?
- Can a REST API be called? (But, if it can, should it be called?)
Thank you for your help and insight,
Event handlers are executed synchronously when the entity that caused the event does change, therefore it is in the same transaction and same thread.
1. I don't think it is possible to call engine APIs here because it will try to open a new transaction. I might be wrong, I did not test that.
2. You can try with The static ways of retrieving API, but as said in 1, it is strongly possible that it will not work.
3. See 1.
4. You can use the services of the engine but they might changes when upgrading to another version (see below)
5. It should. I did not test it.
6. If you mean REST APIs that are outside of the platform (not rest API extensions and so on) It can be but IMO it should not because in case of network latency, it will produce slowness in the platform.
In general, code in those event handlers should:
- Never block, i.e. any network call, no I/O on the filesystem
- Never fail, it will fail the execution of the task
It is meant to add new features to the platform by adding your own services and calling them from those event handlers.
You can use engine services but we don't have SPI and we might break any service in any versions without warning.
Services can be retrieved only statically because handlers need to be serialized when deployed in a cluster (design issue)
This can be done as follow:
ServiceAccessorFactory serviceAccessorFactory = ServiceAccessorFactory.getInstance(); return serviceAccessorFactory.createTenantServiceAccessor(tenantId);
I will try to spend time adding that in the official documentation.