3.11. Process Instance Migration

A process instance contains all the runtime information needed to continue execution at some later point in time. This includes all the data linked to this process instance (such as variables); it also includes the current state in the process diagram. For each node that is currently active, a node instance contains the state of the node. This node instance can also contain additional state information linked to the execution of that specific node. There are different types of node instances, one for each type of node.
A process instance only contains the runtime state and is linked to a particular process (indirectly, using ID references) that represents the process logic that needs to be followed when executing this process instance. The clear separation of definition and runtime state allows reuse of the definition across all process instances based on this process, and it minimizes runtime state. As a result, updating a running process instance to a newer version so it uses the new process logic instead of the old one is simply a matter of changing the referenced process ID from the old ID to the new ID.
However, this does not include the state of the process instance (the variable instances and the node instances) which might need to be migrated as well. In cases where the process is only extended and all existing wait states are kept, the runtime state of the process instance does not need to change at all. However, it is also possible that a more sophisticated mapping is necessary. For example, when an existing wait state is removed or split into multiple wait states, an existing process instance in a wait state cannot simply be updated. When a new process variable is introduced, the variable might need to be initiated correctly so it can be used in the remainder of the (updated) process.
The WorkflowProcessInstanceUpgrader can be used to upgrade a workflow process instance to a newer process instance. The process instance must be provided with the new process ID. By default, the old node instances will be automatically mapped to the new node instances with the same ID. But you can provide a mapping of the old (unique) node ID to the new node ID. The unique node ID is the node ID, preceded by the node IDs of its parents (with a colon in-between), to uniquely identify a node when composite nodes are used (as a node ID is only unique within its node container). The new node ID is just the new node ID in the node container with no need to reference unique node IDs. The following code snippet shows an example.
// create the session and start the process "com.sample.process"
KnowledgeBuilder kbuilder = ...
StatefulKnowledgeSession ksession = ...
ProcessInstance processInstance = ksession.startProcess("com.sample.process");

// add a new version of the process "com.sample.process2"
kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(..., ResourceType.BPMN2);
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

// migrate process instance to new version
Map<String, Long> mapping = new HashMap<String, Long>();
// top level node 2 is mapped to a new node with id 3
mapping.put("2", 3L); 
// node 2, which is part of composite node 5, is mapped to a new node with id 4
mapping.put("5.2", 4L); 
WorkflowProcessInstanceUpgrader.upgradeProcessInstance(
   ksession, processInstance.getId(),
   "com.sample.process2", mapping);
If this kind of mapping is insufficient, you can describe your own custom mappers for specific situations. First disconnect the process instance, change the state accordingly, and then reconnect the process instance. This is similar to how the WorkflowProcessinstanceUpgrader does it.