bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Learning to Use BPM

Defining Workflow Nodes

Note: The Worklist client application is being deprecated as of this release of WebLogic Integration. For information about the features that are replacing it, see the BEA WebLogic Integration Release Notes.

In this section, after a detailed overview of the workflow nodes, we provide procedures for defining every workflow object of the Order Processing workflow, node by node. By following the procedures in this section, you will learn how to:

- Create an event-triggered start node

- Create XPath expressions with the XPath Wizard

- Compose and send an XML document to a Worklist client and process the response with the Worklist DTDs

- Add comments to tasks and workflows

- Define events and event keys

- Create and define decisions

- Configure and perform business operations to call EJB methods

- Use a plug-in action

- Call a sub-workflow

- Send an e-mail message

You are ready to do the procedures provided in this section of the tutorial if you have done the following:

- Imported the Create OrderBean business operation, as described in Importing the Tutorial.jar Workflow Objects.

- Created, designed, and activated the Order Processing workflow template and template definition, as described in Creating a Workflow.

- Optionally, specified a valid e-mail address in the Post XML Event action in the Order Processing Trigger workflow, as described in Posting an Internal XML Event: Editing the Neworder XML Document.

Overview of the Order Processing Workflow Nodes

The following figure provides a detailed view of the workflow. The numbered steps in the figure are described in the table that follows the figure, which maps the real-world processes to the workflow implementation.

Figure 4-1 Order Processing Nodes: Detailed View

Table 4-1 Order Processing Workflow Summary

Process | Implementation
--- | ---
The order is received by a processing system, which reads the data and appends an ID number to the order. In a real-world implementation, an event-type start node would be set up to react to an XML message posted to an external JMS queue by a servlet. | 1. An event-triggered start node is set up to listen for the <neworder> XML message sent to the internal JMS queue by the Order Processing Trigger workflow. XPath statements extract data from the XML document to populate the workflow variables.
The order is forwarded to a customer service representative, who checks the customer's credit information. | 2. An XML message is sent to the admin user, prompting for a yes/no response to confirm whether the credit check passes. The response is sent back in an XML message, and read into a workflow variable by an XPath statement.
3. A decision evaluates whether the response is yes or no.
If the credit check fails, the customer service representative is assigned the task of contacting the customer to obtain correct credit information, and the process becomes manual from this point on. | 4. The task of contacting the customer is assigned to the CustomerService role, and the workflow proceeds to the Done node.
If the credit check passes, the system checks a database for the current inventory of the ordered item, according to the item ID, and it compares the quantity of items available with the quantity requested. | 5. The item ID is passed to a method in an EJB that checks a database and returns the current inventory for the item to a variable.
6. A decision evaluates whether the returned inventory value is greater than or equal to the quantity of items ordered. If it is not, the order status is set to waiting.
If the amount of stock is not sufficient to accommodate the order, the order is placed on hold until new inventory arrives. When the system receives notice of new incoming inventory, it repeats step 5 until it can verify that the inventory is sufficient to process the order. In a real-world implementation, an event would be set up to react to an XML message posted to an external JMS queue by an inventory-reporting application. | 7. An event and event key are set up to react to a hypothetical XML <checkinventory> message including the relevant item ID. When the event is triggered, the flow loops back to the inventory-checking task node.
If the inventory is sufficient, the order is forwarded to two human agents simultaneously: one agent arranges shipment; the other instructs the system to generate an invoice for the order. | 8. The Order Fulfillment workflow is called, variables are passed to it, the results of the operations performed within it are returned.
The system confirms that the order has been shipped and notifies the customer via e-mail. | 9. When the Order Fulfillment workflow terminates, and the Watch for Cancellation event is cancelled, the order status is set to complete, and an e-mail may be sent to the customer.
10. The workflow terminates.
At any point in the transaction before shipping, the order can be cancelled by notification from the customer. In a real-world implementation, an event would be set up to react to an XML message posted to an external JMS queue by a servlet. | 11. An event and event key are set up to react to a hypothetical <cancelledorder> XML message including the relevant order ID. If the event is triggered, the workflow proceeds to the done node and is terminated.

Creating an Event-Triggered Start

The Order Processing workflow is triggered by the XML event that is posted by the Order Processing Trigger workflow. When the workflow is started, its first operation is to initialize workflow variables to the values provided by the XML document posted by the Order Processing Trigger workflow.

Thus, to create our node, we need to do the following:

- Create variables to correspond to the data in the XML document

- Set up the event that triggers the workflow

- Define XPath expressions to extract the data from the XML document and assign it to variables

Creating Variables

Because our start node will extract values from an XML document, we need to set up corresponding variables in which we can store the values we have extracted. The following table lists the variables, their use in the workflow, and the XML elements to which they correspond. Remember that an input parameter is used when the value of a variable is to be passed to another workflow. An output parameter, on the other hand, is used when the value of a variable is to be passed to the current workflow from another workflow.

Table 4-2 Start Node Variables

Variable | Data Type | Parameter Type | Use in Workflow | Corresponding XML Element
--- | --- | --- | --- | ---
OrderStatus | String | Input | Can change at various points of the workflow | <status>
OrderID | Integer | Input | Appears as the workflow label in the Worklist and increments each time the workflow is run | <id>
ShipToState | String | Input, Output | Is passed to the calculate() method of the POBean by the Order Fulfillment workflow; the initial value will be caught by the exception handler and passed to a Worklist user for correction The corrected value obtained from the user is returned to the Order Processing workflow | <shiptostate>
CustomerID | String | n/a | Is used for the credit check task to identify the customer to the Worklist user | <customer> <id>
CustomerName | String | Input | Is used for the customer notification task to identify the customer to the Worklist user Is passed to the Order Fulfillment workflow for the shipping task | <customer> <name>
CustomerAddress | String | Input | Is passed to the Order Fulfillment workflow for the shipping task | <customer> <address>
CustomerPhone | String | n/a | Is used in the customer notification task to provide the customer's contact information to the Worklist user | <customer> <phone>
CustomerEmail | String | n/a | Is used in the order confirmation task | <customer> <email>
ItemID | Integer | Input | Is passed to the checkInventory() and calculate() methods | <item> <id>
ItemName | String | n/a | Not used | <item> <name>
ItemQuantity | Integer | Input | Is used by a decision node for comparison with the result of the checkInventory() method, and is passed to the calculate() method by the Order Fulfillment workflow | <item> <quantity>

To create the variables:

1. Expand the Order Processing template definition folder, right-click Variable, and select Create Variable from the pop-up menu. The Variable Properties dialog box appears.

   Figure 4-2 Variable Properties Dialog Box

2. In the Name field, enter a name for the variable, according to Table 4-2.

   Note: Variable names cannot contain spaces.

3. From the Type drop-down list, select the appropriate data type for the variable, according to Table 4-2.

4. Select any Parameter check boxes that are necessary, according to Table 4-2.

5. Click OK. The new variable appears in the Variables folder in the folder tree.

6. Repeat steps 1 to 5 to create all the variables listed in Table 4-2.

   Note: You do not need to create the OrderID variable, because you already created it in Adding a Workflow Label.

When you are done, the Variables folder tree should appear as follows.

Defining the Start Node Event

To ensure that the workflow is triggered by the correct XML document, we specify a root element for the Start node that corresponds to the root element of the XML document posted in the Order Processing Trigger, namely <neworder>.

Because the Start node is not tied to a particular instance of the XML document, but should be triggered by all incoming XML documents containing the root element <neworder>, we do not need to set up an event key, as we do for the events we define within the workflow. (For an example, see Creating an Event: Defining the Watch for Cancellation Event.)

To set up the event:

1. In the Order Processing workflow diagram, double-click the Start node to display the Start Properties dialog box.

2. Select the Event option, and in the drop-down list, select XML Event.

   Figure 4-3 Start Properties Dialog Box: Event

3. In the Document Type/Root Element field, enter neworder.

4. From the Start Organization drop-down list, select "CDExpress".

Defining XPath Statements

To extract values from an XML document and place them into workflow variables, you use XPath language statements, which function in a similar fashion to query language statements on a database. Although XPath is a powerful language with numerous functions, the function you will most commonly use is text(), which returns the value of an element or attribute. The generic form of the XPath text() function statements that we will use is as follows:

- For an element value:

XPath("/root element/child element/text()")

- For an attribute value:

XPath("/root element/@attribute/text()")

To extract the values from our XML document, then, you will need to set up XPath statements like those shown in the following table.

Table 4-3 Start Node: XPath Expressions

Variable | Corresponding XML Element | Required XPath Expression to Extract Value
--- | --- | ---
OrderStatus | <status> | XPath("/neworder/status/text()")
OrderID | <id> | XPath("/neworder/id/text()")
ShipToState | <shiptostate> | XPath("/neworder/shiptostate/text()")
CustomerID | <customer> <id> | XPath("/neworder/customer/id/text()")
CustomerName | <customer> <name> | XPath("/neworder/customer/name/text()")
CustomerAddress | <customer> <address> | XPath("/neworder/customer/address/text()")
CustomerPhone | <customer> <phone> | XPath("/neworder/customer/phone/text()")
CustomerEmail | <customer> <email> | XPath("/neworder/customer/email/text()")
ItemID | <item> <id> | XPath("/neworder/item/id/text()")
ItemName | <item> <name> | XPath("/neworder/item/name/text()")
ItemQuantity | <item> <quantity> | XPath("/neworder/item/quantity/text()")

You can create XPath statements in the Studio through any of the following three methods, which are listed in increasing order of validity checking:

- Typing the expressions manually—This method provides no validity checking; if your XPath statement is invalid, it will not be rejected, and you will have to find the error manually.

- Using the Expression Builder to construct parts of the expressions—This method still requires that you type most of the expression manually, but it prompts you with error messages if you try to add an invalid statement.

- Using the XPath Wizard to generate the expressions automatically from a stored XML entity—This method allows you to select sections of actual XML entities and to test expressions against them. This method provides the highest level of assistance and validity checking of the three methods listed here.

In the following procedure, we use the XPath Wizard to load the Neworder document you exported in Using the XML Repository: Exporting the Neworder XML Document.

To use the XPath Wizard to define XPath expressions:

1. At the bottom of the Start Properties dialog box, select the Variables tab and click Add. The Workflow Variable Assignment dialog box appears.

2. Click the button next to the Event Expression field. The Expression Builder dialog box appears.

3. Click XPath Wizard. The XPath Wizard appears.

4. Select the Sample tab.

5. Click the Open Document button . The XML Finder dialog box appears.

6. Select the Repository tab.

7. Double-click the folder in which you saved the XML entity in Using the XML Repository: Exporting the Neworder XML Document (for example, Tutorial).

   Figure 4-4 XML Finder Dialog Box: Repository Tab

8. Select the Neworder document and click Preview to preview the document. The Preview Document window appears, showing the actual text version of the XML document you saved in Using the XML Repository: Exporting the Neworder XML Document.

   Figure 4-5 Preview Document Window

9. Click OK to close the Preview window.

10. Click OK to exit the XML Finder. The XML document appears in the Sample window of the XPath Wizard.

    Figure 4-6 XPath Wizard: Sample Tab

11. Do either of the following:

    - Highlight the first element value by clicking it. Its XPath statement is automatically generated in the XPath Expression field.

    - Select the Test tab, type the XPath statement in the XPath Expression field, and validate your expression by clicking the Test XPath Expression button and checking to see whether the value selected in the document by the Wizard is the value you want to capture.

12. Click the Pin Expression to Workspace button . The expression appears in the Workspace (select the Workspace tab to view).

    Figure 4-7 XPath Wizard: Workspace Tab

13. Repeat steps 10 and 11 for all the XML elements in Table 4-3. When you are done, the Workspace should look like this:

14. Click OK to exit the XPath Wizard for now, click OK to exit the Expression Builder and Cancel to exit the Workflow Variable Assignment dialog boxes.

To add the XPath expressions to the Variables list of the Start Properties dialog box:

1. At the bottom of the Start Properties dialog box, select the Variables tab and click Add. The Workflow Variable Assignment dialog box appears.

   Figure 4-8 Workflow Variable Assignment Dialog Box

2. From the Variable drop-down list, select a variable.

3. Click the button to invoke the Expression Builder dialog box.

4. Click XPath Wizard.

5. In the XPath Wizard dialog box, select the Workspace tab.

6. Select the appropriate XPath expression for your variable, according to the list in Table 4-3, and click OK. The expression appears in the Expression window of the Expression Builder dialog box.

   Figure 4-9 Expression Builder Dialog Box

7. Click OK. The expression appears in the Expression field of the Workflow Variable Assignment dialog box.

8. Click OK. The new XPath expression appears on the Variables tab of the Start Node Properties dialog box.

   Figure 4-10 Start Node Properties Dialog Box: Variables Tab

9. Repeat steps 1 to 8 for all the variables and expressions listed in Table 4-3.

10. When you are done, click OK to exit the Start Node Properties dialog box.

Sending an XML Message to a Worklist User: Defining the Check Customer Credit Task

This task assigns the work of checking the customer's credit to the user admin in the Worklist, and then sends an XML message to that user, requesting confirmation of the credit approval.

To define the task, we need to:

- Add and define the Assign Task to User action

- Add and define the Send XML to Client Action

Assigning a Task to a User

This procedure explains how to assign the Check Customer Credit task to the user admin.

Before we can add the actions we want for this node, we need to clear the default actions and permissions that were predefined for all T1 task nodes when you created the template definition.

To clear default actions:

1. In the workflow design area, double-click the Check Customer Credit task node to display the Task Properties dialog box.

2. Select the Activated tab, select the default Assign Task to WorkflowAttribute("Initiator") action, and click Delete. When prompted for confirmation, click Yes.

3. Select the Executed tab, select the default Mark Task Done action, and click Delete. When prompted for confirmation, click Yes.

To add and define the Assign Task to User action:

1. In the Task Properties dialog box, select the Activated tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Assign Task to User, and click OK. The Assign Task to User dialog box appears.

   Figure 4-11 Assign Task to User Dialog Box

3. In the Task to assign list of the dialog box, select the task Check Customer Credit.

4. From the User drop-down list, select admin, and click OK. The Assign Task to User now appears on the Activated tab in the Task Properties dialog box.

Sending an XML Message to a Client

One way of interacting with a client application user is to define an XML document that you send to the client application. The application should be programmed to identify this XML document, respond to it appropriately, and send an XML document to the server with information that can be used to populate workflow variables.

By default, the Worklist application recognizes a default set of Document Type Definitions (DTDs), consisting of eight request and response DTDs, which you can view in the WLI_HOME/docs/apidocs/com/bea/wlpi/common/doc-files directory of your WebLogic Integration installation. They are described in the following table.

Note: You can also develop custom code to extend the types of XML documents a client application can recognize, or to communicate with a client application via the API. For more information, see Programming BPM Client Applications.

Table 4-4 Worklist DTDs

Request DTD | Description | Corresponding Response DTD
--- | --- | ---
ClientMsgBoxReq.dtd | Displays a message box with buttons to the user. | ClientMsgBoxResp.dtd
ClientSetVarsReq.dtd | Displays a message box with data entry fields to the user. | ClientSetVarsResp.dtd
ClientCallPgmReq.dtd | Calls a program on the client machine. | ClientCallPgmResp.dtd
ClientCallAddInReq.dtd | Invokes a custom extension to the Worklist application. | ClientCallAddInResp.dtd

For our Check Customer Credit task, we will use the ClientMsgBoxReq.dtd to send a message box with yes/no buttons. The DTD has the following structure:

Listing 4-1 ClientMsgBoxReq XML Document Structure

>     <message-box title="text"
>      style="{plain|information|question|warning|error}"
>      options="{ok|ok_cancel|yes_no|yes_no_cancel}">
>     text
>        <actionid>	provided by default	</actionid>
>     </message-box>

Note: The action ID element and value are provided by the system when you create a Send XML to client action.

The following figure shows the tags and values that correspond to the message box we will send.

Figure 4-12 Credit Check Message Box

Because we want to use the customer ID in the text of the message we send, we will use the CustomerID variable to supply the appropriate value at run time.

To capture the result of the user's selection of buttons, we need to extract data from the ClientMsgBoxResp.dtd, specifically from the <message-box option> attribute, as shown in Listing 4-2.

Listing 4-2 ClientMsgBoxResp XML Document Structure

>     <message-box option="{ok|yes|no|cancel}" />

Thus, to define the complete action, we need to:

- Add the Send XML to Client action and create a variable in which to store the user's response to the XML message

- Create the XML document structure

- Specify the callback variable with an XPath expression to extract the user's response to the message box

- Add and define the Mark Task Done callback action

Adding the Send XML to Client Action

To store the result of the user's input to the Check Credit task, we need to create the CreditCheck variable.

Since we can create the variable from within the Send XML to Client dialog box, we will add the Send XML to Client action and create the CreditCheck variable at the same time.

To add the Send XML to Client action and create the CreditCheck variable:

1. In the Task Properties dialog box, select the Executed tab, and click Add. The Add Action dialog box appears.

2. Expand the Integration Actions folder, select Send XML to Client and click OK. The Send XML to Client dialog box appears, with the default root and actionid elements.

3. Double-click the value field next to the root element to display the Expression button .

4. Click the Expression button to invoke the Expression Builder.

5. In the Expression Builder, select the Variables option.

6. From the variables list, scroll to NEW, and double-click NEW to invoke the Variable Properties dialog box.

7. Create the variable as described in the following table. Click OK to exit the Variable Properties dialog box.

   Table 4-5 Check Customer Credit Task Variable

   Variable | Data Type | Parameter Type | Use in Workflow | Corresponding XML Element or Attribute
   --- | --- | --- | --- | ---
   CreditCheck | String | n/a | To store the result of the Worklist user's response | <message-box option>

8. Click OK to exit the Expression Builder.

Defining the XML Document Structure

To define the message-box XML document structure:

1. In the Send XML to Client dialog box, expand the root element.

   Warning: Do not edit, delete or move the actionid element, its name or, its value. The action ID is used to identify the action instance at run time.

2. To begin composing the XML document, double-click the root element and type over the existing text to enter message-box. Press Enter.

   Note: If you see the icon, this means that the field does not yet include a valid expression. When you enter a value in the field, the icon disappears.

3. Double-click the value field next to the message-box element and, by typing or using the Expression Builder, enter the following:

   "Does customer " + $CustomerID + " pass credit check?"

   Remember to include spaces inside the quotation marks to separate string literals from variables.

4. Select the message-box element, and click the Add Attribute button to add the first attribute.

5. In the Attribute field, double-click and type over the existing text to add the attribute name options.

6. In the value field next to the options attribute, double-click type over the existing text to enter "yes_no".

7. Select the message-box element, and click the Add Attribute button to add the second attribute.

8. In the Attribute field, double-click and type over the text to add the attribute name style.

9. In the value field next to the options attribute, double-click and type over the text to enter "question".

10. Select the message-box element, and click the Add Attribute button to add the third attribute.

11. In the Attribute field, double-click and type over the text to add the attribute name title. Press Enter.

12. In the value field next to the style attribute, double-click and type over the text to enter "Credit Check", and press Enter.

    The completed XML document structure should now look like the following.

Assigning the Callback Variable

To extract the result of the user's response to the message box from the XML document returned by the Worklist application, we need to set up an XPath expression to populate the CreditCheck variable.

To assign the callback variable:

1. At the bottom of the Send XML to Client dialog box, select the Callback Variables tab.

2. Click Add. The Workflow Variable Assignment dialog box appears.

3. From the Variable drop-down list, select CreditCheck.

4. In the Event Expression field, enter the XPath statement listed in the following table.

   Table 4-6 Check Customer Credit Task Node XPath Expression

   Variable | Corresponding XML Element | Required XPath Expression to Extract Value
   --- | --- | ---
   CreditCheck | <message-box option> | XPath("/message-box/@option/text()")

5. Click OK to exit. The new variable assignment statement appears on the Callback Variables tab.

Tip: You can also load the ClientMsgBoxResp.dtd file into the XPath Wizard to automatically generate an XML document from which you can build the XPath expression. For procedures on using the XPath Wizard, see Defining XPath Statements.

Marking the Task Done

Because we want to ensure that the task node waits for the user's response to the message box before moving to the next node, we specify the Mark Task Done action as a callback action in the Send XML to Client dialog box, rather than adding it to the Task Properties dialog box. Placing the Mark Task Done action here causes the workflow to wait for the response from the Worklist client before proceeding to the next node.

To add the Mark Task Done callback action:

1. At the bottom of the Send XML to Client dialog box, select the Callback Actions tab.

2. Click Add to invoke the Add Action dialog box.

3. Expand the Task Actions folder, select Mark Task as Done, and click OK. The Mark Task as Done dialog box appears.

   Figure 4-13 Mark Task as Done Dialog Box

4. From the Task to mark as done list, select Check Customer Credit, and click OK. The Mark Task Done action appears on the Callback Actions tab.

5. Click OK to exit the Send XML to Client dialog box. The Send XML to Client action appears on the Executed tab of the Task Properties dialog box.

6. Click OK to exit the Task Properties dialog box.

Testing for Equality: Defining the Check Credit Decision

The first decision in our workflow checks whether the customer has passed the credit check, according to the Worklist user's response in the Check Credit task—yes or no.

The decision node is named with the condition that you are evaluating, and this condition must be specified as an expression. Typically the condition compares the value of a variable with another element, such as a constant, or another variable. By default a decision is assigned the condition 1=1 (which always evaluates to true).

To check the Worklist user's response to the credit check question, we will create a test for equality with a constant. That is, we will test whether the response from the user, stored in the variable CreditCheck, equals "yes". If the condition evaluates to true, the flow proceeds to the Check Inventory task; if the condition evaluates to false, the flow proceeds to the Contact Customer task.

To define the C1 decision node:

1. In the workflow design window, double-click the C1 decision shape to display the Decision Properties dialog box.

2. In the Condition field, enter $CreditCheck="yes".

3. Click OK to close the dialog box.

Adding a Task and Workflow Comment: Defining the Contact Customer Task

If the credit check decision evaluates to false, the flow proceeds to the Contact Customer task, and then terminates. This node sets the variable OrderStatus to cancelled and adds a workflow comment to that effect. The comment will appear in the run-time applications when the workflow is executed.

The task of contacting the customer is then assigned to the role CustomerService, rather than to a particular user. This means that any user associated with the role can execute the task. Also, rather than communicating with the Worklist user via an XML message, we set a task comment that appears along with the task in the Worklist window at run time.

Note: Workflow and task comments are limited to a maximum of 254 characters. The comment length is determined at run time because of the variable length of expressions. Comments exceeding the 254 character limit are truncated at run time with no warning.

To define the Contact Customer task node, we will:

- Add and define the Set Workflow Variable action

- Add and define the Set Workflow Comment action

- Add and define the Set Task Comment action

- Add and define the Assign Task to Role action

- Add and define the Mark Task as Done Action

Setting a Workflow Variable

To add and define the Set Workflow Variable action:

1. Double-click the Contact Customer task node to open the Task Properties dialog box.

2. Select the Activated tab and click Add to open the Add Action dialog box.

3. Expand the Workflow Actions folder, select Set Workflow Variable, and click OK. The Set Workflow Variable dialog box appears.

   Figure 4-14 Set Workflow Variable Dialog Box

4. From the Variable to be set drop-down list, select OrderStatus.

5. Select the From Expression option, and in the field, enter "cancelled".

6. Click OK. The Set Workflow Variable action appears on the Activated tab in the Task Properties dialog box.

Setting a Workflow Comment

Once we have set the OrderStatus variable, we can use this variable in the expression we build to specify a workflow comment. This comment will appear in the run-time applications as Order cancelled.

To add and define the Set Workflow Comment action:

1. In the Contact Customer Task Properties dialog box, select the Activated tab and click Add to open the Add Action dialog box.

2. Expand the Workflow Actions folder, select Set Workflow Comment and click OK. The Set Workflow Comment dialog box appears.

   Figure 4-15 Set Workflow Comment Dialog Box

3. In the Comment field, type or use the Expression Builder to enter the expression "Order " + $OrderStatus.

4. Click OK to exit the dialog box. The Set Workflow Comment action now appears on the Activated tab in the Task Properties dialog box.

Setting a Task Comment

The comment we are going to display to the Worklist user is:

Please contact John Doe at 408 534 9567

So that the workflow supplies the variable values at run time, we use the CustomerName and CustomerPhone variables in the expression. Our expression should resemble the following:

Listing 4-3 Contact Customer Task: Task Comment

>     "Please contact " + $CustomerName + " at" + $CustomerPhone

Note the use of plus signs to concatenate string literals and variables, and the use of spaces to ensure that spaces appear in the final message between variable values and literal text.

To add and define the Set Task Comment action:

1. In the Contact Customer Task Properties dialog box, select the Activated tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Set Task Comment, and click OK. The Set Task Comment dialog box appears.

   Figure 4-16 Set Task Comment Dialog Box

3. From the Task for which to set comment list, select Contact Customer.

4. In the Comment field, type or click the Expression button to invoke the Expression Builder to enter the text in Listing 4-3.

5. Click OK to exit the Set Task Comment dialog box. The Set Task Comment action now appears on the Activated tab of the Task Properties dialog box.

Assigning a Task to a Role

In addition to assigning a task to a user, identified by user name, you can also assign a task to a role, which can be executed by any user associated with that role.

You have a third option, which is to assign a task to a user in a role. This action assigns the task to the user associated with the role name who has the fewest number of tasks assigned to him or her at run time. However, because we are working with only a limited number of users and tasks in our examples, we will assign the task to the role name directly.

This procedure assigns the task to the role CustomerService. The user who is assigned the task (in this case, only the user admin) will see the task comment and should respond to it accordingly before executing the task.

To add and define the Assign Task to Role action:

1. In the Contact Customer Task Properties dialog box, select the Activated tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Assign Task to Role, and click OK. The Assign Task to Role dialog box appears.

   Figure 4-17 Assign Task to Role Dialog Box

3. From the Task to assign list, select Contact Customer.

4. From the Role drop-down list, select CustomerService.

5. Click OK to exit the dialog box. The Assign Task to Role action now appears on the Activated tab in the Task Properties dialog box.

Marking the Task Done

Because this is task is assigned to an end user, we add the Mark Task Done action to the Executed tab in the Task Properties dialog box. Remember, without the Mark Task as Done action, the flow will not move forward from this node.

To add and define the Mark Task Done action:

1. In the Contact Customer Task Properties dialog box, select the Executed tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Mark Task as Done, and click OK to invoke the Mark Task as Done dialog box.

3. From the Task to mark as done list, select Contact Customer, and click OK. The Mark Task Done action appears on the Executed tab in the Task Properties dialog box.

4. Click OK to exit the Task Properties dialog box.

Creating and Performing a Business Operation: Defining the Check Inventory Task

If the credit check decision evaluates to true, the flow proceeds to the Inventory Check task. This task calls the checkInventory() method on the POBean EJB, which checks the inventory for the item ordered and returns the results to the workflow. The checkInventory() method takes a single parameter, the item ID, and returns the quantity in stock.

Note: For more information on the POBean.jar EJB, see the BEA WebLogic Integration Javadoc.

To call an EJB method, you need to do two things:

- Create a business operation for it

- Add and define the Perform Business Operation action to the node that calls the business operation

Because the checkInventory() method returns a value, namely the inventory quantity for the relevant item, we also need to create a workflow variable in which to store the result.

However, before calling any method on an EJB, you must first call the bean's create() method, which creates an instance of the EJB on the WebLogic Integration server. The create()method also returns a reference to the EJB instance. This reference needs to be stored in a workflow variable known as an instance variable, so that you can invoke multiple methods on the EJB.

Thus, in order to define our Check Inventory task, we need to:

- Create the business operation for the create() method

- Create the business operation for the checkInventory() method

- Add and define the Perform Business Operation Create OrderBean action, and create a variable in which to store the result

- Add and define the Perform Business Operation Check Inventory action, and create a variable in which to store the result

- Add and define the Mark Task Done action

Note: The sample plug-ins that ship with WebLogic Integration include a plug-in action, Check Inventory, that allows you to perform the first four steps listed above in a single, predefined action. This action provides custom code that calls the appropriate POBean methods and passes parameters from and to the workflow, while you only need to specify the workflow variables that should act as the input and output parameters. To view the dialog box for this action, in the Actions dialog box, expand the Sample Actions folder and double-click Check inventory for an available item. For more information on this action and the other sample plug-ins, see Programming BPM Plug-Ins for WebLogic Integration.

Creating a Business Operation

When you create a business operation, you are configuring it globally, which means that it can then be used by any workflow in any organization. The business operation is essentially a user-friendly alias for a method call on a Java class or EJB. You can also add descriptive names for any parameters the method takes, so that other users who want to call the same business operation can know immediately what parameters, and in which order, they need to provide for it.

We do not need to create the Create OrderBean business operation, because we imported it during the import procedure in Importing Workflow Objects: Importing the Tutorial Package File. (The Order Fulfillment workflow also uses this business operation, and we did not want to cause an unresolved reference in that workflow at import time.) Instead, we will simply view it.

However, we will create the Check Inventory business operation that calls the checkInventory() method on the POBean EJB, so that we can then invoke it in our Check Inventory task.

Viewing the Create OrderBean Business Operation

To view the Create OrderBean Business Operation definition:

1. Choose Configuration—>Business Operations. The Business Operations dialog box appears, with the two business operations you imported in Importing Workflow Objects: Importing the Tutorial Package File: Create OrderBean and Calculate Total Price.

   Figure 4-18 Business Operations Dialog Box

2. In the list of business operations, double-click the Create OrderBean description. The Define Business Operation dialog box appears.

   Figure 4-19 Create OrderBean: Define Business Operation Dialog Box

   The dialog box shows that the create() method contains no parameters, and its return type is a reference to the remote interface of the POBean EJB.

3. Click Cancel to close the Define Business Operation dialog box.

Creating the Check Inventory Business Operation

To create the Check Inventory Business Operation:

1. In the Business Operations dialog box, click Add. The Define Business Operation dialog box appears.

2. Select the Session EJB option. All the currently deployed Session EJBs become available for selection in the JNDI Name for Session EJB drop-down list.

3. From the JNDI Name for Session EJB drop-down list, select wlpi.tour.POBean. The methods for this EJB become available for selection in the Method to Call drop-down list.

4. From the Method to Call drop-down list, select int checkInventory(int p0). Its parameters and return type are displayed in the dialog box.

   Figure 4-20 Check Inventory: Define Business Operation Dialog Box

5. In the Business Operation Name field, enter Check Inventory.

6. Optionally, rename the single parameter by double-clicking on it in the Parameters list. The Parameter dialog box appears.

   Figure 4-21 Parameter Dialog Box

7. Because this method takes the item ID as its parameter, in the Name field, enter ItemID.

   Note: Business operation parameter names cannot contain spaces.

8. Click OK. The new parameter name appears in the Parameters list in the Define Business Operation dialog box.

9. Click OK to exit the Define Business Operation dialog box. The new business operation now appears in the Business Operations dialog box.

10. Click Close to exit the Business Operations dialog box.

Performing a Business Operation

Now that we have created the business operations necessary to call the methods we need from the OrderBean, we need to define the action that invokes them from within the task.

When you define an action that invokes a business operation, you need to specify the following variables/parameters:

- Any workflow variables you are passing as input parameters to the method

- The workflow variable in which you want to store the result returned by the method

- The instance variable, which is the reference to the EJB returned by the create() method

The following table summarizes the relationship between the parameters required by the two business operations.

Table 4-7 Create OrderBean and Check Inventory Business Operations: Parameters

Business Operation | Instance Variable | Input Parameter(s) | Result Variable
--- | --- | --- | ---
Create OrderBean | none | none | OrderBeanReference
Check Inventory | OrderBeanReference | ItemID | Inventory

Note that we need to create the OrderBeanReference and Inventory variables before we can use them in our business operations. Because variables used in business operations can be created from within the Perform Business Operation action dialog box, we will combine the procedure for creating the variables with the procedure for adding and defining the actions in the following sections.

Performing the Create OrderBean Business Operation

When we add and define the action, we will also create the variable listed in the following table.

Table 4-8 Create OrderBean Business Operation: Result Variable

Variable | Data Type | Parameter Type | Use in Workflow
--- | --- | --- | ---
OrderBeanReference | Session EJB | n/a | To store a reference to the instance of the POBean session EJB

To add and define the Perform Business Operation action for Create OrderBean:

1. In the workflow design window, double-click the Check Inventory task to invoke the Task Properties dialog box.

2. Select the Activated tab and click Add to display the Add Action dialog box.

3. Expand the Integration Actions folders, select the Perform Business Operation action, and click OK. The Perform Business Operation dialog box appears.

4. From the Operation drop-down list, select Create OrderBean.

5. Next to the Assign Result to field, click Add. The Variable Properties dialog box appears.

6. In the Name field, enter OrderBeanReference.

7. From the Type drop-down list, select Session EJB.

8. Select the Input check box. (This variable is also used by the Order Fulfillment workflow.)

9. Click OK. The variable name and type now appear in the Assign Results to field.

   Figure 4-22 Create OrderBean: Perform Business Operation Dialog Box

10. Click OK to exit the dialog box. The Perform Business Operation Create OrderBean action now appears on the Activated tab in the Task Properties dialog box.

Performing the Check Inventory Business Operation

When we add and define the action, we will also create the variable listed in the following table.

Table 4-9 Check Inventory Business Operation: Result Variable

Variable | Data Type | Parameter Type | Use in Workflow
--- | --- | --- | ---
Inventory | Integer | n/a | To store the result of the inventory check

To add and define the Perform Business Operation action for Check Inventory:

1. In the Check Inventory Task Properties dialog box, select the Activated tab, and click Add to display the Add Action dialog box.

2. Expand the Integration Actions folders, select the Perform Business Operation action, and click OK. The Perform Business Operation dialog box appears.

3. From the Operation drop-down list, select Check Inventory. The Instance Variable field is automatically populated with the OrderBeanReference variable.

4. In the Parameters list, double-click the ItemID parameter. The Expression Builder appears.

5. Select the Variables option, find ItemID in the list, and double-click it to place it in the Expression field.

6. Click OK. The ItemID variable now appears in the Value section of the Parameters list.

7. Next to the Assign result to field, click Add. The Variable Properties dialog box appears.

8. In the Name field, enter Inventory.

9. From the Type drop-down list, select Integer.

10. Click OK. The variable name and type now appear in the Assign result to field.

    Figure 4-23 Check Inventory: Perform Business Operation Dialog Box

11. Click OK to exit the dialog box. The Perform Business Operation Check Inventory action now appears on the Activated tab in the Task Properties dialog box.

Marking the Task Done

Because this task contains no actions that execute the task (for example, assigning the task to a Worklist user who executes it), we need to add the Mark Task Done action to the Activated, rather than the Executed, tab of the Task Properties dialog box.

To add and define the Mark Task Done action:

1. In the Task Properties dialog box, select the Activated tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Mark Task as Done, and click OK to invoke the Mark Task as Done dialog box.

3. From the Task to mark as done list, select Check Inventory, and click OK. The Mark Task Done action appears on the Activated tab in the Task Properties dialog box.

4. Click OK to exit the Task Properties dialog box.

Testing for Inequality: Defining the Check Inventory Decision

The second decision in our workflow checks whether the inventory is sufficient, by comparing the inventory value returned by the Check Inventory business operation with the quantity of items ordered by the customer (that is, the quantity originally specified in the Neworder XML document and stored in the ItemQuantity variable when the workflow is started).

To test whether the inventory is sufficient, we will create a test for inequality between two variables. That is, we will test whether the value of the variable Inventory is greater than or equal to that of the variable ItemQuantity. If the condition evaluates to true, the flow proceeds to the Start Order Fulfillment task; if the condition evaluates to false, the order status is set to "waiting" and the flow proceeds to the Wait for Inventory task.

To define the C2 decision node:

1. In the workflow design window, double-click the C2 decision shape to display the Decision Properties dialog box.

   Figure 4-24 Check Inventory Decision

2. In the Condition field, enter $Inventory>=$ItemQuantity.

3. Select the False tab, and click Add to invoke the Add Action dialog box.

4. Expand the Workflow Actions folder, select Set Workflow Variable, and click OK to display the Set Workflow Variable dialog box.

5. From the Variable drop-down list, select OrderStatus.

6. Select the From Expression option, and in the field, enter "waiting".

7. Click OK to close the Set Workflow Variable. The Set Workflow variable action appears on the False tab.

8. Click Add to invoke the Add Action dialog box.

9. Expand the Workflow Actions folder, select Set Workflow Comment, and click OK to invoke the Set Workflow Comment dialog box.

10. In the Comment field, enter the expression "Order " + $OrderStatus.

11. Click OK to exit the Set Workflow Comment dialog box. The Set Workflow Comment action appears on the false tab.

12. Click OK to exit the Decision Properties dialog box.

Creating an Event: Defining the Wait for New Inventory Event

If the inventory check decision evaluates to false, the flow proceeds to the Wait for Inventory event, which would be triggered—hypothetically—by the arrival of the relevant XML message on a JMS queue from an inventory-reporting application. Because the node is embedded within the main flow, the flow does not proceed, but remains in a wait state, until the node is triggered. When the node is triggered, the flow loops back to the Inventory Check task to see whether the current inventory is now sufficient to process the order.

Although this event is never actually triggered in the sample workflow because we are not using a real XML document, we can imagine a hypothetical XML document that looks something like the following document.

Listing 4-4 Newinventory XML Document

>     <newinventory>
>        <date> June 18 2001 </date>
>        .
>        .
>        .
>        <item>
>           <id>236</id>
>           <name>CD storage rack</name>
>        <item>
>     </newinventory>

To ensure that the event is triggered at run time only by instances of <newinventory> documents that contain information about the relevant item in stock (in our original XML document, it was a CD storage rack), you define an event key that specifies the relevant element within the message document that the event processor should watch out for—in this case, the item ID. The event key expression is specified as an XPath statement that extracts the value from the relevant element in an XML document.

Then, to save the event processor from searching through every workflow instance containing an event with a reference to a <newinventory> document, the event node itself defines a key value expression to match the value extracted by the event key. If the two values match, the event is triggered. The following figure shows how the mechanism works.

Figure 4-25 Relationship Between Incoming XML Document, Event Key Expression, and Key Value Expression

In the example given in Listing 4-4, the event would be triggered, since our original item ID was 236.

The way in which the incoming XML document element value, event key configuration expression, and event node key value expression correspond to each other for the Wait for Inventory node is represented in the following table.

Table 4-10 Wait for Inventory Event: Relationship Between Event Key and Event Node Expressions

Element | XML Document | Event Key Configuration | Event Node
--- | --- | --- | ---
Root element/Document Type | <newinventory> | newinventory | newinventory
Event Key Expression/Key Value Expression | <item> <id> | ToInteger(ToString(XPath("/newinventory/item/id/text()"))) | $ItemID

Note that an event key configuration expression must evaluate to the same data type as that by the key value expression in a Start or Event node. Since XPath expressions return a node list type, you will usually need to use a typecasting function provided in the workflow expression language to return the correct data type. In our example, since our variable was stored as an integer, we needed to first convert the node list to a string, and then convert the string to an integer. For more information on typecasting and other workflow functions, see "Using Functions" in Using Workflow Expressions in Using the WebLogic Integration Studio.

To create our event, then, we must do the following:

- Configure the event key

- Define the event

Configuring an Event Key

When you configure an event key, you specify the document type or root element of an XML document and an expression that parses the document for the particular element value you want to extract. Once the event key is configured, it is globally available to all workflow templates.

To define the newinventory event key:

1. Choose Configuration—>Events. The Event Key Expressions dialog box appears, showing the cancelledorder event key you imported in Getting Started with the WebLogic Integration Studio.

   Figure 4-26 Event Key Expressions Dialog Box

2. Click Add. The Define Event Key Expression dialog box appears.

   Figure 4-27 Define Event Key Expression Dialog Box

3. In the Event Descriptor field, enter newinventory.

4. In the Expression field, enter the XPath expression listed in Table 4-10, by typing it or clicking the Expression button to invoke the Expression Builder.

5. Click OK. The new event key appears in the Event Key Expressions dialog box.

6. Click Close to close the Event Key Expressions dialog box.

Defining an Event

In the event node, you specify the root element of the incoming XML document, and the key value expression that you wish to match the value provided by the XML document. The key value expression you use in each event node should be unique. You can filter incoming documents further by adding a condition, but we do not use one in this example.

Note: Because the event key facility provides better performance, you should always use it in preference over an event condition. Only use a condition in addition to an event key when you wish to further restrict the XML document instance that should trigger the event.

To define the Wait for Inventory event:

1. In the workflow design window, double-click the Wait for Inventory event node. The Event Properties dialog box appears.

   Figure 4-28 Wait for Inventory Event: Event Properties Dialog Box

2. From the Type drop-down list, select XML Event.

3. In the Document Type/Root Element field, enter newinventory.

4. In the Key Value Expression field, enter $ItemID by typing it or clicking the Expression button to invoke the Expression Builder.

5. Click OK to exit the Event Properties dialog box.

Calling a Sub-Workflow: Defining the Start Order Fulfillment Task

If the inventory check decision evaluates to true, the workflow proceeds to the Start Order Fulfillment task, which calls the Order Fulfillment workflow. When the sub-workflow is finished executing, control returns to the Start Order Fulfillment task, and when the task is marked done, the flow proceeds to the next node in the main workflow, namely the Confirm Order Fulfillment task.

When you call a sub-workflow, you need to pass any values that have been collected or set during the execution of the main workflow to the sub-workflow's input variables. These include, for example, the customer address information needed for the shipping task, and the parameters required by the POBean calculate() method invoked by the invoice generation task. (You can view the list of variables defined in the imported Order Fulfillment workflow by opening its template definition and expanding its Variables folder in the folder tree. To see whether a variable has been defined as input or output, right-click it, and select Properties from the pop-up menu to invoke the variable's Properties dialog box.)

Similarly, you also need to create and specify variables in which you want to store values that are returned by the sub-workflow, such as the total price order to be provided by the calculate() method.

To define the Start Order Fulfillment task, we need to do the following:

- Create the OrderTotalPrice variable

- Add and define the Start Workflow action

- Define the input parameters

- Define the result variables

- Add and define the Mark Task as Done callback action

Creating the OrderTotalPrice Variable

To store the result returned from the calculate() method (which is invoked by the Order Fulfillment workflow), we need to create the OrderTotalPrice variable as described in the following table. If necessary, refer to the procedure given in Creating Variables, substituting the values from the following table.

Table 4-11 Start Order Fulfillment Task Variable

Variable | Data Type | Parameter Type | Use in Workflow
--- | --- | --- | ---
OrderTotalPrice | Double | Input | To store the result of the calculate() method invoked in the Order Fulfillment workflow

Starting a Called Workflow

To start a sub-workflow, you must be sure that the sub-workflow's start node is defined as Called, and that the workflow is active. In this case, we activated the Order Fulfillment workflow when we imported it in Importing Workflow Objects: Importing the Tutorial Package File.

To add and define the Start Workflow action:

1. In the workflow design window, double-click the Start Order Fulfillment task node to invoke the Task Properties dialog box.

2. Select the Activated tab, and click Add to invoke the Add Action dialog box.

3. Expand the Workflow Actions folder, select Start Workflow, and click OK. The Start Workflow dialog box appears.

4. In the Workflow to Start window, select Order Fulfillment

   Figure 4-29 Start Workflow Dialog Box

5. Under Start in Organization, select Current Organization.

Defining Input Parameters

When you select a sub-workflow to call in the Start Workflow dialog box, any variables defined as input in the sub-workflow are displayed in the Parameters tab at the bottom of the dialog box.

Figure 4-30 Start Order Fulfillment Workflow: Input Parameters

You must now set the values for those parameters. You can use an expression to define a value or, in this case, because we simply want to pass the current variable values, you can specify variable names as the parameter expressions.

To define the input parameters for the Start Order Fulfillment workflow:

1. At the bottom of the Start Workflow dialog box, select the Parameters tab.

2. Double-click a parameter in the list. The Set Parameter dialog box appears.

   Figure 4-31 Set Parameter Dialog Box

3. In the Expression field, enter the variable name, preceded by the dollar sign, that corresponds to the parameter, and click OK.

4. Repeat steps 1 to 3 for all the variables in the list.

5. When you are done, the list should be complete, as follows.

Defining Result Variables

When you select a workflow to call in the Start Workflow dialog box, any variables that have been defined as output parameters by the sub-workflow are displayed on the Results tab at the bottom of the dialog box.

Figure 4-32 Start Order Fulfillment Workflow: Results

We now want to ensure that the results returned from the sub-workflow are stored in the appropriate variables. In this case, because all variable names are the same, we need to specify only the equivalent variable name for each result parameter.

To define the result parameters for the Start Order Fulfillment workflow:

1. At the bottom of the Start Workflow dialog box, select the Results tab.

2. Double-click an item in the Result list. The Set Variable from Result dialog box appears.

   Figure 4-33 Set Variable from Result Dialog Box

3. From the variable drop-down list, select the appropriate variable to which to assign the result, and click OK.

4. Repeat steps 1 to 3 for both results.

5. When you are done, the list should be complete, as follows.

Marking the Task Done

To ensure that the main workflow waits for the sub-workflow to complete before it continues, we add the Mark Task Done as a sub-action within the Start Workflow action.

To add and define the Mark Task Done action:

1. At the bottom of the Start Workflow dialog box, select the Actions tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Mark Task as Done, and click OK to invoke the Mark Task as Done dialog box.

3. From the Task to mark as done list, select Start Order Fulfillment, and click OK. The Mark Task Done action appears on the Actions tab of the Start Workflow dialog box.

Sending an E-mail Message: Defining the Confirm Order Fulfillment Task

Once the Order Fulfillment has been executed, we want to ensure that the Watch for Cancellation event can no longer be triggered, and the workflow can no longer be terminated. The Confirm Order Fulfillment task cancels the Watch for Cancellation event, sets the order status to complete, adds a workflow comment to this effect, and, optionally, sends an e-mail to the customer, confirming the completion of the order.

To set up this task, you may:

- Add and define the Cancel Event action

- Add and define the Set Workflow Variable action

- Add and define the Set Workflow Comment action

- Add and define the Send E-mail action

- Add and define the Mark Task as Done action

Cancelling an Event

Once the Order Fulfillment workflow has executed, and the order has been shipped, the order should not be cancelled. To stop the Watch for Cancellation event from listening for incoming messages, we add a Cancel Event action to the Confirm Order Fulfillment task.

To add the Cancel Event action:

1. In the workflow design window, double-click the Confirm Order Fulfillment task to invoke the Task Properties dialog box.

2. Select the Activated tab, click Add to invoke the Add Action dialog box, expand the Miscellaneous Actions folder, select Cancel Workflow Event, and click OK. The Cancel Workflow Event dialog box appears.

   Figure 4-34 Cancel Workflow Event Dialog Box

3. From the Event to cancel list, select Watch for Cancellation and click OK. The Cancel Workflow Event action appears on the Activated tab of the Task Properties dialog box.

Setting the Workflow Variable

The following procedure explains how to set the workflow variable OrderStatus with the value complete.

To add the Set Workflow Variable action:

1. Select the Activated tab, click Add to invoke the Add Action dialog box, expand the Workflow actions folder, select Set Workflow Variable, and click OK to invoke the Set Workflow Variable dialog box.

2. From the Variable to be set drop-down list, select OrderStatus.

3. Select the From Expression option, and in the field, enter "complete".

4. Click OK. The Set Workflow Variable action appears on the Activated tab in the Task Properties dialog box.

Setting the Workflow Comment

Once the OrderStatus variable is set to complete, you can use this variable in a workflow comment expression. The following procedure explains how to set the workflow comment to Order complete.

To add and define the Set Workflow Comment action:

1. In the Task Properties dialog box, select the Activated tab and click Add to invoke the Add Action dialog box.

2. Expand the Workflow Actions folder, select Set Workflow Comment, and click OK to invoke the Set Workflow Comment dialog box.

3. In the Comment field, type or use the Expression Builder to enter the following expression:

   "Order " + $OrderStatus.

4. Click OK to exit the dialog box. The Set Workflow Comment action now appears on the Activated tab in the Task Properties dialog box.

Sending an E-mail Message

To complete the order, you can have the workflow send an e-mail message to the customer who placed it, confirming the fulfillment of the order.

If you entered your own e-mail address and other data in Posting an Internal XML Event: Editing the Neworder XML Document, you will receive the e-mail when you execute the workflow in Executing and Monitoring the Example Workflows.

Note: The Order Processing template definition provided in the tutorial.jar file does not contain this action because the action requires correct server configuration, as described in the following text.

Attempting to send an e-mail at run time requires the following prerequisites:

- Your e-mail server must be appropriately configured during or after the WebLogic Integration installation. For more information on setting up e-mail server properties after installation, see "Customizing Mail Session Properties" in Customizing WebLogic Integration in Starting, Stopping, and Customizing BEA WebLogic Integration.

- You must edit the default e-mail address provided in the Order Processing Trigger workflow, to provide a valid e-mail address. Follow the procedure given in Posting an Internal XML Event: Editing the Neworder XML Document.

If both of these conditions are not met, do not follow this procedure to add the Send E-mail Message action.

If you do opt to add the Send E-mail action, consider using the message shown below as the content for your message.

>     Subject: Your order #order number

>     Your order for item (quantity) has been shipped. The total price for your order is amount. Thank you for your business.

To add and define the Send E-mail Message action:

1. In the Task Properties dialog box, select the Activated tab and click Add to invoke the Add Action dialog box.

2. Expand the Miscellaneous Actions folder, select Send E-mail Message, and click OK. The Send E-Mail Message dialog box appears.

   Figure 4-35 Send E-Mail Message Dialog Box

3. In the subject field, enter "Your order #" + $OrderID or any message you like.

4. Select the To tab and click Add. The Mail Recipient dialog box appears.

   Figure 4-36 Mail Recipient Dialog Box

5. Select the Address option.

6. Select the Expression check box and in the field, enter $CustomerEmail.

7. Click OK. The CustomerEmail variable appears in the Addressee list.

8. Select the Message tab, and enter any text you like. If you enter the expression shown in the following figure, your text will resemble the message shown earlier.

   Figure 4-37 Send E-mail Message Dialog Box: Order Confirmation Message

9. When done, click OK.

10. The Send E-mail action appears on the Activated tab in the Task Properties dialog box.

Marking the Task Done

Because this task contains no actions that execute it, we must add the Mark Task Done action to the Activated tab of the Task Properties dialog box.

To add and define the Mark Task Done action:

1. In the Task Properties dialog box, select the Activated tab, and click Add to invoke the Add Action dialog box.

2. Expand the Task Actions folder, select Mark Task as Done, and click OK to invoke the Mark Task as Done dialog box.

3. From the Task to mark as done list, select Confirm Order Fulfillment, and click OK. The Mark Task Done action appears on the Activated tab in the Task Properties dialog box.

4. Click OK to exit the Task Properties dialog box.

Creating an Event: Defining the Watch for Cancellation Event

At any point during the entire process until the Ship Order task of the Order Fulfillment sub-workflow is executed, the Watch for Cancellation event could be triggered—hypothetically—by the arrival of a relevant XML message on a JMS queue from a Web-tier application. Because the node stands outside of the flow, attached directly to the start and done nodes, the flow can be interrupted regardless of the node which it is currently executing. If the node is triggered before the shipping task of the Order Fulfillment workflow is executed, the Order Processing workflow proceeds to the Done node and terminates.

Although this event is never actually triggered in the sample workflow because we are not using a real XML document, we can imagine a hypothetical XML document that looks like the following document.

Listing 4-5 Cancelledorder XML Document

>     <cancelledorder>
>        <date>June 18 2001</date>
>        <order>
>           <id>9654</id>
>        </order>
>        <customer>
>           <id>232</id>
>           <name>Harold Jones</name>
>        </customer>
>     	.
>     	.
>     	.
>     </cancelledorder>

The way in which the incoming XML document, event key configuration expression, and event node key value expression correspond to each other for this node is represented in following table.

Table 4-12 Watch for Cancellation Event: Relationship Between Event Key and Event Node Expressions

Element | XML Document | Event Key Configuration | Event Node
--- | --- | --- | ---
Root element/Document Type | <cancelledorder> | cancelledorder | cancelledorder
Event Key Expression/Key Value Expression | <order> <id> | ToInteger(ToString(XPath ("/cancelledorder/ order/id/text()"))) | $OrderID

Because you already imported the cancelledorder event key, which is also used by the Order Fulfillment workflow (for information, see Overview of the Order Fulfillment Workflow), you do not need to create the event key. You simply need to define the event.

Defining the Event

To define the Watch for Cancellation event:

1. In the workflow design window, double-click the Watch for Cancellation event node. The Event Properties dialog box appears.

   Figure 4-38 Watch for Cancellation Event: Event Properties Dialog Box

2. From the Type drop-down list, select XML Event.

3. In the Document Type/Root Element field, enter cancelledorder.

4. In the Key Value Expression field, enter $OrderID, by typing it or clicking the Expression button to invoke the Expression Builder.

5. Optionally, set the OrderStatus variable to cancelled by doing the following:

   1. Select the Variables tab, and click Add to invoke the Workflow Variable Assignment dialog box.

   2. From the Variable drop-down list, select OrderStatus.

   3. In the Expression field, enter "cancelled".

   4. Click OK to close the Workflow Variable Assignment dialog box. The variable and expression appear on the Variables tab.

6. Optionally, set the workflow comment to Order cancelled by doing the following:

   1. Select the Actions tab, and click Add to invoke the Add Action dialog box.

   2. Expand the Workflow Actions folder, select Set Workflow Comment, and click OK to invoke the Set Workflow Comment dialog box.

   3. In the Comment field, enter the expression "Order " + $OrderStatus.

   4. Click OK to exit the Set Workflow Comment dialog box. The Set Workflow Comment action appears on the Actions tab.

7. Click OK to exit the Event Properties dialog box.

Save the template definition and it is now ready to be run. The next section describes the Order Fulfillment workflow, which you imported predefined.