XFLOW USER
GUIDE
This user guide is organized into the following sections:
An XFlow model is represented as a directed graph with a set of constraints. A directed graph consists of nodes and transitions between nodes. An XFlow graph has the following types of nodes:
A Start node is simply an indicator to denote where a
workflow starts. Similarly an End node indicates where a workflow ends.
Start and End nodes do not do any processing – they are simply markers used by
the workflow engine.
A Process node indicates the name of an application or an application component
that will perform processing on a work-item.
An And node is used to synchronize two or more parallel flows that transition
into it. For example in the graph below, if P1 and P2 both transition to an And
node and the And node transitions to P3, then if P1 completes processing of a
work item, the engine will wait for P2 to also complete processing before
transitioning to P3.
An Or node is used in the case where a flow should continue when any one of its incoming nodes transitions into it. Thus in the example below if any one of P1, P2, P3 transitions into the Or node, the flow continues on to P4. In our example, if P2 transitions first to the Or node, then the transition to P4 occurs. If at a later point P1 or P3 completes its workitem, it will have no effect on the flow.
A Container node contains the name of another XFlow model – it is in fact a sub-workflow. Container nodes are useful as a means of hiding sub-workflows within the larger workflow. Container workflows may execute within the main thread or be spawned off as a separate workflow instance. A container node that has a transition out of it executes within the thread. A container node that has no transition out of it executes as a separate thread (i.e. a new workflow instance is created).
These are the following constraints on the XFlow directed graph:
You can attach a rule to any transition in an XFlow model . See section 2 on XFlow Rules.
XFlow models are represented in the system as XFLOW-XML. The schema is given in Appendix A.
Here are examples of valid and invalid XFlow models.
Example of a valid
XFlow model
A valid XFlow model
Examples of invalid
XFlow models
This one violates constraint #4:
This one violates constraints #1 and #5:
This one violates constraints #3 and #7:
Simple rules may be defined on a transition from a process
node to another in a workflow model.
During execution of the workflow, the XFlow server evaluates the rule on the
work item to determine if a transition is to be taken.
There are 3 possible ways in which a rule can be expressed:
Type 1 XFlow Rule
Expressions
A Type 1 XFlow rule expression has the following syntax. Spaces are significant in the rule expression.
[<method name> <operator> <literal>]
<operator> is one of the following: ==, !=, <, >, <=, >=
Examples:
[intValue > 10] This assumes that the payload is an Integer object
[getAge <=
21] This assumes
that the payload is an instance of a class that has a getAge() method
[isActive == false] This assumes that the payload is an
instance of a class that has an isActive() method
[isApproved != true] This assumes that the payload is an instance of a class that has an isApproved() method
[getName == Harry Martin] This assumes that the payload is an instance of a class that has a getName method
Here is an example of a workflow model with Type 1 rules:
<xflow name="Example1">
<nodes>
<node id="StartNode" type="Start"/>
<node id="P1" type="Process"/>
<node id="P2" type="Process"/>
<node id="P3" type="Process"/>
<node id="P4" type="Process"/>
<node id="EndNode" type="End"/>
</nodes>
<transitions>
<transition from="StartNode" to="P1"/>
<transition from="P1" to="P2">
<rule>[intValue < 10]</rule>
</transition>
<transition from="P2" to="P3>
<rule>[getAge == 25]</rule>
</transition>
<transition from="P3" to="P4">
<rule>[getName != John Doe]</rule>
</transition>
<transition from="P4" to="EndNode"/>
</transitions>
</xflow>
Type 2 XFlow Rule
Expressions
A Type 2 XFlow rule expression has the following syntax. Spaces are significant in the rule expression.
[property.<property name> <operator> <literal>]
<operator> is one of the following: ==, !=, <, >, <=, >=
Examples:
[property.quantity > 10] This assumes that the work item property is called “quantity” and is an Integer object
[property.age
<= 21]
This assumes that the work item property is called “age” and is an
Integer object
[property.active == false] This assumes that the
work item property is called “active” and is a Boolean object
[property.approved != true] This assumes that the work item property is called “approved” and is a Boolean object
[property.name == Harry Martin] This assumes that the work item property is called “name” and is a String object
Here is an example of a workflow model with Type 2 rules:
<xflow name="Example1">
<nodes>
<node id="StartNode" type="Start"/>
<node id="P1" type="Process"/>
<node id="P2" type="Process"/>
<node id="P3" type="Process"/>
<node id="P4" type="Process"/>
<node id="EndNode" type="End"/>
</nodes>
<transitions>
<transition from="StartNode" to="P1"/>
<transition from="P1" to="P2">
<rule>[property.quantity < 10]</rule>
</transition>
<transition from="P2" to="P3>
<rule>[property.age == 25]</rule>
</transition>
<transition from="P3" to="P4">
<rule>[property.name != John Doe]</rule>
</transition>
<transition from="P4" to="EndNode"/>
</transitions>
</xflow>
Type 3 XPATH
expressions
XPATH expressions are valid only for work items with a payload type of XML. Using XML payloads and XPATH rules is one of the best ways of exploiting the power of XFlow. The syntax of XPATH may be found at: http://www.w3.org/TR/2003/WD-xpath20-20030502/ and a good tutorial at: http://www.zvon.org/xxl/XPathTutorial/General/examples.html
For example, if our work item has an XML payload such as the following:
<book>
<title>XFlow User Guide</title>
<detail>
<price>10.00</price>
<pages>120</pages>
<author>John Doe</author>
<inventory copies="50"/>
</detail>
</book>
Here is an example of a workflow model with Type 3 rules that could operate on the XML payload above:
<xflow name="XMLExample">
<nodes>
<node id="StartNode" type="Start"/>
<node id="P1" type="Process"/>
<node id="P2" type="Process"/>
<node id="P3" type="Process"/>
<node id="P4" type="Process"/>
<node id="P5" type="Process"/>
<node id="EndNode" type="End"/>
</nodes>
<transitions>
<transition from="StartNode" to="P1"/>
<transition from="P1" to="P2"/>
<transition from="P2" to="P3">
<rule>//book/detail/inventory[@copies > 50]</rule>
</transition>
<transition from="P2" to="P4">
<rule>//book/detail/inventory[@copies <= 50]</rule>
</transition>
<transition from="P3" to="P5">
<rule>//book[title = 'XFlow User Guide' && detail/price = 10.00]</rule>
</transition>
<transition from="P4" to="P5"/>
<transition from="P5" to="EndNode"/>
</transitions>
</xflow>
Here are some examples of more XPATH expressions (using our example payload):
Does book contain a
title called “XFlow User Guide”?
Result: true
//book[title = 'XFlow User Guide']
Does book contain the
title "XFlow User Guide" and price is = 10.00 Result: true
//book[title = 'XFlow User Guide' && detail/price = 10.00]
Does book contain the
title "XFlow User Guide" and price is = 10.00 and inventory copies
> 50? Result: false
//book[title = 'XFlow User Guide' and detail/pages < 1000 and detail/inventory[@copies > 50]]
You can run the following XFlow tools on a command line.
These tools are meant for administrative and/or debugging purposes.
The syntax for each tool is given below:
DeployModel
Usage: java xflow.tools.DeployModel <xflow-xml file name>
Example: java xflow.tools.DeployModel MyWorkflowModel.xflow
Description: Deploys
a workflow model as defined in the given XFLOW-XML file. If a model of the same
name has already
been deployed, this
model will be deployed with a version number incremented by 1.
AbortWorkflow
Usage: java xflow.tools.AbortWorkflow <workflow instance ID>
Example: java xflow.tools.AbortWorkflow 35
Description: Aborts an active workflow instance with the given ID.
GetNextWorkItem
Usage: java xflow.tools.GetNextWorkItem <workflow model name> <process name>
Example: java xflow.tools.GetNextWorkItem MyWorkflowModel CheckCredit
Description: This
tool mimics a workflow process and
allows you to peek into the next work items bound for that process.
Useful for debugging.
GetWorkflowState
Usage: java xflow.tools.GetWorkflowState <workflow instance ID>
Example java xflow.tools.GetWorkflowState 123
Description: Retrives the state of an active workflow instance. Useful for debugging.
GetVar
Usage: java xflow.tools.GetVar <workflow instance ID> <variable name>
Example: java xflow.tools.GetVar 123 CreditScore
Description: Allows you to peek into the variables within a workflow instance. Useful for debugging.
SetVar
Usage: java xflow.tools.SetVar <workflow instance ID> <variable name> <variable value>
Example: java xflow.tools.SetVar 123 CreditScore 784
Description: Allows you to set a variable in a workflow instance. Useful for debugging or affecting the workflow’s execution state.
GetProcessNodes
Usage: java xflow.tools.GetProcessNodes <workflow instance ID>
Example: java xflow.tools.GetProcessNodes 123
Description: Returns a list of all the process nodes in a given workflow instance.
GetActiveWorkflowInstances
Usage: java xflow.tools.GetActiveWorkflowInstances
Description: Returns a list of states of all currently active workflow instances.
GetAllWorkflowInstances
Usage: java xflow.tools.GetAllWorkflowInstances [workflow name]
Description: Returns a list of states of all workflow instances. If workflow name is given, the list will only contain the workflow instances with that name.
An XFlow participant process may communicate with the XFlow server using web services. This is the only method if the participant process is a non-Java application or if the participant process is running outside of the organization hosting the XFlow server. Using XFlow Web Services, a participant process can do the following:
1. Deploy workflows
2. Start and abort workflows
3. Get Workflow states
4. Get and complete work items
5. Get and set workflow variables
There are some restrictions to the types of objects that can serve as work item payloads, work-item properties and variable values. These must be of type XML, String, or a primitive Java type such as Integer, Double, Boolean, etc.
The WSDL for XFlow is given in Appendix B.
Calling an XFlow web
service from a Java client
A Java client may invoke an XFlow web service using a framework such as JAXM or Axis.
Here is an example of a client invoking the “start workflow” operation using Axis:
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import
org.apache.axis.encoding.ser.BeanSerializerFactory;
import
org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.utils.Options;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import xflow.common.*;
import xflow.security.*;
public class StartWorkflowWS {
public
static void main(String [] args) throws Exception {
String
endpoint = "http://localhost:8080/axis/services/XflowService";
String method
= "startWorkflow";
Service
service = new Service();
Call
call = (Call) service.createCall();
QName
qn = new QName( "urn:XflowService", "WorkItemId" );
call.registerTypeMapping(WorkItemId.class, qn,
new
BeanSerializerFactory(WorkItemId.class, qn),
new
BeanDeserializerFactory(WorkItemId.class, qn));
qn =
new QName( "urn:XflowService", "WorkflowId" );
call.registerTypeMapping(WorkItemId.class, qn,
new
BeanSerializerFactory(WorkflowId.class, qn),
new
BeanDeserializerFactory(WorkflowId.class, qn));
QName
qn1 = new QName( "urn:XflowService", "WorkItem" );
call.registerTypeMapping(WorkItem.class, qn1,
new
BeanSerializerFactory(WorkItem.class, qn1),
new
BeanDeserializerFactory(WorkItem.class, qn1));
QName qn2
= new QName( "urn:XflowService", "User" );
call.registerTypeMapping(User.class, qn2,
new
BeanSerializerFactory(User.class, qn2),
new
BeanDeserializerFactory(User.class, qn2));
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName( method );
call.addParameter( "op1", XMLType.XSD_STRING, ParameterMode.IN
);
call.addParameter( "op2", XMLType.XSD_INT, ParameterMode.IN );
call.addParameter( "op3", qn1, ParameterMode.IN );
call.addParameter( "op4", qn2, ParameterMode.IN );
String
workflowName = “SimpleWorkflow”;
Integer
version = new Integer(-1);
WorkItem witem = new WorkItem ();
witem.setPayload (new Integer(1));
witem.setPayloadType (WorkItem.JAVA_OBJECT);
User
user = new User ("foo", "foo");
call.invoke( new Object [] { workflowName, version, witem, user });
System.out.println("Workflow started.");
}
}
An alternative method of using the XFlow web service operations is to generate a JAVA API from the XFlow WSDL and invoking the methods of the generated API.
Refer to XFlow webservice example in the examples/webservice folder in the XFlow distribution.
The server publishes events when the following occur:
By subscribing to these events and saving them, you can
collect useful data about the workflows and workflow instances in the system.
The data could serve as a log or an audit trail or as a source for generating
reports and statistics of workflow activity.
The server publishes each event as an XML payload wrapped in a SOAP envelope. Examples of the messages for each event are given in Appendix C.
The following code shows you how to subscribe to XFlow events:
import java.io.*;
import java.util.*;
import javax.jms.*;
import xflow.common.XflowException;
import xflow.messaging.JMSSubscriber;
import xflow.messaging.JMSTopicConnection;
public class EventsHandler implements
MessageListener {
private
JMSSubscriber subscriber;
/*
* Constructor
*/
public
EventsHandler() {
try
{
// Initialize the JMS connection
JMSTopicConnection.initialize();
// Subscribe to the topic XFLOW.EVENT
subscriber
= new JMSSubscriber(this, "XFLOW.EVENT", null);
}
catch (XflowException e) {
e.printStackTrace();
System.out.println("Can't
set up JMS Subscription");
}
catch (JMSException e){
e.printStackTrace();
}
}
/*
* Callback method when an event message arrives
*/
public
void onMessage(Message evt) {
String
evtXML = null;
System.out.println("Got
a message...");
try
{
if
(evt instanceof TextMessage) {
evtXML
= ((TextMessage) evt).getText();
System.out.println
(evtXML);
// Process the
event here
}
else {
System.out.println("Message
not recognized.");
return;
}
}
catch (JMSException e) {
e.printStackTrace();
}
}
/*
*
*/
public
static void main (String[] args) throws Exception {
new EventsHandler();
}
}
Note that to run the above program, your class path must include the directory where jndi.properties is located. This file contains the URL for the JNDI server that will return the TopicConnectionFactory for establishing JMS connections with the server. This file is located in the <xflow>\conf directory. When you execute tools\setclasspath, this directory will be included in your class path.
XFlow EventsHandler
The XFlow Events Handler is an out-of-the-box events subscriber that saves the events it receives in a database.
The database schema is given in Appendix D. It is a standalone application. To run it, you must first start the XFlow server (JBoss), then do the following:
Start a console
cd <xflow>
tools\setclasspath
java xflow.events.EventsHandler conf\db.properties
db.properties contains the database configuration where the events tables will be stored. The default database is Hypersonic SQL.
All requests made to the XFlow server are password authenticated. The default out-of-the-box authenticator is the class xflow.security.XflowUserAuthenticator. This class implements the xflow.security.Authenticator interface which contains a single method, “authenticate”. This is stubbed out to always return true.
public
interface Authenticator {
public boolean authenticate (String
userName, String password);
}
The XFlow architecture allows you to plug in your own
Authenticator. To do this you must write a class that implements Authenticator.
Then do the following:
Appendix A
XFLOW-XML Schema
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="node" type="xs:string">
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Start"/>
<xs:enumeration value="End"/>
<xs:enumeration value="Process"/>
<xs:enumeration value="Container"/>
<xs:enumeration value="And"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="containee" type="xs:string" use="optional"/>
</xs:element>
<xs:element name="rule" type="xs:string"/>
<xs:element name="transition">
<xs:attribute name="from" type="xs:string" use="required"/>
<xs:attribute name="to" type="xs:string" use="required"/>
<xs:complexType>
<xs:element ref="rule" minOccurs="0"/>
</xs:complexType>
</xs:element>
<xs:element name="nodes">
<xs:complexType>
<xs:sequence>
<xs:element ref="node" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="transitions">
<xs:complexType>
<xs:sequence>
<xs:element ref="transition" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="xflow">
<xs:complexType>
<xs:sequence>
<xs:element ref="nodes" />
<xs:element ref="transitions" />
</xs:sequence>
</xs:complexType>
<xs:attribute id="name" type="xs:string" use="required"/>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8" ?>
<wsdl:definitions targetNamespace="http://localhost:8080/axis/services/XflowService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/axis/services/XflowService" xmlns:intf="http://localhost:8080/axis/services/XflowService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="urn:XflowService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<schema targetNamespace="urn:XflowService" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<complexType name="WorkflowId">
<sequence>
<element name="id" type="xsd:int" />
<element name="intValue" nillable="true" type="xsd:int" />
<element name="value" type="xsd:int" />
</sequence>
</complexType>
<complexType name="User">
<sequence>
<element name="name" nillable="true" type="xsd:string" />
<element name="password" nillable="true" type="xsd:string" />
</sequence>
</complexType>
<complexType name="WorkItemId">
<sequence>
<element name="id" type="xsd:int" />
<element name="value" type="xsd:int" />
</sequence>
</complexType>
<complexType name="WorkItem">
<sequence>
<element name="id" nillable="true" type="tns1:WorkItemId" />
<element name="payload" nillable="true" type="xsd:anyType" />
<element name="payloadType" nillable="true" type="xsd:string" />
<element name="properties" nillable="true" type="apachesoap:Map" />
<element name="workflowId" nillable="true" type="tns1:WorkflowId" />
</sequence>
</complexType>
</schema>
<schema targetNamespace="http://xml.apache.org/xml-soap" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<complexType name="Map">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item">
<complexType>
<all>
<element name="key" type="xsd:anyType" />
<element name="value" type="xsd:anyType" />
</all>
</complexType>
</element>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="getVariableResponse">
<wsdl:part name="getVariableReturn" type="xsd:anyType" />
</wsdl:message>
<wsdl:message name="startWorkflowResponse" />
<wsdl:message name="setVariableRequest">
<wsdl:part name="in0" type="xsd:int" />
<wsdl:part name="in1" type="xsd:string" />
<wsdl:part name="in2" type="xsd:anyType" />
<wsdl:part name="in3" type="tns1:User" />
</wsdl:message>
<wsdl:message name="abortWorkflowResponse" />
<wsdl:message name="abortWorkflowRequest">
<wsdl:part name="in0" type="xsd:int" />
</wsdl:message>
<wsdl:message name="setVariableResponse" />
<wsdl:message name="startWorkflowRequest">
<wsdl:part name="in0" type="xsd:string" />
<wsdl:part name="in1" type="xsd:int" />
<wsdl:part name="in2" type="tns1:WorkItem" />
<wsdl:part name="in3" type="tns1:User" />
</wsdl:message>
<wsdl:message name="getVariableRequest">
<wsdl:part name="in0" type="xsd:int" />
<wsdl:part name="in1" type="xsd:string" />
<wsdl:part name="in2" type="tns1:User" />
</wsdl:message>
<wsdl:portType name="XflowService">
<wsdl:operation name="getVariable" parameterOrder="in0 in1 in2">
<wsdl:input message="intf:getVariableRequest" name="getVariableRequest" />
<wsdl:output message="intf:getVariableResponse" name="getVariableResponse" />
</wsdl:operation>
<wsdl:operation name="setVariable" parameterOrder="in0 in1 in2 in3">
<wsdl:input message="intf:setVariableRequest" name="setVariableRequest" />
<wsdl:output message="intf:setVariableResponse" name="setVariableResponse" />
</wsdl:operation>
<wsdl:operation name="startWorkflow" parameterOrder="in0 in1 in2 in3">
<wsdl:input message="intf:startWorkflowRequest" name="startWorkflowRequest" />
<wsdl:output message="intf:startWorkflowResponse" name="startWorkflowResponse" />
</wsdl:operation>
<wsdl:operation name="abortWorkflow" parameterOrder="in0">
<wsdl:input message="intf:abortWorkflowRequest" name="abortWorkflowRequest" />
<wsdl:output message="intf:abortWorkflowResponse" name="abortWorkflowResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="XflowServiceSoapBinding" type="intf:XflowService">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getVariable">
<wsdlsoap:operation soapAction="" />
<wsdl:input name="getVariableRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:input>
<wsdl:output name="getVariableResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="setVariable">
<wsdlsoap:operation soapAction="" />
<wsdl:input name="setVariableRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:input>
<wsdl:output name="setVariableResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="startWorkflow">
<wsdlsoap:operation soapAction="" />
<wsdl:input name="startWorkflowRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:input>
<wsdl:output name="startWorkflowResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="abortWorkflow">
<wsdlsoap:operation soapAction="" />
<wsdl:input name="abortWorkflowRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:input>
<wsdl:output name="abortWorkflowResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/XflowService" use="encoded" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="XflowServiceService">
<wsdl:port binding="intf:XflowServiceSoapBinding" name="XflowService">
<wsdlsoap:address location="http://localhost:8080/axis/services/XflowService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Appendix C Examples of XFLOW Event Messages
ModelDeployed Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ModelDeployedEvent xmlns="http://xflow.net/events">
<User>rtan</User>
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
</ModelDeployedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WorkflowStarted Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<WorkflowStartedEvent xmlns="http://xflow.net/events">
<User>rtan</User>
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
<ParentWorkflowInstanceId/>
<WorkItem>
<WorkItemId>9999</WorkItemId>
<Payload type="XML">
<book>
<title>Great Expectations</title>
<author>Charles Dickens</author>
<isbn>1828282882</isbn>
<price>12.99</price>
</book>
</Payload>
</WorkItem>
</WorkflowStartedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WorkflowSuspended
Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<WorkflowSuspendedEvent xmlns="http://xflow.net/events">
<User>rtan</User>
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
</WorkflowSuspendedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WorkflowResumed Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<WorkflowResumedEvent xmlns="http://xflow.net/events">
<User>rtan</User>
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
</WorkflowResumedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WorkflowAborted Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<WorkflowAbortedEvent xmlns="http://xflow.net/events">
<User>rtan</User>
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
</WorkflowStartedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WorkflowCompleted
Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<WorkflowCompletedEvent xmlns="http://xflow.net/events">
<User>rtan</User>
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
</WorkflowCompletedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
NodeTransition Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<NodeTransitionEvent xmlns="http://xflow.net/events">
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
<From nodeId="222" nodeName="CheckCredit" nodeType="Process"/>
<To nodeId="223" nodeName="ApproveCredit" nodeType="Process"/>
<WorkItem>
<WorkItemId>9999</WorkItemId>
<Payload type="XML">
<credit>
<ssn>83838838383</ssn>
<name>John Doe </name>
<score>800</score>
</credit>
</Payload>
</WorkItem>
</NodeTransitionEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
VariableUpdated Event
<SOAP-ENV:Envelope xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<VariableUpdatedEvent xmlns="http://xflow.net/events">
<WorkflowName>CreditApproval</WorkflowName>
<WorkflowVersion>1</WorkflowVersion>
<WorkflowInstanceId>1233</WorkflowInstanceId>
<Variable name="score" type="integer">800</Variable>
</VariableUpdatedEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Appendix D XFLOW Events Database Schema
create table Event (
EventId int identity,
EventType varchar(32) not null,
Timestamp date not null,
WorkflowName varchar(64) not null,
WorkflowVersion int not null,
WorkflowInstanceId int,
ParentWorkflowInstanceId int, -- only used if this is sub-workflow
User varchar (64)
)
create table EventWorkItem (
EventId int not null, -- foreign key to Event table
WorkItemInternalId identity,
WorkItemId int not null,
PayloadType varchar(16),
Payload varchar(5000)
)
create table EventWorkItemProperties (
WorkItemInternalId int not null, -- foreign key to EventWorkItem table
PropertyName varchar(64) not null,
PropertyType varchar(16) not null,
PropertyValue varchar(5000) not null
)
create table NodeTransitionEvent (
EventId int not null, -- foreign key to Event table
FromNodeName varchar(64) not null,
FromNodeType varchar(16) not null,
ToNodeName varchar(64) not null,
ToNodeType varchar(16) not null
)
create table VariableUpdateEvent
EventId int not null, -- foreign key to Event table
VariableName varchar(64) not null,
VariableType varchar(16) not null,
VariableValue varchar(5000) not null
)