Comments
==Tom== You're invited to add comments, but please, add your name in the format as i showed at the beginning of this line.
If you want to start a discussion on a certain topic, please do that in the developers forum.
General updates to the language
Node names become process scoped
In jPDL 3, node names are scoped relative to the nesting level. E.g. nodes could have the same name if they are in different superstates. Now, the scope of the node names will be the full process definition. So no two nodes can have the same name.
Only a fixed set of characters is allowed a..z, A..Z, 0..9, space, ,.;:!?|-_+=&%$ÃÂÃÂÃÂïÃÂÃÂÃÂÿÃÂÃÂÃÂý@
If the graphical designer wants to make a separation between the node name (that serves as the id) and the label of the node, it should use the annotation with key 'label'. The graphical designer also can use the URLEncoder to allow for newlines to be inserted into node labels.
Graphical information merged into the process
Tooling should be configurable to show or hide the graphical information in the XML source view.
When people use the tooling to create the graphs, I'm sure they won't mind seeing the coordinates if they open the file in another editor. As long as the xml doesn't get too verbose.
This also creates much easier interaction with files. The alternative is to have a separate file. In that case, the two files need to be kept in sync. And the relative location of the two files becomes a convention. Merging the graph information into the process file, makes it possible to name the files as any other file and move it and rename it just like any other file. The implementation of the graphical designer will become easier as the graph information cannot get out of sync with the process information (think node renamings only in one of the two files)
Build and package information in the process
I would like the process file to include references to the class, forms and other files that need to be included in the process archive file.
E.g. then during assembly of the process archive, an ant task could be created that takes a process file and a classpath as input. the ant task could then build the package from that.
Also the deployment preferences could optionally be included.
The designer will also be able to remember the included forms and class files for later packaging and deployment operations.
Version attribute in the process definition
Processes can optionally have a version. A deployer tool (like a jboss deployer) can then automatically check if the version in the process sources is 1 higher then the highest version available in the database. If that is the case the process is deployed, otherwise deployment is ignored.
The designer tool could update the version attribute automatically if it's specified and after each deployment. A preference could indicate wether the designer should include the version in newly created processes.
==Bernd==: Also ui attributes could be included as proposed in forum
Functional elements
Functional elements are elements that can be used as nodes or as actions.
In case functional elements are used as nodes, they can be decorated with a synchronizer or a propagator as explained at the end of this chapter.
java
can be used as node
can be used as action
used to action in jPDL 3. Now, java can be used as node and as action.
Should support ActionHandler configuration with expressions (see jBPM Developers Forum)
java has :functionalElementProperties {FOOTNOTE DEF 1 1}
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
class | Yes | java class name | The class name of the java class |
ejb (invoke a method on an ejb)
script
Groovy
Beanshell
JRuby
JSR 223
task
can be used as node
can be used as action
can be defined on process level
Add direct support for approval tasks ?
Attributes | Required? | Type | Description |
---|---|---|---|
id | Yes | identifier | the id |
ref-id | Yes | id-ref | refers to the task defined in this process |
ref-resource | Yes | resource-ref | refers to the task defined in the specified resource |
label | No | text | the short name |
form | No | text | resource, url or other reference to the task form |
Elements | Multiplicity | Description |
---|---|---|
description | 0..1 | the long description |
subtask | 0.. | subtask definitions (inline or not?) |
assignment | 0..1 | swimlane assignment (either this or a swimlane assignment should be specified. in extreme cases, no assignment might be specified. in such case tasks might be offered to people depending on other properties or e.g. skills match) |
==Bernd== Maybe subtasks should be skipped? It would be the easiest to just have tasks corresponding to a TaskNode with one Task in jPDL 3. If I need more tasks, I can use a fork. I think everything else is counter-intuitive
swimlane
can be defined in process
Attributes | Required? | Type | Description |
---|---|---|---|
id | Yes | identifier | the id |
label | No | text | the short name |
Elements | Multiplicity | Description |
---|---|---|
description | 0..1 | the long description |
assignment | 0..1 | swimlane assignment (only optional for swimlanes that are associated to an initial node, in that case the initiator of the process instance is captured as the swimlane actor) |
ws-invoke
Based on JAX-WS
Attributes | Required? | Type | Description |
---|---|---|---|
wsdl | Yes | file reference | process archive file reference to a wsdl file |
operation | Yes | text | the operation name to be invoked |
service | No | text | the service name. This only needs to be specified if there are multiple services defined in the WSDL. |
port | No | text | the port name. This only needs to be specified if the service has multiple ports defined in the wsdl. |
Elements | Multiplicity | Description |
---|---|---|
part | 0.. | a part in the ws-request |
response-part | 0.. | a part in the response from which information needs to be extracted |
part
Attributes | Required? | Type | Description |
---|---|---|---|
name | Yes | identifier | the id of the part |
variable | this or expression | expression | the variable to use |
expression | this or variable | variable name | the object to be extracted as the return value of this expression. |
Elements | Multiplicity | Description |
---|---|---|
conversion | 0.. | a list of conversions |
jbossesb-invoke
Based on JBoss ESB API's
Attributes | Required? | Type | Description |
---|---|---|---|
message-id | No | uri | uniquely identifies the message; if a reply is expected, this attribute must be present |
action | No | uri | identifies the semantics of the message |
Elements | Multiplicity | Description |
---|---|---|
to | 1 | addresses the intended receiver of the request |
reply-to | 0..1 | identifies the intended receiver for replies |
fault-to | 0..1 | identifies the intended receiver for faults |
part | 0.. | data item to be added to the body of the request |
response | 0..1 | specifies how to parse the response message; if not present, service is invoked asynchronously |
Notes
message-id should probably be generated based on the name of the process and/or either a database identifier or java.util.UUID
to, reply-to and fault-to are either {service-category, service-name} pairs or EPRs
response
Attributes | Required? | Type | Description |
---|---|---|---|
timeout | Yes | long | how long the client will wait for a response |
Elements | Multiplicity | Description |
---|---|---|
part | 0.. | data item to be retrieved from the body of the response |
mule-invoke
Based on Mule API's
jms-send
Sends a message using JMS API's
jms-receive
Receive a message from a queue using JMS API's.
TODO: Maybe building a configurable MDB is better for this.
invoke
can be used as node
can be used as action
Is one of following forms of service invocation:
direct web service invocation
jboss esb service invocation
java service defined in the jbpm global configuration. this decouples the process definition from the actual service being invoked.
rules
fire all rules or a subset of the rules of a rulebase
insert facts
extract facts
sql
Execute a SQL database insert, update or delete
hibernate
A hibernate select and store one or more elements as process variables might make sense.
But probably an update would not make sense as you can have hibernate variables that are references to hibernate entities. Updates are automatic in that scenario.
Not sure if this is a valid node/action type
Send an email.
TODO: Check out our current email support, which is pretty good. And compare it with Seam's email support. I believe that Seam based it's email templates on facelets and it generates html emails. Always make sure that the chosen mechanism can send notification and reminder emails for tasks.
Variable assignment (= variable assignment and transformation)
XSLT transformation
smooks transformation
FTP (get and put)
HTTP (get and post)
File (read and write)
Print (see javax.print)
PDF (generate a pdf with iText)
Excell spreadsheet generation
{FOOTNOTE RED #1 1} ! :functionalElementProperties
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
async | No | false | {true, false} | If false, then execution will be done in the thread of the client. If true, execution will be done in a separate thread, with an asynchronous, transactional message inbetween. |
synchronizer | No |
synchronizer
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
type | No (either type or class is required) | join-flat | {join-flat, join-hierarchical} | |
class | No (either type or class is required) | java class name | classname to implement the synchronizer behaviour |
propagator
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
type | No (either type or class is required) | flat | {default, fork, decision} | default takes the default transition. fork takes all transitions for which there is no condition or for which the condition resolves to true. decision takes the first transition for which the condition resolves to true. |
class | No (either type or class is required) | java class name | classname to implement the synchronizer behaviour |
General Structural Elements
process
Attributes | Required? | Type | Description |
---|---|---|---|
name | Yes | identifier | the id |
version | No | integer | the version of this process. See above 'Version attribute in the process definition'. |
initial | Yes | id-ref | the name of the initial node |
label | No | text | the short name |
Elements | Multiplicity | Description |
---|---|---|
description | 0..1 | the long description |
nodes | 0.. | nodes contained in this process |
variable | 0.. | variable declarations |
static-variable | 0.. | static variable declarations. one variable instance per process. value can be updated. |
annotations | 0.. | free java objects that can be wired together and associated to this process as static read-only annotations |
rule-base | 0.. | reference to a resource, for which a working memory should be created and maintained throughout the whole process instance. name of the rulebase should be resolvable in expressions |
event | 0.. | process events |
exception-handler | 0.. | Exception handlers |
swimlane | 0.. | Swimlanes |
task | 0.. | Task declarations |
service declarations | ||
named actions | 0.. | |
graphics | 0..1 | width and height of the diagram. maybe the transition layout style. |
state
A wait state waits creates a Trigger object (and corresponding record in the DB if used with persistence)
for each outgoing transition. Trigger name is the transition name.
Has all common attributes and elements.
(obsolete discussion:
==Bernd== I don't see the advantage of the merger. Why not keep the states as in jPDL 3?
==Tom== OK. I realize the answer to that question is : Because we can. Which doesn't make a lot of sense. So let's keep them separate.
)
super-state
Has all common attributes and elements.
By default, the first one is the initial node of the super-state.
(should we add support for history states in super states?)
Elements | Multiplicity | Description |
---|---|---|
common node elements | common node elements | |
nodes | 0.. | child nodes contained in this state |
process-state
Make sure that the following is supported:
configurable way to bind different end states in the subprocess to outgoing transitions of the sub process state
configurable way to bind different variable values in the subprocess to outgoing transitions of the sub process state
Elements | Multiplicity | Description |
---|---|---|
common node elements | common node elements | |
sub-process | 0.. | references which sub process should be executed. exclusive with child nodes |
variable | 0.. | local variable declarations |
Idea contributed by Paul Lorenz:
+Hello Tom,
I thought you might be interested in my master's project, for which I built a workflow engine. The bulk of the engine is probably not very interesting to you, but I've implemented a few (potentially) novel ideas. One which may interest you is the idea of composing graphs at load time, instead of (or in addition to) at runtime via nested processes. In this way multiple graphs, when loaded, are composed into a single, flat graph. This allows certain restrictions to be lifted (although has other drawbacks). If you are interested, the model documentation can be found at http://code.google.com/p/sarasvati/wiki/EngineConcepts (the composition section is near the end). The project is released under LGPL.
I always wanted to say thank you for your work on JBPM and your paper on PVM, which were helpful when I was designing my model, which takes ideas from petri-nets and PVM/JBPM.
cheers,
Paul Lorenz
+
transition
Attributes | Required? | Default | Type | Description |
---|---|---|---|---|
id | Yes | identifier | the id | |
label | No | text | the short name | |
condition | No | expression | condition expression | |
async | No | false | text | asynchronous taking of this transition |
Elements | Multiplicity | Description |
---|---|---|
description | 0..1 | the long description |
condition | 0..1 | condition on this transition specified, by a java class, a groovy script, a beanshell script, an mvel script or another scripting language |
java | 0.. | java actions |
graphics | 0..1 | anchors and bendpoints |
TODO: since transitions can now be wait states, I think that it should be possible to associate a task to a transition. That way, transitions would support plain wait states (task is absent) and human task based wait states. Cool, huh ?
Common node contents
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
id | Yes | identifier | the id | |
label | No | text | the short name | |
async | No | false | text | is execution of this node asynchronous |
signal-async | No | false | text | is signal of this node asynchronous |
Elements | Multiplicity | Description |
---|---|---|
description | 0..1 | the long description |
event | 0.. | events |
timer | 0.. | timer |
exception-handler | 0.. | exception handlers |
graphics | 0..1 | attributes x, y, w, h represent the coordinates of the node and the width and height. width and height might be left empty in case the default spanning should be taken. |
Transitions or nested node elements are specified in each individual node type.
Control flow : Propagators
These are the node types that only implement syncrhonization behaviour
decision
Decision can have outgoing transitions or nested nodes. Outgoing transitions and nested nodes are exclusive.
method expression that returns the transition name
conditions on the transitions
decision handler
fork
Fork can have outgoing transitions or nested nodes. Outgoing transitions and nested nodes are exclusive.
method expression that returns the list of transitions to take or nodes to execute
conditions on the transitions
fork handler returning the list of transitions to take or nodes to execute
iterator for each transition
Forks are flat or nestable. Flat is the default and means that only one set of concurrent executions can be active at a given time. The advantage is that unstructured forks and joins are supported. Nestable means that multiple forks can be executed in concurrency, in which case, the runtime engine must keep track of the 2 or more sets of concurrent executions. Nestable forks do not support unstructured joining and require that every fork must have a matching join. Nested forks should never have outgoing transitions and always be based on child nodes.
Flat fork refers to the way that the runtime execution tree is treated as a flat collection.
==Bernd== It should be configurable in the join under which condition it propagates (all incoming, 2 of 10, one, ...)
Control flow : Synchronizers
join
Joins a flat fork.
end-state
All common attributes and elements except timers.
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
ends | No | process-instance | {process-instance, execution} | specifies if the whole process instance has to be ended or only this execution |
Control flow : Others
while
iterator
condition
Synchronizers and Propagators
These are elements that can be optionally added to functional nodes.
Propagators can specify how execution should be propagated after a functional node is executed. Options for propagators are:
take the default outgoing transition (default propagator behaviour)
take the first transition for which the condition resolves to true
take all the transitions for which the condition resolves to true
propagate to the parent node
Synchronizers can act as a join before a functional node is executed. Join behaviour can that way be included in the functional node itself.
I don't know yet what the proper configuration for a synchronizer should look like.
test-process
A test process refers to another process and applies some modifications to it so that it can be ran in a test environment. E.g. Functional element behaviour can be skipped, stubbed out or configurations can be changed.
For test purposes, the changes can be applied statically, resulting in a new and updated process definition. Whereas for other use cases, dynamic modifications need to be applied to a process definition (think runtime actions). In the case of dynamic modifications, the modifications need to be maintained separate from the original process and they need to be applied at runtime, rather then at deployment time.
Attribute | Required? | Default | Type | Description |
---|---|---|---|---|
resource | Yes | resource | refers process to be tested as a resource |
Elements | Multiplicity | Description |
---|---|---|
skip | 0.. | Functional elements to be skipped |
replace | 0.. | Elements to be replaced |
Comments