IBM Business Automation Manager Open Editions (BAMOE) has evolved its event streaming capabilities between versions 8 and 9.
BAMOE v8 allows users to configure the KIE Server to emit Kafka messages about every event when a process, case, or task is completed.
BAMOE v9 introduces a more modular and flexible approach using add-ons to enable messaging and event-driven capabilities in Quarkus or Spring Boot projects. Events are published in the CloudEvents format, making them easily consumable by external systems.
Events are categorized into:
-
Messaging Events: Related to BPMN message elements.
-
Process/Runtime Events: Related to process instances, tasks, and variables
Messaging event add-on
This add-on enables integration between BPMN message elements and external event sources or listeners, depending on the message type.
For more information see Using Events in Workflows
Process event add-on
This add-on emits events when operations alter the state of a process. Such operations include the creation of a process instance, task transitions, and variable modifications. Events are published in the CloudEvents format, with the data field containing a JSON representation of one of the following types
For more information see Using Events in Workflows
Migrating Event Listeners from BAMOE v8
Every time a process or task changes to a different point in its lifecycle, the Process Engine generates an event. You can develop a class that receives and processes such events called an event listener.
The BAMOE 9.5 Process Engine provides a default implementation of the event listener interface. You can use this implementation as a starting point for your own implementation via the following two interfaces: ProcessEventListener and UserTaskEventListener.
The main elements to consider when migrating your Event Listeners from BAMOE 9.5 to 8.0.x are:
- Event timing
-
In 8.0.x, you had separate before/after callbacks to distinguish when your code runs relative to the state change. In (VERSION), the single callback is invoked after the state change, and you have access to both the old and new states via the
eventobject. - Interface changes
-
TaskLifeCycleEventListeneris replaced byUserTaskEventListener. - Event object changes
-
Replace
TaskEventwith the appropriate event type (UserTaskStateEvent,UserTaskAssignmentEvent,UserTaskVariableEvent, etc.). - CDI registration
-
In 9.5 CDI is used for listener registration. There is no need for manual registration
If you have implemented your own event listener in 8.0.x the following sections provide more information to help you upgrade your code to work with 9.5.
For more information about migration, see Tutorial 05: Event Listeners Migration from BAMOE v8 to v9.
The Process Event Listener Interface
The ProcessEventListener interface is mostly the same in 8.0.x and 9.5. The main difference is that are few additional event methods in 9.5, namely:
-
onSignal
-
onMessage
-
onError
-
onMigration
-
onProcessStateChanged
-
onNodeStateChange
The User Task Event Listener Interface
The TaskLifeCycleEventListener interface in 8.0.x has been replaced by UserTaskEventListener in 9.5. The main difference is that the TaskLifeCycleEventListener interface had separate beforeTaskXXX() and afterTaskXXX() methods. In 9.5 a different pattern where a single callback method receives an event containing both the old and new states, as shown in the code below:
// Single callback with old/new state in event
onUserTaskState(UserTaskStateEvent event) {
UserTaskState oldStatus = event.getOldStatus(); // Previous state
UserTaskState newStatus = event.getNewStatus(); // Current state
}
This architectural change means that a single event object contains all required information rather than before/after callbacks. This makes it easier to implement a listener that reacts to a single event.
The example below shows BAMOE 8.0.x code:
public class MyTaskListener implements TaskLifeCycleEventListener {
@Override
public void beforeTaskClaimed(TaskEvent event) {
// Validation logic before claim
String taskName = event.getTask().getName();
System.out.println("About to claim task: " + taskName);
}
@Override
public void afterTaskClaimed(TaskEvent event) {
// Notification logic after claim
String owner = event.getTask().getActualOwner().getId();
System.out.println("Task claimed by: " + owner);
}
}
And the equivalent code in BAMOE 9.5 is:
@ApplicationScoped
public class MyTaskListener implements UserTaskEventListener {
@Override
public void onUserTaskState(UserTaskStateEvent event) {
UserTaskState oldStatus = event.getOldStatus();
UserTaskState newStatus = event.getNewStatus();
// Check if this is a claim transition (Ready → Reserved)
if (oldStatus != null && "Ready".equals(oldStatus.getName())
&& "Reserved".equals(newStatus.getName())) {
// Same logic as BAMOE 8 beforeTaskClaimed
String taskName = event.getUserTask().getTaskName();
System.out.println("About to claim task: " + taskName);
// Note: actualOwner info available via getUserTaskInstance() if needed
System.out.println("Task claimed");
}
}
}
For more information on the Event Listener Lifecycle in 9.5 see Working with Events → Implementing an Event Listener Lifecycle in the Process Engine
Migrating External Event Emitters from BAMOE v8
In BAMOE 8.0.x, users who needed to replicate engine state to an external read model (for example, an Elasticsearch index that powers a custom dashboard) implemented a custom EventEmitter on top of TransactionalPersistenceEventManager. The engine delivered InstanceView-style snapshots through the deliver / apply / drop lifecycle around the JTA transaction.
In BAMOE 9, the v8 type names (EventEmitter, InstanceView, TransactionalPersistenceEventManager) no longer exist. The equivalent extension point is the org.kie.kogito.event.EventPublisher interface in kogito-api. The engine batches the events produced during each command and delivers the batch to every registered publisher when the unit of work commits. If the unit of work is aborted, the batch is discarded and the publisher is not called.
The customer surface is preserved: one (or two) implementation classes, registered through standard CDI / Spring annotations instead of a META-INF/services file.
Type-by-type mapping
The following table shows the 8.0.x types and their 9.5 equivalents:
| BAMOE 8.0.x | BAMOE 9.5 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
For the full EventPublisher SPI reference, the two implementation styles, and a working code example, see Working with Events → Publishing engine events to an external read model.