Skip to main content

Case Migration

This tutorial describes the way how you can do migration for Case Instances from one definition version to another definition version. To understand the background of the need of migration the Model Migration overview gives a general overview.

Different APIs to Execute Migration

There are different levels to execute migration:

  1. Migrating a single case instance
  2. Migrating all case instances from a case definition
  3. Batch migration of all case instances from a case definition

To execute the migration you need to specify a migration document which then can be executed in the different environments.

In addition to the above APIs, it is also possible to migrate historic case instances. This is intended in case you are using case reactivation to reopen a case, so that the case will open in a specific version again. Please note, during migrating a historic case instance you can't specify any migration mappings and expressions since the case remains closed.

The following historic migrations are available:

  1. Migrating a single historic case instance
  2. Migrating all historic case instances from a case definition

It will not automatically migrate completed/terminated case instances when you migrate active instances and vice versa.

The following section about the migration document only applies to the migration of runtime case instances.

The same APIs also exist as Java APIs as part of the CmmnMigrationService. The migration document is available in a builder pattern on the different operations.

Migration Document

Considering we are doing a migration from the following case (testMigrationCase in version 1):

Simple case diagram with two human tasks connected with a sentry

To this case diagram (testMigrationCase in version 2):

Simple case diagram with one human tasks and one service task connected with a sentry

The migration document is a JSON document would have the following content the following content:

{
"toCaseDefinitionKey": "testMigrationCase",
"toCaseDefinitionVersion": 2,
"terminatePlanItemDefinitions": [
{
"planItemDefinitionId": "humanTask2"
}
],
"moveToAvailablePlanItemDefinitions": [
{
"planItemDefinitionId": "serviceTask1"
}
]
}

Specifying the Destination Definition

PropertyDescription
toCaseDefinitionIdId of the case definition to migrate to, this ID is unique and the other toCaseDefinition-properties do not need to be provided. The ID is typically different in different environments.
toCaseDefinitionKeyThe key of the case definition which should be migrated to, this must be specified together with the version.
toCaseDefinitionVersionThe version number of the destination case definition. Please be aware that this version number might be different between different environments.
toCaseDefinitionTenantIdTenant in which the source and destination case definitions are. Only required in case of migration in a multi-tenant environment and without the toCaseDefinitionId.

Changing the State

There are several different possibilities to switch the state of specific plan items. Those plan items are referenced by the ID in the model. For each of the plan items it is possible to change the state. In case an element is deleted from the case during upgrade and the instance has a still active plan item, it is mandatory to also terminate that plan item.

All the following configurations have the following sub-properties available:

PropertyDescriptionExample
planItemDefinitionIdThe id of the plan item the configuration is about.humanTask1
conditionA condition which will be evaluated for each plan item to check if the mapping should be executed.${planItemInstances.definitionId("humanTask2") .completed().exists()}

Activating Plan Items

In case there are new plan items in a stage which is already active, then it's required to activate the plan item instance. This can be done by specifying activatePlanItemDefinitions. This is an array and for each object it's required to provide the planItemDefinitionId. Additionally, to the common properties also the following properties can be provided:

PropertyDescriptionExample
newAssigneeAllows to set the assignee of a human task.shane.bowen
localVariablesSet local variables to the specified plan item.{"myLocalVar": true}

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"activatePlanItemDefinitions": [
{
"planItemDefinitionId": "humanTask1",
"newAssignee": "shane.bowen",
"localVariables": {
"showUserInfo": true,
"additionalContext": "Test Task",
"numberOfDays": 5
},
"condition": "${planItemInstances.definitionId(\"humanTask2\").completed().exists()}"
}
]
}

Move to Available

For new plan items which are guarded by a sentry and which do not need to be directly activated, those can be moved to available. This only needs to be done when the stage in which they are is also available. For specifying plan item definition ids which need to be moved to available, the moveToAvailablePlanItemDefinitions can be used. This is an array and for each object it's required to provide the planItemDefinitionId. Additionally, to the common properties also the following properties can be provided:

PropertyDescriptionExample
localVariablesSet local variables to the specified plan item.{"myLocalVar": true}

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"moveToAvailablePlanItemDefinitions": [
{
"planItemDefinitionId": "serviceTask1",
"localVariables": {
"showUserInfo": true,
"additionalContext": "Test Task"
},
"condition": "${planItemInstances.definitionId(\"humanTask2\").completed().exists()}"
}
]
}

Terminating Plan Items

In case plan items are removed or plan items should be stopped during the migration, those can be terminated. This is specified inside the terminatePlanItemDefinitions. For the termination it is not important to consider if those are active, since they are only terminated in case they are active. This is an array and for each object it's required to provide the planItemDefinitionId. Besides the common properties, there are no specific properties for terminating.

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"terminatePlanItemDefinitions": [
{
"planItemDefinitionId": "humanTask1"
}
]
}

Waiting for Repetition

Sometimes it is required to change the waiting for repetition of an object. Therefore, the options waitingForRepetitionPlanItemDefinitions to add repetition and removeWaitingForRepetitionPlanItemDefinitions to remove repetition are available. This option will create a plan item instance with waiting for repetition or remove it in case it exists. Adding it only needs to be done when it is expected that the plan item instance will be created, the condition can be used to add it only in the appropriate cases. Besides the common properties, there are no specific properties for adding/removing repetition.

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"waitingForRepetitionPlanItemDefinitions": [
{
"planItemDefinitionId": "humanTask1",
"condition": "${planItemInstances.definitionId(\"humanTask1\").completed().exists()}"
}
],
"removeWaitingForRepetitionPlanItemDefinitions": [
{
"planItemDefinitionId": "humanTask2"
}
]
}

Pre and Post Upgrade Expressions

It is possible to execute an expression before and after the migration. Those are the preUpgradeExpression and the postUpgradeExpression. It is possible to use them to for example ensure pre-conditions or do an upgrade of child process or case instances.

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"preUpgradeExpression": "${customCaseMigrationService.preMigration(caseInstance)}",
"postUpgradeExpression": "${customCaseMigrationService.postMigration(caseInstance)}"
}

Case Instance Variables

To set additional variables on the case, the property caseInstanceVariables is available. It is possible to provide a map with different fields as a payload.

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"caseInstanceVariables": {
"showUserInfo": true,
"additionalContext": "Test case level",
"numberOfDays": 5
}
}

Change of Plan Item IDs

In case the plan item id is changed, this can be specified with changePlanItemDefinitionWithNewTargetIds. It is required to provide the plan item definition id as well as the target id.

PropertyDescriptionExample
existingPlanItemDefinitionIdOriginal plan item definition id which is renamed in the new version.processTask9
newPlanItemIdId of the plan item in the new version, typically the plan item definition id prefixed with planItem when using Flowable Design.planItemprocessTask6
newPlanItemDefinitionIdNew plan item definition id in the new version.processTask6

Example:

{
"toCaseDefinitionId": "CAS-4ce9eaf6-6287-11ef-ae73-e68ac21327db",
"changePlanItemDefinitionWithNewTargetIds" : [
{
"existingPlanItemDefinitionId" : "processTask9",
"newPlanItemId" : "planItemprocessTask6",
"newPlanItemDefinitionId" : "processTask6"
}
]
}