Table of Contents

, , , , , , , ,

Workflow definitions and approval processes

FIXME Page ID and namespace are not decided yet - fix the internal links below before publishing.

An approval process decides whether a request (assignment of a role, change of an assigned role, recertification, …) has to be approved and by whom. It binds three things together: the event that triggers it, the workflow definition that describes the approval graph, and an optional condition that narrows down when it applies.

Since IdM 16 the product uses its own workflow engine (agenda Workflows) instead of Activiti. IdM 16.1 adds a set of workflow definitions and approval processes that are delivered with the product, so that an upgraded instance keeps approving role requests the way it did before the engine was replaced.

Version

Version Compatible with product Notes
16.1.0 16.1.0 Workflows delivered with the product, default approval processes, read only system workflows, copy of a workflow, unique code of a definition
16.0.0 16.0.0 New workflow engine, agenda Workflows, versioning of a definition

Compatible with the product from the version stated above.

Concepts

Workflows delivered with the product

@since 16.1.0 Three workflow definitions ship inside the product and are deployed on every application start:

Code What it does
`system-workflow-approve-by-manager/guarantor` Approved by the manager of the applicant or by the guarantor
`system-workflow-approve-by-manager/guarantor–role-criticality-1+` The same, but only for roles with criticality 1 and higher. Used by the default approval processes
`system-workflow-approve-by-role-guarantor` Approved by the guarantor of the requested role

They are read only

A workflow delivered with the product is managed by the application. It cannot be changed and it cannot be deleted - not through the user interface, not over REST and not by an import. The editor opens it in a read only mode: no palette, no Save, the fields are greyed out, a node cannot be moved or deleted. Clicking a node still shows its properties, read only.

⚠️ Do not try to work around the flag.
The systemWorkflow property is read only on REST, so it cannot be sent from a client, and an import never grants it either. The only write path that marks a workflow as delivered with the product is the deployment described below.
Want your own variant? Use Duplicate workflow and edit the copy. That is the supported way to build on what the product delivers.

What happens on every start

The deployment compares the shipped content with what is in the database and acts per workflow:

Situation in the database Result of the start
The workflow is missing It is created
It is there and unchanged Nothing is written
Its content differs It is repaired back to the shipped content
It was deleted It is created again
It is archived and no current version exists The archived version is restored as the current one
Another workflow occupies the shipped identifier The start fails, an administrator has to resolve it
Two current workflows share the shipped code A warning is logged and the workflow is skipped

An unchanged workflow is deliberately not saved again: a save of a definition that has instances creates a new version (see below), so writing on every start would produce a new version per restart. The comparison uses the content of the graph - its natural keys, node attribute values and edges. The layout is not part of it, so moving a node in the editor is not a content change.

Own layout of a workflow delivered with the product survives as long as nothing else differs. As soon as the content itself has to be repaired, the shipped layout is written back together with it.

When the deployment fails

The deployment runs as an initialization processor (core-init-system-workflow-processor). An enabled initialization processor that fails prevents the application from starting - that is the standard behaviour and it is intentional here: an instance without the shipped workflows would silently approve nothing. Data situations the processor recognises (an ambiguous code) are answered with a warning instead.

If starting without the shipped workflows is preferred, disable the processor in the configuration:

# Deployment of the workflows delivered with the product
idm.sec.core.processor.core-init-system-workflow-processor.enabled=true

Versioning of a definition

A definition that has no instance is updated in place. A definition that has an instance is versioned by copy on write:

Archived versions therefore share the code with the current one by design. Deleting a definition that has instances archives it as well, it does not remove it.

Uniqueness of the code

@since 16.1.0 The code of a current (not archived) workflow definition is unique. Everything that resolves a workflow by its code - the deployment above, the default approval processes, pairing of an import - expects exactly one row, and before 16.1 two current definitions could share a code even through the user interface.

The rule is enforced twice: by a partial unique index in the database (ux\_wfe\_definition\_code, only over rows that are not archived) and by a validation in the service, so a client gets a readable error (WORKFLOW\_CODE\_NOT\_UNIQUE) instead of a constraint violation.

Upgrade. The migration that creates the index renames existing duplicities first: one definition keeps its code and the following ones get the suffixes `-2`, `-3` and so on. A workflow delivered with the product always keeps its code, among the rest the oldest one keeps it. Renaming is safe, because a definition is always referenced by its identifier, never by its code.

A definition without a code is allowed and is not checked - the graph can be built before the code is filled in.

Copying a workflow

@since 16.1.0 The bulk action Duplicate workflow in the agenda Workflows creates an independent copy of the selected definitions, including the whole graph. The copy:

Export and import

A definition can be exported and imported through the standard export and import batches. Two things are specific to this agenda:

An import cannot change a workflow delivered with the product and cannot grant that flag either. An import of an unchanged shipped workflow is a no operation.

⚠️ A refused item fails the whole batch.
When an imported item violates a business rule, the import manager reports a transaction error instead of the localized reason - the reason itself is in the log. That is how the import manager reports any violated rule, it is not specific to workflows.

Approval processes

Approval processes live in the agenda Business processes. Each one binds a triggering event to a workflow.

What the product delivers

@since 16.1.0 After an upgrade the product creates the approval configuration an instance had before the engine was replaced:

Code Triggering event Workflow used
`system-process-assign-role` Assignment of a role Approve by manager or guarantor, role criticality 1 and higher
`system-process-change-assigned-role` Change of an assigned role The same
`system-process-recertificate-role` Recertification of an assigned role (module rec) The same

A process is created only when it is missing. An existing configuration is never changed, so an administrator can replace the default or switch it off.

Switch the default approval off by disabling it, not by deleting it.
A disabled process stays disabled - the deployment counts it as an existing configuration and does not touch it.
A deleted process is created again by the next start, with a new identifier.

Order and who claims a request

Approval processes are started in the order given by the order column, and the first process that reaches a concept of the request claims it - a later process is not started for the same concept. The processes delivered with the product therefore use the order `1000`, so that a process created by an administrator (order `0` unless it is filled in) always wins.

The criticality of the role is evaluated inside the shipped workflow, not on the approval process. For a role with criticality `0` the shipped process still claims the concept and then finishes without creating any approval task - the request is executed without approval.

Condition

An approval process can carry a named condition that decides whether the process applies at all (for example only for identities with a given form projection). The condition belongs to its process: it is created with it and @since 16.1.0 removed with it, including its extended attributes.

Uniqueness of the code

@since 16.1.0 The code of an approval process is unique. The database has enforced it since the agenda was introduced, but a reused code ended as an internal error - now it is refused with BUSINESS\_PROCESS\_CODE\_NOT\_UNIQUE.

A process the application cannot resolve

When the triggering event of a process is not known to the application - typically after a module was uninstalled - the process is ignored, a warning is logged and the requests of other events are not affected. The same holds for a process whose workflow no longer exists.

Configuration

In the application profile (application.properties) - overloadable via ConfigurationService.

# Product initialization data. The default approval processes are init data, so they are
# not created when this is switched off. The shipped workflows are deployed regardless -
# they are an artifact, like scripts and notification templates.
# @since 16.1.0
idm.pri.core.init.data.enabled=true
 
# Deployment of the workflows delivered with the product
# @since 16.1.0
idm.sec.core.processor.core-init-system-workflow-processor.enabled=true
 
# Creation of the default approval processes
# @since 16.1.0
idm.sec.core.processor.core-init-business-process-processor.enabled=true
⚠️ The legacy block idm.sec.core.wf.approval.* and idm.sec.core.wf.role.approval.* does not configure the approval of IdM 16.
Those keys belong to the removed Activiti engine and are read only by artifacts that are no longer deployed. The approval of IdM 16 is configured by the approval processes described above. Do not add anything there.

Known limitations

Developer guide

Services

Service Method What it is for
WfeDefinitionService upsert(dto) Standard save of the whole aggregate. Refuses a change of a workflow delivered with the product, validates the uniqueness of the code, versions the definition when it has instances
WfeDefinitionService deploySystemWorkflow(dto) The only write path that marks a workflow as delivered with the product. Used by the deployment
WfeDefinitionService duplicate(id) Independent copy, see Copying a workflow
IdmBusinessProcessService supports, shouldBeStarted Decides whether a process applies to an event and whether it claims a concept
WorkflowEventTypeManager findByCode(code) Resolves the triggering event. Returns an empty Optional for an unknown code instead of failing

Result codes

Code Status When
SYSTEM\_WORKFLOW\_DELETE\_FAILED 400 Delete of a workflow delivered with the product
SYSTEM\_WORKFLOW\_UPDATE\_FAILED 400 Change of a workflow delivered with the product outside the deployment
SYSTEM\_WORKFLOW\_CODE\_CHANGE\_FAILED 400 Change of the code of a workflow delivered with the product
SYSTEM\_WORKFLOW\_ID\_OCCUPIED 400 Another workflow occupies the identifier of a shipped one. Raised during the deployment, so it prevents the start
WORKFLOW\_CODE\_NOT\_UNIQUE 400 Another current definition already uses the code
BUSINESS\_PROCESS\_CODE\_NOT\_UNIQUE 400 Another approval process already uses the code

Extension points

Developer guide

Services

Service Method What it is for
WfeDefinitionService upsert(dto) Standard save of the whole aggregate. Refuses a change of a workflow delivered with the product, validates the uniqueness of the code, versions the definition when it has instances
WfeDefinitionService deploySystemWorkflow(dto) The only write path that marks a workflow as delivered with the product. Used by the deployment
WfeDefinitionService duplicate(id) Independent copy, see Copying a workflow
IdmBusinessProcessService supports, shouldBeStarted Decides whether a process applies to an event and whether it claims a concept
WorkflowEventTypeManager findByCode(code) Resolves the triggering event. Returns an empty Optional for an unknown code instead of failing

Result codes

Code Status When
SYSTEM\_WORKFLOW\_DELETE\_FAILED 400 Delete of a workflow delivered with the product
SYSTEM\_WORKFLOW\_UPDATE\_FAILED 400 Change of a workflow delivered with the product outside the deployment
SYSTEM\_WORKFLOW\_CODE\_CHANGE\_FAILED 400 Change of the code of a workflow delivered with the product
SYSTEM\_WORKFLOW\_ID\_OCCUPIED 400 Another workflow occupies the identifier of a shipped one. Raised during the deployment, so it prevents the start
WORKFLOW\_CODE\_NOT\_UNIQUE 400 Another current definition already uses the code
BUSINESS\_PROCESS\_CODE\_NOT\_UNIQUE 400 Another approval process already uses the code

Extension points

Things that are easy to get wrong

Notes for tests