Chapter 2. OSWorkflow Introduction and Basics

This chapter introduces OSWorkflow and teaches the basics of the workflow engine. We begin by describing a simple real-world example, and then by using steps, actions, and results we create an XML definition of the process. We have taken the example of the holiday workflow, which is used in every company.

After building the example, we will show you how to visually model workflow definitions. Finally, we will embed OSWorkflow into our application or use it as a standalone workflow engine. The outline will cover the following topics:

  • Downloading and installing OSWorkflow

  • Getting a taste from the distribution

  • OSWorkflow basics

  • Visual Process modeling

  • Ways to implement OSWorkflow

Downloading and Installing OSWorkflow

The current OSWorkflow version, 2.8, requires a Java VM version 1.3 or higher. You can download binaries and sources from the OSWorkflow page at http://www.opensymphony.com/osworkflow/. To use the software, you must unpack the files using any compression utility like 7-Zip.

In the binary version you already have everything you need to run, on the other hand, the source code distribution must be compiled using the Jakarta Ant utility.

Getting a Taste from the Distribution

The OSWorkflow distribution comes with a sample web application useful for testing workflow definitions. This test application is packed as a WAR file, called osworkflow-2.8.0-example.war. In order to deploy it, you will need to install a web container such as Jakarta Tomcat.

You can download Tomcat from http://tomcat.apache.org. After downloading, unpack the distribution to a directory, and copy the osworkflow-2.8.0-example.war file into the webapps directory inside the root directory of Tomcat.

After that, start Tomcat by executing the startup.bat file in the bin directory of the distribution (or startup.sh if you are in a UNIX system). When Tomcat starts, open your web browser and point it to the following address: http://localhost:8080/osworkflow-2.8.0-example.war (change the host and port to the one on which you configured Tomcat; the default is localhost listening on port 8080). We are going to navigate through the generic user interface supplied with OSWorkflow.

The WAR distribution is configured by default with a sample publishing workflow definition and the workflow's persistence is done in the system's memory, so you can try it out.

Navigating the Sample User Interface

OSWorkflow includes a sample workflow definition based in a document-publishing system. Be free to try it out; log into the web application and execute actions. The screenshots that follow will show you how to instantiate a new document publishing workflow, revise the history and traceability data, and search for workflows in the workflow database.

The welcome screen that appears immediately after you enter the application address into the browser is as follows:

Navigating the Sample User Interface

It shows a login screen with two hyperlinks—one for loading test users and the other for creating a new account.

Click the reference data hyperlink to load the test user's data. After loading the data, you can log in using "test" as username and password. Clicking the Login button will display the following screen:

Navigating the Sample User Interface

Once you are logged in, you will see the following three buttons:

  • Home: This sends you back to the previous screen.

  • New Workflow: This instantiates a new document-publishing workflow.

  • My Underway Workflows: This shows you a list of workflows with the status "Underway". The significance of this status will be explained later in this chapter.

You will also see a View Workflow text box and a View button. Every time you create a new workflow, it is assigned a new identifier. Typing this identifier in the View Workflow text box and clicking the View button will show the workflow's traceability data. As we haven't generated any new workflows so far, we will cover this functionality later.

Clicking on New Workflow creates a new workflow instance, and stores it in memory, so don't be afraid to try it. After that click the anchor (#), to view the following page:

Navigating the Sample User Interface

This window is the same as the one shown earlier with the only difference being the message New workflow entry #1 created and initialized! This message gives us the identifier number of the newly generated workflow. Clicking #1 will show the workflow instance details and history steps as shown in the following screenshot:

Navigating the Sample User Interface

This window contains some very useful information, so let's look at it in detail.

The Finish First Draft hyperlink is the action used to execute the current step of the workflow. Below this hyperlink is a bulleted list, which enumerates the permissions needed for executing the Finish First Draft action. Under the Permissions section, resides the most important part of the application—the workflow's history and traceability data. At the moment, it is only showing where this workflow instance stands in the process flow.

The table shown in the figure consists of the following columns:

  • Step: This column shows the history or the current step name.

  • Action: This column displays the action executed to make the transition to this step. In this example the Action is NONE, which indicates that this is the first step.

  • Status: This column gives the step status. In this example it is Underway. This status should not be confused with the process status. These concepts will be explained in detail later in the chapter.

  • Start Date: This column tells the reader when the step started. The Start Date for this step is shown in the figure.

  • Finish Date: This column tells the reader when the step ended. At the moment, we don't have a Finish Date because we haven't made the transition to another step as yet.

  • Previous: This column tells us that no preceding steps were transited on the way to this step, as this is the first step in the workflow.

The View Live Graph hyperlink shows a graphical representation of the workflow descriptor.

Below this hyperlink are the same Home, New Workflow, and My Underway Workflows links for navigating away from this page.

The graph generated by View Live Graph is as follows:

Navigating the Sample User Interface

The red highlighted box is the current step of the workflow instance while the blue ones show steps and the gray ones are the splits and joins. Clicking Finish First Draft executes this action on the workflow #1 and puts the workflow in another step. The application will display the following screenshot, which is almost the same as the previous one. Let's take a look at the changes.

Navigating the Sample User Interface

The first things you will notice are the Finish Foo and Finish Bar actions. These are two dummy actions in the document-publishing process. Below these actions is the Permissions section, which shows that the application doesn't need any permission for executing these actions. The history and traceability data table reflects a few changes—two more lines have been added to the table: Both are current steps in the workflow (because the Finish First Draft action caused the flow to split into two parallel branches). The Status of both is Underway and the Previous column shows 1, indicating that both steps come from the first step. The step that previously was current is now a history step. It now has a Finish Date and the Status is Finished.

Try clicking the next actions to complete the document-publishing process. Eventually, you will finish some processes and they will not come back again in the My Underway Workflows page.

You can explore the interface a little bit, though it is very limited. The main purpose for which you can use this web application is for testing the process with your users thus skipping the prototype step. So let's learn the OSWorkflow constructs to deploy our chapter's example, the employee holidays business process.

OSWorkflow Basics

OSWorkflow is a mature open-source Java workflow engine. It is mainly aimed at the programmer and not an end user or business analyst. For the end user or business analyst, it includes a user-friendly visual workflow modeler designed only for basic usage.

This section will cover the basic concepts needed to create simple but useful process definitions using OSWorkflow. In the next section, we will generate a simple workflow to request holidays and finally you will have a complete working process. The example includes creating a very simple definition and the instantiation of new processes based on that descriptor.

XML Definition Files

OSWorkflow defines the process definition in an XML file called workflow descriptor. The OSWorkflow descriptor XML must have a root element of workflow and obligatory child elements named steps and initial-actions. Here is a snippet of the sample file bundled with the distribution.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow
2.6//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd">
<workflow>
…
</workflow>

The workflow engine parses this file and builds the business process structure from the definition. You can construct any workflow definition by placing XML elements that represent workflow concepts such as steps and actions.

The XML file has a Document Type Definition (DTD) for validation purposes included with the OSWorkflow distribution. This allows any XML editor (such as Cooktop http://www.xmlcooktop.com/) to build syntactically correct definitions. The following figure depicts the OSWorkflow concept model.

XML Definition Files

In the next section, we will explore the different constructs OSWorkflow has to assemble in a definition.

An Example Workflow

We will use a business process that a medium to large company would encounter at least once a year—the holiday workflow. Every time you need days to rest or travel, you request your supervisor to sanction the holidays. The supervisor may allow or deny the holidays.

The following flowchart shows the business process structure:

An Example Workflow

This is the simplest business process to start exploring the OSWorkflow features.

Steps, Actions, and Results: The Workflow Building Blocks

OSWorkflow's description of a business process is based on the concept of a step. A process has well-defined steps or activities to fulfill the business goal. For instance, the holiday workflow may have at least two logical steps—the employee's request and the manager's authorization.

Remember that every business process starts with external stimuli; in OSWorkflow these stimuli are called initial-actions. The initial-actions allow the workflow to start in a step other than the first, giving a lot of flexibility to the definition. The initial‑actions element contains a group of action elements identified by numbers. You can explicitly start a workflow instance triggering a specific action. These actions can change the flow of control by going to different steps depending on a conditional element. We will discuss the Conditional constructs of OSWorkflow in the next chapter.

The following XML workflow definition snippet shows the typical beginning of a process definition:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//
DTD OSWorkflow 2.6//EN"
"http://www.opensymphony.com/
osworkflow/workflow_2_8.dtd">
<workflow>
<initial-actions>
<action id="100" name="Start Workflow">
<results>
<unconditional-result old-status="Finished" status="Underway"
step="1"/>
</results>
</action>
</initial-actions>
…

The definition starts with a DTD declaration that every valid XML document has and the root XML element, workflow. The DTD allows XML parsers and editors to validate every XML element and attribute thus generating a valid definition.

Every well-defined XML document starts and ends with only one root element. This initial‑action construct indicates that the workflow will start immediately in step 1. The step is the main workflow concept in OSWorkflow because the process steps mark its progress and completion level. The next fragment follows the initial-actions element:

…
<steps>
<step id="1" name="Employee request">
<actions>
<action id="1" name="Request holidays">
<results>
<unconditional-result old-status="Finished" step="2"
status="Requested"/>
</results>
</action>
</actions>
</step>
…

The steps XML element contains sibling step elements. In this snippet only one step element is present. In the definition snippet, we can see that step 1 is called Employee request.

Every step can have one or more actions, which can be viewed as events or external stimuli to the process that can occur in real life. In the manager authorization step, the manager can approve or deny the holidays. The definition says that step 1—the employee request phase—has only one action called Request holidays having ID 1. Actions must have a numerical ID that is unique within the definition.

Every action has at least one outcome, that is, a transition to the same or another step. The outcomes are called results, and the default outcome is the unconditional-result of an action. An action must have at least one default outcome; the other optional outcomes are called conditional results. The Request holidays action has an unconditional-result that brings the workflow to step 2.

…
<unconditional-result old-status="Finished" step="2"
status="Requested"/>
…

You must be curious about the old-status and status attributes of the unconditional‑result element. We'll cover both these attributes later in this chapter.

Conditional results have nested conditions elements, which are evaluated when going out of the step. The conditional results are executed only if the condition becomes true. Nested conditions can be combined with Boolean logic, such as AND and OR. If you have more than one conditional result in an action, the first one evaluated to true is followed.

Results can transition into a step, a join, or a split. The last two concepts will be covered later in the section.

Coming back to the example workflow, the manager can approve or deny (two independent actions) the request. The finish attribute set to TRUE signals OSWorkflow to finish the workflow after executing the action.

<step id="2" name="Manager revision">
<actions>
<action id="2" name="Approve" finish="TRUE">
<results>
<unconditional-result old-status="Revised" status="Approved" />
</results>
</action>
<action id="3" name="Deny" finish="TRUE">
<results>
<unconditional-result old-status="Revised" status="Denied" />
</results>
</action>
</actions>
</step>

You can imagine the step as a place, the action as an event, and the result as an exit path. So a workflow is composed of a series of steps. The conditional results are exits with doors that open if the associated predicate is true; the unconditional result is the path you'd take if all other exits are closed.

Optionally, if the manager approves or denies the request, we can send an email to the employee. A utility Java function included with the OSWorkflow distribution can take care of sending the email as you can see in the following fragment:

…
<action id="3" name="Deny" finish="TRUE">
<pre-functions>
<function type="class">
<arg name="class.name">com.opensymphony.workflow.util.SendEmail
</arg>
<arg name="to">[email protected]</arg>
<arg name="from">[email protected]</arg>
<arg name="subject">Holidays</arg>
<arg name="cc">[email protected]</arg>
<arg name="message">Your request has been denied</arg>
<arg name="smtpHost">10.250.0.168</arg>
</function>
</pre-functions>
<results>
…
</results>
</action>
…

Stitching the fragments together, the definition ended up like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//
DTD OSWorkflow 2.8//EN"
"http://www.opensymphony.com/
osworkflow/workflow_2_8.dtd">
<workflow>
<initial-actions>
<action id="100" name="Start Workflow">
<results>
<unconditional-result old-status=
"Finished" status="Underway" step="1" />
</results>
</action>
</initial-actions>
<steps>
<step id="1" name="Employee request">
<actions>
<action id="1" name="Request holidays">
<results>
<unconditional-result old-status=
"Finished" step="2" status="Requested" />
</results>
</action>
</actions>
</step>
<step id="2" name="Manager revision">
<actions>
<action id="2" name="Approve" finish="TRUE">
<results>
<unconditional-result old-status=
"Revised" status="Approved" />
</results>
</action>
<action id="3" name="Deny" finish="TRUE">
<results>
<unconditional-result old-status=
"Revised" status="Denied" />
</results>
</action>
</actions>
</step>
</steps>
</workflow>

This XML shows a workflow definition with two steps, the first with only one action, and the second with two actions, either one finishing the process. This example is very basic and linear; it proceeds in sequence. You can find the definition in the holiday.xml file. This file is included in the downloadable source code.

Testing the Workflow Definition

We can use the sample web application as a user-friendly way to test our definitions. We'll run our first definition this way. First, we must change to the webapps directory of the Tomcat distribution, unpack the osworkflow-2.8.0-example.war inside the webapps directory, and then delete the original WAR file. This way the example application will be deployed on what's called an expanded WAR, a directory resembling a WAR file. This allows us to tinker with the files without the hassle of repacking to a WAR file every time we change a file.

Then go inside the osworkflow-2.8.0-example.war folder, browse to the WEB‑INF/classes folder, and rename the example.xml file to example.xml.orig. Then place the holiday.xml file included with the book and rename it to example.xml. This will cheat the sample web application into using our definition instead of the original publishing workflow definition.

That's it, now start up Tomcat again and point your web browser to http://localhost:8080/osworkflow-2.8.0-example, login, and enjoy your first business process. You can test every definition we will create in the book this way, or you can use the text-based test interface inside the packtpub.osw.TestWorkflow class. You can find all the directions inside the class javadoc comments.

Splits and Joins

In real-world situations, you can find employees collaborating and working simultaneously in parallel, in which case the process splits into two or more branches, and these branches can eventually join into a main path.

OSWorkflow has the split and join constructs to represent this situation. The split construct branches the main flow of the workflow into two parallel paths and the join construct does the opposite, it unites the branches into the main flow again.

Let's modify the chapter's example a little bit by saying that two managers must approve or deny the request. The first manager is the line or functional manager and the other is the human resources manager. Both managers must give their approval for the employee to receive an email confirming the approved status of his or her request. The following figure depicts the new business process:

Splits and Joins

We will modify the XML definition to reflect this change by incorporating a splits and a joins XML element. The code snippet that follows shows the modification to the holiday example XML. The splits and the joins elements are children of the root workflow element.

<workflow>
…
<splits>
<split id="1">
<unconditional-result old-status="Finished" status="Underway" step="2" />
<unconditional-result old-status="Finished" status="Underway" step="3" />
</split>
</splits>
<joins>
<join id="1">
<conditions type="AND">
<condition type="beanshell">
<arg name="script">
<![
CDATA[
propertySet.setString("result", "denied");
if(jn.getStep(2).getStatus().endsWith("approved")
&&
jn.getStep(3).getStatus().endsWith("approved")){
propertySet.setString("result", "approved");
}
</arg>
</condition>
</conditions>
<unconditional-result old-status=
"JoinFinished" status="${result}" step="4" />
</join>
</joins>
…
</workflow>

The splits element nests child split elements, each one telling the engine to fork the current path of execution into two parallel branches. The split must have an id and two results (one can be conditional but at least one must be unconditional). Each result's step attribute indicates to OSWorkflow to make this step the new current step. In this case, we have only one split identified by the number 1 and it will fork the process flow into two branches; the first one will go to step 2 and the other to step 3.

To arrive to a split, the conditional or unconditional result of a step must have the split attribute with the corresponding split ID as shown in the following snippet:

<step id="1" name="Step 1">
<actions>
<action id="1" name="Action 1">
<results>
<unconditional-result old-status="Finished" status="Pending" split="1"/>
</results>
</action>
</actions>
</step>

This fragment tells OSWorkflow that the unconditional result of Step 1 is to go to split 1. Similarly to the splits element, the joins element can have any number of join child elements you want. Each join has at least one condition. To be able to use a join node, the process must have executed a split previously.

When the engine arrives at a join, it evaluates all the conditions. If they all return true, then the unconditional result is followed. A join has a join condition and a new jn variable. This new variable is available only on join conditions and has several convenient methods to check for workflow and step status. Let's analyze the joins section in more detail:

<joins>
<join id="1">
<conditions type="AND">
<condition type="beanshell">
<arg name="script">
<![
CDATA[
propertySet.setString("result", "denied");
if(jn.getStep(2).getStatus().endsWith("approved")
&&
jn.getStep(3).getStatus().endsWith("approved")){
propertySet.setString("result", "approved");
}
</arg>
</condition>
</conditions>
<unconditional-result old-status=
"JoinFinished" status="${result}" step="4" />
</join>
</joins>

Here we have only one join identified by the number 1. To effectively join two parallel branches of execution, the process will have to comply with a condition scripted in BeanShell code. We will cover BeanShell functions and conditions in Chapter 4; for now assume that the code will check for the status of step 2 and step 3 to be approved. If any of them is not approved, the process will stay in whatever step it currently is in. When the condition is satisfied, the flow of control will be directed to the fourth step (see the unconditional-result element).

One last important thing to note: A split or a join cannot result into a split or join again; this is a current limitation of OSWorkflow.

Setting Status and Old Status Values

A workflow always has a state associated with it; OSWorkflow represents it in the form of status. Every step has a status while the workflow is placed on it and when the workflow advances, OSWorkflow assigns the leaving step an old-status value. Consider the previous example:

<step id="2" name="Manager revision">
<actions>
<action id="2" name="A+pprove">
<results>
<unconditional-result old-status=
"Revised" status="Approved" step="3"/>
</results>
</action>

When the action with id 2 makes the process take the action's unconditional result, it leaves the step with the status Revised (thus an old status) and the new current step (step 3) takes the status value of Approved. The following figure shows this mechanism in a more generic fashion. It depicts a step transition from Step 1 to Step 2.

Setting Status and Old Status Values

The definition of Step 1 is as follows:

<step id="1" name="Step 1">
<actions>
<action id="1" name="Action 1">
<results>
<unconditional-result old-status=
"Finished" status="Pending" step="2"/>
</results>
</action>
</actions>
</step>

As Step 1 transitions to Step 2 it set its old-status value to Finished and Step 2 status to Pending.

The status and old-status values are nominal; you can define them to whatever value you want. The most common status names are "Pending" or "Queued". And the old‑status is typically "Finished".

A common question an end user has on workflows is—what is the current state of this process? As OSWorkflow supports parallel steps, the answer is—the status of every current step.

As the workflow advances, the engine calls the completed steps "history steps" and the current steps are called well, just "current steps". When a workflow is finished, it has steps only in history and none in the current stage.

Sending an Email Automatically

In the new example workflow definition, if both managers approve the request, then OSWorkflow sends a mail message notifying about this. If one of the managers denies the request, another mail message is sent. You can see in the following snippet the pre-functions and function elements:

…
<step id="4" name="Notify employee">
<actions>
<action id="6" name="Notify" finish="TRUE">
<pre-functions>
<function type="class">
<arg name="class.name">com.opensymphony.workflow.util.SendEmail</arg>
<arg name="to">[email protected]</arg>
<arg name="from">[email protected]</arg>
<arg name="subject">Holidays</arg>
<arg name="cc">[email protected]</arg>
<arg name="message">Your request has been ${result}
</arg>
<arg name="smtpHost">10.250.0.168</arg>
</function>
</pre-functions>
<results>
<unconditional-result old-status="Finished" status=
"Line approval" step="-1" />
</results>
</action>
</actions>
</step>
…

This snippet sends an email with a destination address, a "from" mail address, and a carbon copy. This is intended to be sent to the employee; as the subject of the email is "Holidays" the content of the email varies. If the holiday request was approved it will say "Your request has been approved", if it was rejected it will say so. The ${result} token and more about the OSWorkflow functions will be explained later in the chapter.

Let's go back to actions; they can have functions, which are the main extensibility mechanism of OSWorkflow. They are of the following two kinds: pre-functions and post-functions. Additionally, OSWorkflow functions can be action based or step based. Action pre-functions execute before the execution of the action and Action post-functions execute during the transition. Functions and OSWorkflow's built-in functions will be seen in more depth in Chapter 4.

<pre-functions>
<function type="class">
<arg name="class.name">
com.opensymphony.workflow.util.SendEmail </arg>
<arg name="to">[email protected]</arg>
<arg name="from">[email protected]</arg>
<arg name="subject">Holidays</arg>
<arg name="cc">[email protected]</arg>
<arg name="message">
Your request has been ${result}</arg>
<arg name="smtpHost">10.250.0.168</arg>
</function>
</pre-functions>

Pre-functions are executed before the step transitions to the next step.

Our modified holiday workflow definition ended up like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.6//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd">
<workflow>
<initial-actions>
<action id="100" name="Start Workflow">
<results>
<unconditional-result old-status=
"Finished" status="Underway" step="1" />
</results>
</action>
</initial-actions>
<steps>
<step id="1" name="Employee request">
<actions>
<action id="1" name="Request holidays">
<results>
<unconditional-result old-status=
"Finished" split="1" status="Requested" />
</results>
</action>
</actions>
</step>
<step id="2" name="Line Manager revision">
<actions>
<action id="2" name="Approve">
<results>
<unconditional-result old-status=
"Line aproved" status="joining" join="1" />
</results>
</action>
<action id="3" name="Deny">
<results>
<unconditional-result old-status=
"Line denied" status="joining" join="1" />
</results>
</action>
</actions>
</step>
<step id="3" name="HR Manager revision">
<actions>
<action id="4" name="HR Approve">
<results>
<unconditional-result old-status=
"HR aproved" status="joining" join="1" />
</results>
</action>
<action id="5" name="HR Deny">
<results>
<unconditional-result old-status=
"HR denied" status="joining" join="1" />
</results>
</action>
</actions>
</step>
<step id="4" name="Notify employee">
<actions>
<action id="6" name="Notify" finish="TRUE">
<pre-functions>
<function type="class">
<arg name="class.name">
com.opensymphony.workflow.util.SendEmail</arg>
<arg name="to">[email protected]</arg>
<arg name="from">[email protected]</arg>
<arg name="subject">Holidays</arg>
<arg name="cc">[email protected]</arg>
<arg name="message">
Your request has been ${result}</arg>
<arg name="smtpHost">10.250.0.168</arg>
</function>
</pre-functions>
<results>
<unconditional-result old-status=
"Finished" status="Line approval" step="-1" />
</results>
</action>
</actions>
</step>
</steps>
<splits>
<split id="1">
<unconditional-result old-status=
"Finished" status="Underway" step="2" />
<unconditional-result old-status=
"Finished" status="Underway" step="3" />
</split>
</splits>
<joins>
<join id="1">
<conditions type="AND">
<condition type="beanshell">
<arg name="script">
<![CDATA[
propertySet.setString("result", "denied");
if(jn.getStep(2).getStatus().endsWith("aproved") && jn.getStep(3).getStatus().endsWith("aproved")){
propertySet.setString("result", "aproved");
}
!("Underway".equals(jn.getStep(2).getStatus())) && !("Underway".equals(jn.getStep(3).getStatus())) ]]>
</arg>
</condition>
</conditions>
<unconditional-result old-status=
"JoinFinished" status="${result}" step="4" />
</join>
</joins>
</workflow>

This definition is a little more advanced than the first one. For starters it has a parallel path of execution, so two managers must approve the request independently. It also sends an email to the employee telling him or her the result of his or her request. This file is called holiday2.xml. In the next chapter, we will learn how to visually model workflow definitions using the built-in graphical tool of OSWorkflow.

Visual Process Modeling

Instead of writing the XML definition by hand, you can use the visual modeler. Although it's a little more restricted than the manual approach, it is very useful for non-technical people to specify a business process.

Visually Creating the Holiday Example

You can start the designer by typing java jar designer.jar on the command line of your system (given that the java command is on your path). First copy designer.jar into the lib/designer path of your unpacked OSWorkflow distribution. You have to do this because some library files cannot be found otherwise hopefully this will be fixed in the next version of OSWorkflow.

After the splash screen, a blank workspace screen will be displayed, like the one that follows:

Visually Creating the Holiday Example

This welcome screen prompts you to load an existing workspace or create a new one. We will create a new workspace to model the same holiday example, but this time visually. In the Select Workspace dialog, select the Create new workspace checkbox, and click on the button.

Visually Creating the Holiday Example

After clicking the button, a standard file chooser dialog will appear. You must navigate to a directory of your choice and type in a new filename for the workspace.

After creating a new workspace file, we continue by creating a new workflow. Go to the File | New | New workflow menu item and click on the item.

Visually Creating the Holiday Example

You will be prompted with a dialog box to type a name for the new workflow:

Visually Creating the Holiday Example

Type any name you want and, after clicking OK, a new workflow screen will appear as shown in the following figure. The three icons in the leftmost upper section of the screen are used to create a new step, split, or join. These are the building blocks of the definition.

Visually Creating the Holiday Example

We will create a new step by clicking on the new step icon and then clicking on the empty canvas. A dialog box appears as shown in the following figure. This dialog box prompts us to select the result type of the transition between the start node and the new step. In this case, we will select Unconditional.

Visually Creating the Holiday Example

After we click the Unconditional button, the visual modeler will create a graphical link between the start and the Employee Request step. Then we proceed to make another step, called Manager Revision, again with the result type as unconditional.

Visually Creating the Holiday Example

With this last step, we have finished the first and simplest holiday process definition. Go to File | Save Workflow to save the displayed contents in an XML file.

Looking at the End Result

Opening the definition in Notepad will display the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.8//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd">
<workflow>
<meta name="lastModified">Sun Dec 17 16:57:01 ART 2006</meta>
<meta name="created">Sun Dec 17 16:55:59 ART 2006</meta>
<meta name="generator">OSWOrkflow Designer</meta>
<initial-actions>
<action id="0" name="Start Workflow">
<results>
<unconditional-result id="2" old-status=
"Finished" status="Queued" step="1"/>
</results>
</action>
</initial-actions>
<steps>
<step id="1" name="Employee Request">
<actions>
<action id="4" name="Employee Request" view=
"Employee Request">
<results>
<unconditional-result id="5" old-status=
"Finished" status="Queued" step="3"/>
</results>
</action>
</actions>
</step>
<step id="3" name="Manager Authorization">
</step>
</steps>
</workflow>

Notice that the definition is not the same as the one made manually. This is because the visual modeler is suited for simpler business processes. The recommended approach for complex workflows is to build the definition manually.

Ways to Implement OSWorkflow

There are two ways of implementing OSWorkflow: the first is embedding OSWorkflow in your application and the second is using OSWorkflow as a standalone workflow server.

OSWorkflow as a Workflow Layer

If your needs are just workflow support in one application, then incorporating the OSWorkflow libraries and using the API is sufficient. An example application architecture diagram showing the Business Process Layer that is responsible for tracking the business process in the application is as follows:

OSWorkflow as a Workflow Layer

The addition of this layer to the standard three adds workflow capabilities to the domain model. This domain model contains the abstract entities of the business domain that travel with the business process. Remember, that each layer can talk only to the layers above and below, so the Business Domain Layer handles Business Process Layer objects. The section entitled Embedding OSWorkflow into your Applications in Chapter 4 will cover this architectural option.

OSWorkflow as a Centralized Workflow Server

If you need a corporate centralized workflow server, then you can execute OSWorkflow with SOAP bindings to have workflow functionality across applications. As long as you use SOAP as the transport protocol, you can integrate applications written in any programming language such as .NET, COBOL, and obviously Java.

The following figure depicts the role of the centralized workflow server:

OSWorkflow as a Centralized Workflow ServerOSWorkflow, implementingOSWorkflow as a workflow layer

In the standalone environment, you have the advantage of centralizing business process data for the corporation and reusing workflow logic in applications. Having this information allows you to mine and explore the information to uncover hidden process patterns and process relationships. To enable other applications to use workflow server, it must have a universal connector, a SOAP web service interface.

Adding the SOAP Bindings

OSWorkflow uses the Codehaus XFire (http://xfire.codehaus.org/) library to expose a set of interfaces through the web services SOAP protocol. To enable the OSWorkflow's SOAP server, you have to use a web container such as Jakarta Tomcat. Create a web application, and then modify the application's web.xml descriptor present inside the application's WEB-INF directory to include the following lines:

<servlet>
<servlet-name>SOAPWorkflow</servlet-name>
<servlet-class>com.opensymphony.workflow.soap.SOAPWorkflowServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SOAPWorkflow</servlet-name>
<url-pattern>/wsserver/*</url-pattern>
</servlet-mapping>

After modifying the web.xml file, put the XFire libraries (listed in the following table) inside the WEB-INF/lib directory of the web application.

Jar File

Description

jaxen-1.1-beta-5.jar

XPath expression parser

jdom-1.0.jar

DOM navigator library

stax-1.1.2-dev.jar

XML parser

wsdl4j-1.4.jar

WSDL library

xfire-aegis.jar

XFire support library

xfire-core.jar

XFire core library

Once the application is deployed, you can access the OSWorkflow's SOAP WSDL at http://<server>/ wsserver/Workflow?wsdl.

This WSDL is the web service descriptor and lists all the operations available in the web service. For the client applications you can use the XFire library or another SOAP client to access services of the OSWorkflow server. That's all you need to create a centralized workflow engine server for all your applications.

Summary

This chapter covered the most basics concepts to get you started with business process definitions using OSWorkflow as your workflow engine. The next chapter will cover advanced uses and will build upon the basic concepts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset