Adding/removing execution listener at runtime permanently

I have two main questions on the topic:
A. So I managed to add an execution listener at runtime as follows:

processEngine.getRepositoryService().getBpmnModel(processDefinitionId).getMainProcess().getExecutionListeners().add(listener);

But how do I save the resulting bpmn model, as if the execution listener was configured from the start? I also need to be able to remove it.

Basically the use case is a web hook where a target url is subscribed, to which new process instance events will be published. So I thought the subscribe process could add an executionlistener which then publishes newly created process instances (and other things like tasks in future) to the target url .

B. Another consideration is that afaik the process instance is not yet committed at this point, so if the event is published to external service and that service then makes other calls related to that process instance they would fail right? Is there a way to only publish at the first wait state when it is committed?

Hi,

To dynamically change process definition I would use DynamicBpmnService.
What I would expect in your case is that definition is changed, but it is not parsed. May be you can try to hook into process parsing and add listener dynamically.

In your case I would use message or signal start event to start process instances.

I did not understand B question. Could describe the case little bit more?

Regards
Martin

Thanks Martin. Firstly as a note I should probably have been clearer in the sense that my code above works for registering the listener, I just need to save it to database so it is there after a restart as well.

I looked at DynamicBpmnService, but seemingly missed the “saveProcessDefinitionInfo” method the first time around, will check that out, thanks.

In terms of starting with a message or signal: It shouldn’t matter HOW the process is started, I want to notify a third party that it did and give it a reference to the process. The third party could register an execution listener remotely at any time on any process definition, and then later be notified of process start events along with the relevant process instance id. Then the third party could at any time send REST queries to the process engine using the id of that process instance.

On B:
So in the below sequence of events, note the two threads and note that the execution listener is already registered:

  1. Thread 1: Start process: processInstanceId=589
  2. Thread 1: Execution Listener -> http post processInstanceId=589 -> Third Party
  3. Thread 1: 589: Service Task 1
  4. Thread 2: Process Engine <- http get processInstanceId=589 <- Third party
  5. Thread 1: 589: Service Task 2
  6. Thread 1: 589: User Task 1 -> commit start process transaction -> wait state

I may be wrong but as far as I understand at the time Thread 2 queries the process engine it won’t find that process instance because it would not be committed yet. Or am I mistaken?

If I am correct then for the sake of concurrency it would be ideal if the notification to the third party only happens right after the next wait state. Is there some way to hook into that “first wait state”? Or if there is no user task the final state I guess?

Hi ruzkant,

True, - please create a pull request :-).

On B:
I would change execution listener into service task with the same logic. (Service Task 0)
Let’s make Service Task 0 asynchronous (wait state), and then process instance state is already committed to the storage.
The side effect is that user is not informed that process instance has successfully passed through Service Task 1, 2.
In your case when one of these tasks fails - process instance is not created anyway, but third party has process instanceId already.

Martin

I meant I now saw there is a method already, I just need to figure out how to use it:

void saveProcessDefinitionInfo(String processDefinitionId, ObjectNode infoNode);

[Edit: this does not work as I expected as a way to save changes to process definitions, so I understand the “create a pull request” comment now]

On B:
Ok, thanks will look into async. I was hoping to avoid “polluting” the process flow diagrams etc.

Looking at docs I see the concept of triggerable for a service task. Will have a look there as well.

thanks…