Workflow proposal
Workflow is meanwhile [being] implemented in the Daisy 2.0, so the following information is left here mainly for historical purposes. The final information on workflow will be available in the Daisy 2.0 documentation.
Overview
The goal of this document is to describe possible features, architecture and implementation considerations for a default workflow system that will be added to Daisy.
We assume people are already familiar with general workflow concepts, and mainly look into how we apply this to Daisy.
Basically a workflow process is a series of steps to be performed, which typically require interaction from persons (“workflow participants”, which could also be other systems that respond assynchronously -- the key point is that the system has to wait). If a workflow step requires intervention of a person, it is called a task or work item. A task is usually assigned to some role, the system will then decide which concrete person to assign the task to. The workflow system keeps an audit trail of all activity.
Some possible use-cases for workflow, when used in a CMS, are:
-
approval: without doubt the most popular one. Once an editor is finished writing some content, the editor can start a workflow to request approval of the content for publication on the live site.
-
'write (create) a document' process: someone wants another person to write a document about a certain topic.
-
'update a document' process: the content of a document is outdated, and you want to delegate the updating of the document to someone else. Ultimately, that someone else could be yourself, in which case the workflow engine serves as a personal task list.
-
'translate a document' or 'update translation' process (i.e. create/update document language variant)
-
'request feedback' workflow
-
or combinations of these into one bigger workflow
Daisy should include a number of default workflows that can be used 'out-of-the-box'.
The high level architectural view
[todo: diagram]
Inside the repository server an additional workflow component will be added. This will be an optional extension component, i.e. it won't change the core repository server code.
The Workflow component will have a Daisy-defined interface, independent from any underlying workflow implementation we will choose to use. This interface will allow to do things such as:
-
retrieve the list of open tasks (all for a user, all for a user + roles, all -- filtered by access control on process instances)
(mpo) possibly also: ordered by priority, due date,...
-
retrieve the list of available workflow definitions a user can start
-
instantiate a new workflow instance (based on a certain workflow definition)
-
get the details of a task: required input variables and possible transitions.
(mpo) currently unclear how this 'required input variables' should be working, maybe taking up a task in the list could be starting an apple that guides me through some steps, at the end of which the task would be marked as ended? Possibly continuing automatically into new ones?
-
update a task:
-
save or save+transition on a certain task. Response is: who's next, or 'process ended'
-
re-assign the task to someone else (person or role)
-
-
get list of all process instances
-
possibly filtered by object (document), state (open or ended), or any process variable...
-
-
get details of a process instance:
-
open tasks (can be multiple ones per process instance when having forks/joins)
-
log
-
tokens (see jBPM) are probably too low level to expose here
-
-
...
- ...
(mpo) other ideas coming to mind:
- Having some kind of browseable 'service' and 'task' catalog to the flow-editor out of which he/she can select. (in this area also: maybe allowing to have 'saved' document-tasks that can be assigned as tasks inside a flow?)
- A way to manage the deployed (or 'registered') flows in the workflow component (i.e. also allow for new ones to be uploaded and made available to the system run-time?)
Creating workflow definitions themselves is very dependent on the actual workflow engine (Daisy won't have its own workflow language), so this will probably not be part of this generic interface.
An alternative would be to have a Daisy specific workflow definition, and translate this to something that can be processed by the underlying workflow engine, but that seems quite limitting, and is additional implementation work.
The Workflow component will of course have a Java API. It will also expose its functionality via a HTTP/XML API, and the Java API will be implemented in a remote variant which communicates over the HTTP/XML API, like is already the case for all of the repository server.
In theory, the workflow engine in Daisy could be used for any purpose, i.e. there are no technical limits on what you can do with it.
In some cases companies might already have a workflow system, and want to define processes in which doing some task in Daisy is only one step in the process. This is of course fine, and has nothing whatsoever to do with the here proposed solution.
Workflow engine
Reusing an existing workflow engine, just like reusing anything else, has several benefits. It saves a lot of time and effort: less design decissions to make, less code to write, debug and document. In addition, we benefit from new developments of the workflow engine. This of course at the cost of having to learn the system, and coping with mismatches between what we need and what is provided.
Currently we are thinking of using jBPM as workflow engine. This engine is easy to integrate (it is a library rather than a server) and it is well-documented. Its license is LGPL (which is less attractive).
Some things jBPM does for us:
-
defines a workflow definition format (XML, zip package with associated classes) (no standard)
-
execution of the workflow processes (obviously)
-
persistence
-
versioning of workflow definitions: existing workflow instances keep using the old workflow definition, holds also for classes used by the workflow model
-
it is not really a server with running processes etc, but rather a library to execute workflow models. It is possible to start a SchedulerThread to execute scheduled actions.
-
it has an eclipse-based design tool for the workflows. One big plus of this tool is that it also saves a graphical diagram of the workflow, together with an XML file specifying the coordinates of the workflow nodes in the diagram, allowing to display the workflow to the user and highlight the active step.
Quick jBPM technical summary
To get started with jBPM, you can read its documentation and download a starters kit which comes complete with a webapp so that one can play around with it to get some feel of how things work.
What follows is a short technical summary, probably a little too dense, and mainly targeted towards myself for refreshing my memory.
A workflow is defined by a Process Definition. A process definition consists of nodes and transitions. Based on a process definition, a process instance is created. Both process definitions and process instances are Java objects, which can be persisted to the database if desired (via Hibernate).
A token, also called an execution, represents a certain execution path through the process. A token has a reference to a certain node in the process, which is the node where the execution is currently located. A process instance has by default one root token, but child tokens can be created by certain nodes, e.g. by a parallel split node, where multiple execution paths are followed concurrently. In such case, the parent token can only move further when all the child tokens have arrived at the same join node.
A node has an execute method, when execute is called on a node, the node can do something and is also responsible for forwarding the execution by calling the take() method of a transition. A process keeps executing (as a sequence of method calls executing in the current thread) until there's a node that doesn't forward the execution. During all this, the token is passed on so that on entering of a node, the current node property of the token can be updated. To restart (continue) the execution of a process, the token.signal() method is called, possibly with the name of a transition to take as argument. [this will often be done implicitely via task.end()]
Starting the execution of a process is typically done by calling processinstance.getRootToken().signal().
A task is just a special type of node in the process, which upon entering registers a task with the task manager, and stops process execution. A class can be specified to handle the task assignment (it can also be done using some expression syntax). A task can have a 'controller' to control a set of variables to be completed by the user through the GUI.
Process variables allow to associate data with a process instance. More specificially, the process variables are associated with a certain token of the process instance (by default, the root token). Variables can be of various types (including serializable Java objects). There is no support for lists yet though (issue JBPM-66) (which would be handy to associate workflows with a set of documents).
(mpo) I assume the goal around these 'lists' is to provide an
easy way to be able to query which tasks/process-instances are concerning a
certain document?
From jbpm tests I've done you can have some custom task-creation upon entering a
task-node in such a way that it could create separate tasks per
document(-variant) that needs to be handled. This will probably be needed
anyway in some cases, but will still not handle the problem for bulk-tasks.
Maybe the search can be hacked in by providing separate variable-names rather
then variable-values (need to check if those can easily be searched for
existance rather then for a certain value)
Searching for process instances using variables is simply done by performing SQL searches on the database. jBPM itself does not have an abstraction for this. The database schema is documented on the wiki.
Another topic is that nodes can fire events, and that actions can be associated with events. An event can e.g. be 'enter-node' or 'leave-node', an action could be anything, e.g. sending an email.
Some of the more common node types we'll likely use are StartState, EndState, Task and Decission.
(mpo) unsure if maybe some custom node-types shouldn't be the way to go since that simplifies the jpdl syntax
Process log: ...
Some more notes about jbpm:
- A swimlane is a special name for a process role (multiple tasks in the process should be done by the same actor)
- A process definition should have a start-state and an end-state (to be executable)
- jbpm has a module concept to add extra functionality to process instances. Task management and process variables are implemented this way.
- Transient process variables are useful to pass things like Daisy's Repository object to action handlers.
- There's a difference between a 'task' and a 'task-node'. A task is not a node, but something which can be associated with either a task-node or a start-state.
- Associating a task with the start-state is useful to gather initial parameters for the workflow.
- It's possible to let a token progress through the node graph even if the tasks associated with the node are not completed. Tasks can be marked as blocking, though this doesn't work for the task associated with the start-state (which is also not instantiated automatically). It seems like the convention is to move progress only through the tasks (which are normally the only wait-states in the graph execution), not by directly signalling tokens.
- The jbpm sample webapp seems to assume a start-state always has a task.
- A tasknode can be associated with multiple tasks. In this case, choosing the transition can be a bit strange, as it is only the last person who completes a task whose choice will have effect. Probably to avoid this strangeness no more then one task should be associated with a node (unless for cases where the tasks are instantiated by other tasks or so).
- Threading/synchronisation: still need to research whether multiple threads doing something related to the same process instance is allowed (quite sure it is not meaningful), and if jbpm itself performs synchronisation or if that's up to us.
Practical Daisy-jBPM issues
jBPM uses a relational database. Should creation of this be a required step in the installation of Daisy or not?
(mpo) jbpmConfiguration has a createSchema/dropSchema method to
manage the schema's existence at run-time (works through hibernate's
SchemaExport)
It takes a while to run of course, but could be done when the appropriate
workflow-component is enabled and started?
Is the task controller (variables) flexible/powerful enough? E.g. what if you want to have a selection list for a variable?
Modelling some concrete workflows
How would e.g. an approval workflow be implemented? [would be useful to prototype this]
start state -> task state 'approve' -> end state (possibly add a 'request change and then re-approve state')
which variables? document ID (variant key), creator user ID
how does task get assigned to someone?
how does that person get notified? action associated with enter-node event?
what task variables: approved: yes/no, comment
who does the actual changing of the version state? the workflow system or the user? the repository object of the current user could be made available to the workflow (e.g. as a non-persistent process flow variable), so that workflow logic can do things on the repository, acting as the user.
What if a person that needs to approve the document does not have publish rights.
Standard action library
Some things like sending out an email notification will be pretty common, so should be included by default in Daisy.
Workflow and access control
Who can start a new workflow?
-
workflows associated with a document
-
if you have edit rights, you can start workflows...
(mpo) this seems more restrictive then generally needed? e.g. a user requests that a certain document be translated? (or the translator himself, while not having the rights on 'this' variant, takes up the request to provide the other variant)
-
more complex needs? Foresee an interface?
-
-
from-scratch workflows
-
all non-guest users?
(mpo) Expecting to at least know someone before allowing to start process-instances sounds logic to avoid DoS attacks. I think that could be a ground rule...
-
Who can access information about process instances?
-
process instances related to a document -> persons with edit rights on the document (read only)
(mpo) again I find this very restrictive, without edit- rights to any document involved it's potentially useful information for me as a co-content-provider that certain 'works' are going on. After all I might have links to those all over in my docs... (same applies for the following:)
-
other process instances -> persons related to it (the creator, the one to whom it is assigned) (creator can do everything, task assignee only things related to the task at hand)
-
administrators can see and do everything. Maybe a separate role Workflow Administrator should be introduced?
(mpo) Current feeling is that even both WorkflowAdmin and WorkflowUser (to maybe distinguish some between content-creators that should or should never participate in workflow) seem to be logical roles to add that are distinct and seperate to a large extend from the actual document roles IMHO?
A difficulty with the access control and task assignment is that it should be avoided that tasks get assigned to persons who don't have the necessary Daisy privileges to perform them.
(mpo) yep, although we should be aware that not everything can be foreseen either (ACL changes after task-assignment) So some escape through task-re-assignment should be foreseen anyway, hopefully even without requiring intervention of the workflow-admin
Workflow reporting
Lists which could be useful to retrieve:
- all workflow instances (with possible filters on user, state -- open or ended, workflow definition -- id, name, version, document association, process variables, ...)
- number of open tasks per user or per pool
- tasks which have passed their due-time
- tasks which have been open for longer than x days
Workflow GUI -- DaisyWiki integration
When viewing a document
-
show open tasks for the document for the current user
(mpo) and open tasks for the document in general (as nmentioned earlier: even if I'm not involved, knowing that things are in process might be useful info)
-
this will require an extra query upon display of each document
-
probably best to allow disabling this through siteconf
Starting a new workflow
(mpo) ...hand-picked from a catalogue of available (to me) process-flows ?
Viewing open tasks
-
tasks assigned to current user
-
tasks assigned to role which the current user has: the user can then decide to 'take' the task
“Performing” a task
(mpo) as mentioned before, this doesn't quite fit yet in my head: are we bound to have some task-instance-handling-apple that can execute the task and mark it 'ended'?
Show input fields for variables, buttons for the possible transitions to take, and the diagram with the current position in the workflow highlighted.
or
assign the task to someone else
(mpo) and 'un-assign' so it gets back in the 'group' from which
one can assign it to him/herself
I'm also wondering if those groups should only be 'role' based (in terms of
'allowed to do') or better/also 'capability' based (in terms of 'capable of
doing' like in: knowing which languages to-from translate)
Management issues
Cleanup of finished and expired (stalled) workflows. Or does everything always stay in the database forever?
Exception handling: jBPM has facilities for this, uncaught exceptions are simply thrown as usual.
Misc
Found this document about Alfresco and workflow: http://wiki.alfresco.com/wiki/Workflow. Have not read it yet.
Found this document about Magnolia and workflow: http://magnolia.sourceforge.net/30/magnolia-module-openwfe/overview.html (not yet read either)
Notes from the implementation-front
Branch
The branch where workflow development is happening is:
http://svn.cocoondev.org/repos/daisy/branches/BRANCH_WORKFLOW
Database creation
Upon initialisation of the workflow component, a check is performed to see if the jBPM schema already exists and if not it is created. After creation, this fact is recorded in the daisy_system table by adding an entry containing the jBPM version number. Since creating the schema can take quite some time, a warn message is printed to the log before/after doing it, and also to standard out.
The tables are created in the same database as Daisy. By means of an appropriate hibernate dialect, the tables are created as InnoDB-tables. The database connections for hibernate are taken from the same connection pool as used by the rest of Daisy.
Since the tables are added to the same database as Daisy, no extra effort or changes are required for backup.
Deploying of default/sample process definitions
When the jBPM tables are first created, Daisy will also deploy some default (or sample, if you which) processes.
The source for the samples can be found in the Daisy source tree at:
services/workflow/server-impl/src/processes
or in the .zip files embeddeed inside daisy-workflow-server-impl-<version>.jar.
API
Normally the only wait states in a process are the tasks, so initially the idea was to only make tasks visible through the daisy-workflow API and only allow signaling on them. However, it seems that other nodes (such as the basic 'state' node) don't forward the process execution automatically, therefore it would be better to make singinaling of arbitrary execution paths possible, and make information about the execution paths and workflow nodes available through the API.
The API approach will be quite similar to the one of alfresco, with a general WorkflowManager through which all operations are performed, and the other objects (tasks, nodes, execution paths, ...) being simple data objects without behaviourial methods. This has the advantage that (1) objects don't need to be retrieved before being able to do an operation on them and (2) that we don't need to bother updating the object state info after applying an operation on it. This makes things simpler and straightforward, though less OO (and more service-oriented).
Transactions
Database and transactions
The basic jBPM workings do not require any persistency, it is an optional step to make process definitions and instances persistent. This is done by surrounding the jBPM operations with the retrieval of a "JbpmContext" and using its methods to persist the entities.
A JbpmContext requires closing, which will close the services managed by the context, among which the "PersistenceService", and upon closing this service, the database transaction will be committed, or rolled back if JbpmContext.setRollbackOnly() was called. (The PersistenceService by default starts a transaction when the database connection is first retrieved).
So it is upon us (of course) to call JbpmContext.setRollbackOnly() in case an exception occurs, where we don't want things to persist.
If we want to do things in the same database transaction as jBPM, we can do this inside the same JbpmContext retrieve/close block, by getting the connection using JbpmContext.getConnection() or the hibernate session using JbpmContext.getSession().
Performed actions and transactions
While database changes will be rolled back in case of an error, it might be more challenging to rollback the effects of operations performed by events/actions in the workflow. E.g. a mail is send as part of the initialisation of a task, but later on an error occurs, the transaction is rolled back and hence the task is not created. A case like the mail can be covered by using a database-based mail queue, others could be handled by "compensating" operations, or not be handled at all. (these "others" could e.g. include updating a Daisy document or launching some external process)
Concurrency
About executing the same process instance in multiple threads.
A workflow instance (process instance in jBPM-speak) should not be executed by more than one thread. jBPM doesn't really help here though. I guess hibernate would detect it though when trying to save a process instance that has meanwhile has been modified by another thread. (will check later)
It might be nice though if we did some own synchronisation/concurrency checking. If we do that, we shouldn't forget the SchedulerThread.
Associating a workflow with a Daisy document (variant, version)
To associate Daisy documents with workflow instances, we make use of jBPM's context variables. This is also the recommended way to do this sort of things in jBPM (cfr. the "The state of workflow" whitepaper). Context variables in jBPM can be scoped to a certain token or task, or be global to the process instance (= associated with the root token).
For pointing to document variants (possibly to a specific version) we use WfVersionKey objects as the data type.
jBPM supports by default various data types for the process variables, and luckily allows plugging in support for new ones. Process variable values can be stored in different database columns per type, but it is also possible to store different types of data in the same column by means of a converter. This method is less intrusive as it doesn't require changes to the database schema. For the storage of WfVersionKey's, we have created a converter which converts a WfVersionKey to a string representation (documentID + "@" + branchId + ":" + languageId + ":" + version) and vice versa.
It is important that we're able to search for all process instances that are associated with a certain document, and this is possible by querying the jbpm_variableinstance table e.g. like this:
select processinstance_ from jbpm_variableinstance where converter_ = 'Z' and stringvalue_ like '5-DSY@1:1%'
In this query, 'Z' is the value we have choosen to identify the VariantKey converter, i.e. it allows to differentiate WfVersionKeys from other types of values stored in the stringvalue_ column. To limit the search to open process instances, the jbpm_variableinstance table can be joined with the jbpm_processinstance table. See the jBPM execution data model.
Process Definition Verification
When deploying a process definition in Daisy, Daisy applies some stricter checking on the process definition than jBPM does, more specifically:
- it checks the process definition has a name
- it checks the process definition has a start-state node
- it checks all nodes in the process definition have a name
- it checks all tasks (in task-node and the start-state task) have a name
- it checks all (leaving) transitions of the nodes have names
- it validates the Daisy metadata (if present) against its XML schema
Without these names, it is hard/impossible to refer to these entities from the Daisy-specific workflow metadata, or from the non-Java HTTP API, or to tell the user something about them.
If any of these fail, an exception is thrown and the process definition is not deployed.
This is implemented in the class ProcessDefinitionVerifier.
Daisy-specific process definition metadata
The jBPM ".par" process archive can contain an XML file with additional Daisy-specific metadata for the process definition. The metadata contains things such as localized labels and descriptions for the process definition, its nodes, transitions and variables, and for task nodes a description of the allowed/required variables.
This technique was inspired by Alfresco, which does something similar, though there the data dictionary stuff from the repository is reused, while we have some small independent stuff to describe the process variables.
PROCESS DEFINITION
^
PROCESS INSTANCE | Enriched with
|
DAISY-SPECIFIC PROCESS METADATA
The current format of the metadata is currently as follows:
<workflowMeta xmlns="http://outerx.org/daisy/1.0#workflowmeta">
<label [i18n="true"]>...</label>
<description [i18n="true"]>...</description>
<!-- Names of the resource bundles, in the order in
which they should be searched. -->
<resourceBundles>
<resourceBundle>...</resourceBundle>
[... more resource bundles ...]
</resourceBundles>
<!-- global variable definitions that can be reused
inside tasks -->
<variables>
[ see variable definition syntax in tasks, exactly
the same except for the base attribute which cannot
be used here ]
</variables>
<nodes>
<!-- This serves to specify metadata about nodes, currently
this is only the labels for the (leaving) transitions.
The path attribute contains the fully qualified node
name (= parent node name + "/" + node name). -->
<node path="...">
<transition name="...">
<label>...</label>
</transition>
[... more transitions ...]
</node>
[... more nodes ...]
</nodes>
<tasks>
<task name="...">
<label>...</label>
<description>...</description>
<variables>
<variable name="..."
type="string|daisy-link|long|date|datetime|actor|boolean"
scope="task|local|global" [optional, default task]
required="true|false [optional, default false]
readOnly="true|false" [optional, default false]
base="[name of a global variable]">
<label>...</label>
<description>...</description>
<selectionList>
<listItem>
[just one of the following, depending on the
variable type]
<string>...</string>
<date>...</date>
<dateTime>...</dateTime>
<long>...</long>
</listItem>
[... more list items ...]
</selectionList>
<initialValue>
[insert the same type-dependent tag as in the listItem]
[initialValue only makes sense for start-task variables]
</initialValue>
<styling>
[any attributes and child elements, depending on what
the front end supports. Currently support are:
- attribute 'width': size of input field (e.g. "10em")
- attribute 'rows': for multi-line input]
</styling>
</variable>
[... more variables ...]
</variables>
</task>
[... more tasks ...]
</tasks>
</workflowMeta>
All elements in the process meta file are optional. The process meta file in itself is also optional. The process meta file should be valid according to its XML schema, so no additional elements or attributes are allowed (if it's not valid, deploying the process archive will fail).
The file should be called daisy-process-meta.xml and be located in the root of the process archive.
The structure of a process archive file is like this:
root
|
+-- processdefinition.xml (jBPM process definition)
|
+-- daisy-process-meta.xml
|
+-- i18n (directory)
|
+-- messages bundle files (e.g. messages_en.xml, messages_fr.xml, ...)
Samples
For sample process definitions see this directory in the Daisy source tree:
services/workflow/server-impl/src/processes
Variable types
Some variable types which might need some explanation:
daisy-link
A reference to a Daisy document. More specifically, to a version of a variant of a Daisy document.
When setting/retrieving the value of this variable on the Java/jBPM level, the following type of class should be used:
org.outerj.daisy.workflow.WfVersionKey
actor
A reference to a workflow actor, which can either be a user or one or more "workflow pools".
When setting/retrieving the value of this variable on the Java/jBPM level, the following type of class should be used:
org.outerj.daisy.workflow.WfActorKey
Global variable definitions
Variables can be defined in the <variables> section of the daisy-process-meta.xml file, and then reused by means of the "base" attribute in concrete tasks. For example:
<variables>
<variable name="myvar" type="string" scope="global"/>
</variables>
[...]
<tasks>
<task name="foo">
<variables>
<variable base="myvar"/>
</variables>
</task>
</tasks>
It is possible to override each attribute or child element in the variable in the task. For example, to reuse the "myvar" variable but have it read only instead, one would do:
<variable base="myvar" readOnly="true"/>
Daisy will first search each attribute or element on the task variable, and than on the base variable. If a required attribute is not found, an error will be thrown when trying to deploy the process definition.
About i18n and resource bundles
All <label> and <description> elements can contain either a fixed label or description or a key which will be used to lookup the label in a resource bundle. If a key is intended, add an attribute i18n="true" on the label or description tag.
The resource bundles should be placed in the i18n subdirectory of the process archive. Their naming structure is as follows:
basename_<language>_<country>_<variant>.xml
The language, country and variant are all optional. These are some examples of valid names:
messages_nl_BE.xml messages_nl.xml messages.xml
When a value needs to be retrieved from a resource bundle, Daisy will search all resource bundles in the order as listed in the <resourceBundles> tag in the daisy-process-meta.xml file, performing fallback between languages.
So if the user's locale is nl_BE, Daisy will first look in messages_nl_BE.xml, if this file doesn't exist or the key is not found there then it will look in messages_nl.xml, and finally in messages.xml. Then the next set of bundles will be searched (if any). The purpose of multiple sets of bundles is to easily reuse sets of keys in different process archives.
Instead of the standard java property file format, we have opted for an XML-based resource bundle format since this is more familiar and provides more comfortable encoding support. The format used is the same as Apache Cocoon's bundles, which is something like this:
<catalogue> <message key="...">...</message> [... more message tags ...] </catalogue>
The message tags can contain "mixed content", i.e. other tags, such as:
<message key="my.description">This is an <b>important</b> thing.</message>
Special Daisy process context variables
Daisy defines some preserved context variables which have a special meaning. Their names all begin with "daisy_". The "daisy_" prefix shouldn't be used for naming your own variables.
The variables are:
- daisy_description (string, global scope): a short description of the process, used in e.g. task overview screens.
- daisy_status (string, task scope): an indication of the progress of the task (not yet started, in progress, completed)
Planned but not yet implemented:
- daisy_process_creator
- daisy_process_owner
Workflow pools
Tasks in jBPM can be assigned to an actor, which can either be a specific user or one or more pools. The definition of the pools and who belongs to it is managed by Daisy, using some specific database tables. Java, HTTP and GUI interfaces are available for this.
Process definitions authoring hints
Give all nodes, tasks an transitions names
with uniqueness according to the jBPM scoping rules. For tasks, this means globally unique.
Use tasks as the only wait-states that need human interaction
The Daisy frontend GUI only supports task-based "signaling" of the workflow execution. On the API level we also allow triggering specific execution paths, though currently there is no GUI for this.
Doing assignment based on the value of an "actor" (WfActorKey) type variable
Suppose you have a process variable of type "actor" which you use to let the user select who should perform a task. You can then do the assignment as in the following example:
<swimlane name="reviewer">
<assignment class="org.outerj.daisy.workflow.jbpm_util.ActorKeyAssignmentHandler">
<variableName>reviewer</variableName>
<variableScope>global</variableScope>
</assignment>
</swimlane>
The variableName and variableScope properties define from which process variable the value should be taken.
Workflow HTTP interface
Most workflow related URLs which return some XML take a "locale" request parameter to specify the prefered locale for localized content (such as labels and descriptions).
/workflow/task
GET:
- no request parameter: all tasks assigned to the current user
- with request parameter select=pooled, all tasks belonging to the user's pools
/workflow/task/<taskId>
GET: retrieves XML representation of the task
POST: depending on the value of the "action" request parameter:
- no action parameter: updates or ends task, as specified in the XML payload (wf:taskUpdateData, see workflowmsg.xsd)
- action=requestPooledTask: assign a pool task to the current user
/workflow/process
POST: start a new workflow process. The parameters are specified in the XML payload, which is an wf:startProcess element (see workflowmsg.xsd)
/workflow/process/<processId>
GET: retrieves an XML representation of the process instance
POST: signals an execution path. Request parameters: executionPath (required) and transitionName (not required). Returns an XML representation of the execution path.
/workflow/processDefinition
GET: retrieves an XML representation of the list of all process definitions, in all their versions. Add a request parameter latestOnly=true to get only the latest version of each process definition.
POST: deploys a new process definition. The payload should be a multipart request containing an item named "processdefinition" which contains the process definition, either in XML form or as a process archive (zip file). The content type of the item should be set accordingly, thus to text/xml or application/zip.
/worfklow/processDefinition/<id>
GET: retrieves an XML representation of this process definition
DELETE: permanently deletes the process definition. Be careful: this also deletes all process instances associated with this definition, without any further warning.
/workflow/processDefinitionByName/<name>
GET: retrieves an XML representation of this process definition.
/workflow/pool
GET: retrieves the XML representation of the list of either:
- all pools
- the pools to which a certain user belongs, specified using the request parameter limitToUser=<userId>
POST: creates a new pool, the payload should be an XML document with wf:pool as root element (see pool.xsd)
/workflow/pool/<id>
GET: retrieves an XML representation of the pool
POST: updates the pool by submitting an updated variant of the XML representation retrieved using GET.
/workflow/poolByName/<name>
GET: retrieves an XML representation of the pool.
/workflow/pool/<id>/membership
GET: retrieves the list of users that are member of this pool (as a wf:users element, see pool.xsd).
POST: updates the membership of the pool, according to the value of the "action" request parameter:
- add or remove: adds or removes users to/from the pool. The users should be specified in the XML payload as a wf:users element (see pool.xsd)
- clear: removes all users from the pool
Open TODO's
These are some things that might be considered later on:
- jbpm adds quite some time to repository startup, making it even more useful to have some message printed when the repository server is completely started up.
Upgrade instructions stuff
Here things are collected which will need to be added to the upgrade/compatibility/... instructions.
add following to the myconfig.xml:
<target path="/daisy/extensions/workflow/workflow-manager">
<configuration>
<jbpm>
<hibernate>
<properties>
<entry key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</entry>
</properties>
</hibernate>
</jbpm>
</configuration>
</target>
for automated installs, the new property dbHibernateDialect should be provided for the daisy-repository-init script
The workflow changes contain some extra database schema changes (on top of the other Daisy 2.0 changes).



There are no comments.