Yes, a section from documentation I still have to add:
Over time, processes may evolve, for example because the process itself needs to be improved, or due to changing requirements. Actually, you cannot really update a process, you can only deploy a new version of the process, the old process will still exist. That is because existing process instances might still need that process definition. So the new process should have a different id, though the name could be the same, and you can use the version parameter to show when a process is updated (the version parameter is just a String and is not validated by the process framework itself, so you can select your own format for specifying minor/major updates, etc.).
Whenever a process is updated, it is important to determine what should happen to the already running process instances. There are various strategies one could consider for each running instance:
Proceed: The running process instance proceeds as normal, following the process (definition) as it was defined when the process instance was started. As a result, the already running instance will proceed as if the process was never updated. New instances can be started using the updated process.
Abort (and restart): The already running instance is aborted. If necessary, the process instance can be restarted using the new process definition.
Transfer: The process instance is migrated to the new process definition, meaning that - once it has been migrated successfully - it will continue executing based on the updated process logic.
By default, jBPM5 uses the proceed approach, meaning that multiple versions of the same process can be deployed, but existing process instances will simply continue executing based on the process definition that was used when starting the process instance. Running process instances could always be aborted as well of course, using the process management API. Process instance migration is more difficult and is explained in the following paragraphs.
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 (as variables), but also the current state in the process diagram. For each node that is currently active, a node instance is used to represent this. This node instance can also contain additional state linked to the execution of that specific node only. 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 (this clear separation of definition and runtime state allows reuse of the definition accross all process instances based on this process and minimizes runtime state). As a result, updating a running process instance to a newer version so it used the new process logic instead of the old one is simply a matter of changing the referenced process id from the old to the new id.
However, this does not take into account that the state of the process instance (the variable instances and the node instances) might need to be migrated as well. In cases where the process is only extended and all existing wait states are kept, this is pretty straightforward, the runtime state of the process instance does not need to change at all. However, it is also possible that a more sofisticated mapping is necessary. For example, when an existing wait state is removed, or split into multiple wait states, an existing process instance that is waiting in that state cannot simply be updated. Or when a new process variable is introduced, that variable might need to be initiazed 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. Of course, you need to provide the process instance and the new process id. By default, Drools Flow will automatically map old node instances to 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 inbetween), to allow 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 simply the new node id in the node container (so no unique node id here, simply the new node id). The following code snippet shows a simple 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();
// 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
// node 2, which is part of composite node 5, is mapped to a new node with id 4
If this kind of mapping is still insufficient, you can still describe your own custom mappers for specific situations. Be sure to first disconnect the process instance, change the state accordingly and then reconnect the process instance, similar to how the WorkflowProcessinstanceUpgrader does it.
I will add this to the online documentation shortly.
I'm not sure if I understand you correctly, Kris. As far as I know, current JBPM 5 implementation allows you to deploy processes from file system alone (yes, I know Guvnor integration is in the works). So, when you overwrite the old bpmn process file with a new version, you basically lose the previous version of the diagram. How the JBPM engine actually manages to "remember" old process definition? I haven't seen anything in the persistent storage (database).
Or is my assumption wrong and you have to deploy a new version of the process in a separate file with a different name (which actually makes the SCM versioning useless)? In that case how does the JBPM know the two are the newer and older version of the same business process? The name correlation is only cosmetic, isn't it? All in all, you start processes with a process id (which needs to be changed, according to your words).
I'm totally new to JBPM, so don't hesitate to send me to Drools or JBPM5 manual section where I can read more on that issue.
Okay, I have read the whole manual again. It implies (but does not say it directly) that JBPM should load the process definitions from file system at the application start via knowledge builder and then store it in memory, right? Now, when you start the particular process instance via kbase, it then saves (persists?) all the information needed to finish the proces in case something goes wrong (like server restart). Am I right?
So basically, when you upload new process definition, overwriting old file, and restart the server, all currently running (safe point) or waiting processes (on wait states, human tasks, etc) should be able to finish their work using old process definition (because the information is persisted) and all new processes will use the newly uploaded diagram?
I think an example would be very helpful here.
The process engine itself doesn't really care about process versioning directly, as far as it is concerned, two versions of the same process definition are concidered different processes (they just have the same name and a different version), and this probably makes sense as in reality two different versions of the same process definitions can actually be completely different.
You should always keep a version of your process somewhere if you still need it (for example if there are still process instances executing based on the "old" definition). So only if you make sure that all active instances of your old definition are either aborted or migrated to the newer version, you no longer need the old definition.
The process engine doesn't really care where those process definitions are stored, it just needs to be able to reload them (in case of restarting for example). So you can use file system, a repository (like Gunvor), a database, or whatever you prefer. If you use a simple file system, you probably want to have different files for each of the versions you're still using. If you use a SCM system, you can probably reuse the same file as long as you can then retrieve all the versions of the process you still need.
when I do the following steps (using JPAKnowledgeService and kbuilder takes files from META-INF directory):
- create session with kbase which includes "Process.BPMN"
- start process definition "HelloProcess"
- restore session with kbase which includes "Process.BPMN" with changed "HelloProcess" (id of process is not changed)
then new "HelloProcess" is used.
I don't understand why it is then writen in the user guide:
By default, jBPM5 uses the proceed approach, meaning that multiple versions of the same process can be deployed, but existing process instances will simply continue executing based on the process definition that was used when starting the process instance.
So what's the questions?
As the documentation and kris mention the process don't care about the version. If you change your process and keep the same id you can end up with strage behavior during runtime. It will depend on the process complexity and the changes that you apply. The engine knows the processes by the ID and if you change the process and keep the ID the engine will treat it as the old one.
The problems will start to appear when you have multiple processes instances in different stages and you change your process definition using the same ID.
My Two cents ..