Adaptive Case Management

Classic BPM processes have a clear flow that defines how the process is executed. Within these strict processes the involved user has limited possibilities to improve the process while executing. Optimizations and flow changes often require a long modeling and re-deployment round-trip. Furthermore the process could get cryptic because every rarely occurring special case has to be modeled. Therefore, the process does no longer clearly show the most relevant business paths. Welcome to the world of spaghetti BPM.

Today the user has the need to adapt the process flow during execution. Optional side tasks are required in addition to the normal process flow or a set of tasks must be skipped because of a special condition. This brings back the power to the user which has often more knowledge about the domain and the current context of the process. For instance an important information could be received from a phone call, but the workflow system has no knowledge about this analog information.

Adaptive implementation

Invoking optional processes

Think about a process where the purchase of an asset must be approved by a line manager. The line manager may want to ask the requester to provide more details why the asset is required. Therefore he’d add a side task to ask the requester for clarification. This optional interaction should not be wired into the main approval process as it obfuscates the most used business path. But it could be available as an optional side task that the line manager can start and then gets executed within the current process context.

In Axon.ivy processes with side tasks can be invoked through Triggers or Signals.


It is possible to trigger a strictly defined process. Strictly defined means that the calling process knows the target process as it has to be implemented in the same or a required project. RequestStart events can be declared as trigger-able. While the Trigger activity is used to actually trigger such a start.

So in the request verification front end, a manager could simply trigger the process to enrich the request with a trigger call activity.




Most of the time you’d prefer a looser coupling between processes. This could be accomplished with Signals. A process that wants to integrate other processes simply fires a signal when a certain state within the process is reached. Multiple other processes in the same application could listen to this signal and all of them will be executed as soon as the signal is fired. A dependency between the firing and listening processes is not required.

As example think of an employee that starts to work in a company. When the employee is registered from HR, other processes can setup the environment for this employee. An IT responsible will setup a new desktop workstation while an office administrator will get the personal keys for the employee. To do this tasks in parallel and loosely coupled signals are the first choice. The IT- and the office-process could listen to employee entry signals fired by the HR process.


Keeping loosely coupled processes in same context

A real world agile process execution can touch many different processes. But still the history and the context must be clear for anyone who is involved in a task. So the workflow needs to know whether an invoked process belongs to the invoking case. Or if the invoked process belongs to a completely new case.

The entity that can glue multiple process cases together is the Business Case. All cases and tasks that belong to the same Business Case are presented to the user of a workflow screen as related cases. Therefore, triggerable- and signalable-process start must define whether they belong to the same Business Case as the invoking process case. This can be done with a simple configuration on these starts. See Signal Start and Trigger Start inscription for details.


You can also use the Public API to attach the current case to an existing Business Case.

if (in.departement.equals("HR")) // evaluate attachment by runtime conditions

For workflow front end developers there exists API to list all tasks or cases of a Business Case. So showing the involved cases and tasks to a workflow user is a simple implementation. For more details see the Public API of ch.ivyteam.ivy.workflow.businesscase.IBusinessCase.; // get involved tasks that are active; // get all involved tasks

Aborting tasks

A long running process could get into the situation that there are many open tasks that have to be done by human users. But eventually the environment of the case changes and it does no longer make any sense to accomplish the open tasks. For instance think about a car leasing process. If the customer decides shortly before contract signing that he requires leather seats instead of the furnished ones, the car will get more expensive. So the whole credit assessment process has to run again and open tasks become obsolete.

A User Task can support abortion by listening to a signal. The UserTask activity can subscribe to an abortion signal by adding a Signal Boundary Event on it. When the signal, that the credit amount of the car changed, is fired from another process the listening UserTask will be aborted. And the process continues at the Signal Boundary Event. Classically after the Signal Boundary a clean up process follows.


Share data between processes

Often an initial larger process starts by gathering data that is later processed and enriched. This data is typically business relevant domain data that can be recognized by domain experts that contribute to the process. Think of bank employee that grants credits. The data for his processes could look like this when simplified:


To store this kind of data Axon.ivy provides a simple repository that is called Business Data. This stored data can then be accessed by multiple processes instances during the lifetime of a long living complex process. The repository provides access to the data with simple store and load functions similar to well known other repositories such as the EntityManager from JPA. But in comparison to JPA and similar technologies this repository can be used without any database or environment configuration.

CreditRequest creditRequest = ivy.repo.get(CreditRequest.class); // load a CreditRequest from the Business Data Repo
creditRequest.amount = 30000; // modify a field; // save the modified CreditRequest back to the Repo.

By annotating a data class with the @BusinessCaseData annotation, all values of the annotated data class are automatically associated with the context of the current Business Case. The data is then shared and accessible from all processes belonging to the Business Case. Multiple data classes of different types can be used inside a Business Case.

Business Data analytics

Running business processes typically generate highly valuable data, that could influence critical business decisions. Based on the stored data you will typically want to visualize KPIs on a management dashboard. In our credit sample, you may want to visualize the aggregated sum of all open credits. The data in the Business Data repository is stored in form that is easily accessible and explorable with a tool like Kibana.


Regaining the big picture

Real world BPM projects have shown that big processes tend to get increasingly complex and need to be split up into huge process landscapes, which leads to an intransparent main process flow. Users of the process often do not see how their work contributes to the bigger business process and therefore great opportunities for improvements are not taken. There is also a big need for a unique view of adaptive case operations that can be used by process contributors. Like an overview of optional tasks that a clerk can start at any time.

The Case Map addresses the needs for flexible and agile Business Cases by providing a clear and simple view on the main process and its execution. With the Case Map you can easily orchestrate the main flow of processes and the business can identify and track the stages where a running process instance is.


A Case Map is divided into stages (in the sample above the stages are: Identification, Credit rating and Approval). Each stage defines a certain phase in the life cycle of a business process. A stage consists of processes (e.g. “Collect personal data”). The default flow or also known as happy path is from left to right and from top to bottom. If the last process of a stage has finished the flow continues on the stage to the right of the current stage. Stages typically have a name and icon. The idea is to reuse this icons in Workflow UIs and processes to give the end user a hint in which stage the current Business Case is.


Besides processes a stage of a Case Map can contain Sidesteps (e.g. “External solvency service” in the Case Map above). Sidesteps can be started manually by the workflow user during the ongoing Business Case. A typical Sidestep could be a process which aborts the business process (e.g. abort request). The use of Sidesteps can reduce the time spent on technical round trips, for modeling rare and costly edge cases.


The dependencies between Case Map, Business Cases and Business Data are as follows: Processes started inside a Case Map create new cases inside the Business Case, which themselves contain tasks for the users. Data between processes can be easily shared using Business Data. A Business Case can be attached to a Case Map, which in turn controls the flow of the processes.

Relationship between Business Case, Business Data and Case Map.

Relationship between Business Case, Business Data and Case Map.


To reiterate: signals and triggers can be used to loosely respectively tightly couple different processes. The innovative Case Map brings order in to chaos of spaghetti BPM. A domain expert always has a simple graphical view on the Business Case where he contributes to. The Case Map empowers the domain expert to steer the process execution by starting optional Sidesteps or gracefully skipping large parts of the pre-modeled standard flow.

The Case Map gives the developer and the user a common language to talk about a complex process landscape. The Case Map can be read and understood by anyone that contributes to the process without an introduction. This brings back the old BPM ideas that stood the test of time.

Signal Reference

Signals inform an unknown number of recipients of a specific event that has happened. Signals are sent application-wide without the need for project dependency between the sender and receiver.

Sending Signals

A Signal can be sent programmatically and consists of a Signal Code and optional signal data.


Signal codes are defined as strings. Only letters and numbers [A-Za-z0-9] as well as the colon : as separator, are allowed characters for a Signal Code.

Valid: hr:employee:quit, flight:cancel:no:LXL398

Send a Signal programmatically

A signal with a custom signal code can be sent using the following IvyScript code:

import ch.ivyteam.ivy.process.model.value.SignalCode;

// send simple signal"datarepository:updated");

// send signal with reference"order:canceled:";

// send signal with signal data SignalCode("user:created"),;


It is not recommended to use data classes as signal data as not all receiving projects might have access to these data classes. Better send an id which references an object in a database or send payload data that is encoded as string (e.g. JSON).

Send a Signal manually in the Designer

While developing a process it is possible to send a Signal manually in the Signals page of the Designer Workflow UI Overview Page.

Receiving Signals

Signals can be received by Signal Boundary- and Signal Start-Events. Receivers can either register for an explicit signal code or a generic Signal patterns.

Signal Boundary Event

A Signal Boundary Event attached to a User Task Element destroys the task if a matching signal is received and the task is in SUSPENDED state (see also Signal Boundary Event in the Workflow chapter). The inscribed pattern on the Signal Boundary Event defines the filter for awaited signals codes:

Listens for a cancelled order signal with a specific id defined as macro:


Listens to signals that have a created postfix. E.g (user:created, order:created).



Signal Start Event

With a Signal Start a new process is started if a matching signal code is received.


Signal patterns

Receivers can listen to a specific signal by its full qualified name. Besides, it is also possible to catch multiple signal sources by listening to its common prefix.Moreover, signal listener pattern can contain wildcards (*) so that the prefixes must not necessarily be shared.

# passenger on-boarding"airport:passenger:boarding:3424");
Signal receivers for signal code Signal ‘airport:passenger:boarding:3424’

Listener pattern





Full qualified match



Prefix matches



Prefix matches



Prefix matches


Empty matches all signals by prefix



Different prefix part: crew



Wildcard matches



Wildcard matches



Only one wildcard instead of two

Tracing Signals

Signals can be traced by either using the Designer Workflow UI or the JSF Workflow UI both Workflow UIs make use of the Public API for Signals (


For debugging the signal data of a Signal event you can set a Breakpoints on a Signal Start or Signal Boundary Event and inspect the signal variable in the ‘Variables’ view.