The following figure depicts the required flow of events:
When the bank receives the request to send funds from the sender (Sender’s Request), it validates the request (Validate Request), and rejects it if discovers a problem (Send Reject to Sender). If the request is valid, the bank informs the sender of its acceptance (Send Accept to Sender), notifies the recipient by email (Send Email To Recipient), and sets aside funds from the sender’s account (Allocate Funds). The first burst is complete, but several possible paths can follow:
- There is a time limit on the transfer, and if it expires the transfer is aborted.
- The sender may cancel the transfer.
- The sender’s bank may reject the recipient’s bank’s request to move the funds into the recipient’s account. The recipient may try again later.
- The sender’s bank may accept the recipient’s bank’s request to move the funds into the recipient’s account.
There are three events in the deferred choice, one for expiry (path 1), one for cancellation (path 2), and one for the recipient’s bank transfer request (paths 3 and 4). The logic for cancellation and expiry (headed by the events Sender’s Cancellation and Expired respectively) is identical: the process sends a cancellation email to the recipient (Send Email Recipient), informs the sender that the transfer is aborted (Send Abort to Sender), and restores the funds to the sender’s account (Restore Funds). In the transfer request path (starting with the event Recipient Bank’s Transfer Request), the sender bank validates the transfer (Validate Transfer) and sends the outcome to the recipient’s bank (Send Reject to Recipient Bank or Send Accept to Recipient Bank). If validation passes, the process also notifies the sender that the transfer is complete (Send Completion to Sender) and commits the funds it had earlier allocated (Commit Funds).
The sender’s bank’s process is long-running, typically spanning several days from start to finish. To build it using a short-running process engine, such as TIBCO’s BusinessWorks, we need to break it into smaller processes: one to handle the sender’s request to send funds, one to handle the recipient’s bank’s request to complete the transfer, one to handle the sender’s cancellation, one to handle expiry, and one to manage the overall event routing. In dividing the process into pieces, we lose the loop and deferred choice, but we add housekeeping responsibility to each piece.
The Router ProcessThe next figure shows the BusinessWorks process to handle the overall routing.
When it receives an inbound message on a JMS queue in GetEvent, the router process checks the event type to determine to which BusinessWorks process to route the event. There are three event types:
- Request: Sent by the account holder (known as the sender). Because this request starts the process, it must not contain a conversation identifier. If it does, the route process immediately logs the event as an error and discards it (Log Illegal Input). Otherwise, it queries the ProcessStarter table, in the step Check Starter Enabled, to verify that the email transfer process may be started by this type of event. (It checks that there is a record in the table that matches the given event type and process type.) If this check passes, the route process creates a unique conversation identifier (Set Conv ID) and calls the request process to handle the event (Call Request Process).
- Transfer: Sent by the recipient bank. The route process checks that the message has a conversation identifier. If it does, it calls the transfer process (Call Transfer Process) to handle the event. Otherwise, it logs the event and discards it (Log Illegal Input).
- Cancel: Sent by the sender or internally by the timer process (discussed further next). The route process checks that the message has a conversation identifier. If it does, it calls the cancellation process (Call Cancel Process) to handle the event. Otherwise, it logs the event and discards it (Log Illegal Input).
The process begins by creating a unique process identifier (Set Proc ID) and then validates the request (Validate Request). If the request is invalid, the process sends a rejection to the sender (Send Reject to Sender) and writes three records to the database:
- A record in the Process table (using Add Process Record Aborted) that sets the status of the instance to ABORTED. The process identifier is the one created in Set Proc ID.
- A log of the validation failure (using Add Audit Invalid Req) in the ProcessAudit table.
- A copy of the inbound message in the ProcessVariable table, using Add Variable Request. The earlier step RequestAsString converts the message from XML to string form.
The happy path, in which the request passes validation, contains three steps that we described earlier: Send Email Recipient, Send Accept to Sender, and Allocate Funds. It also creates the following records in the database:
- A record in the Process table (using Add Process Record Pending) about the instance, with a status of PENDING and the identifier created in Set Proc ID.
- An indication that the validation passed (using Add Audit Valid Request) in the ProcessAudit table.
- A copy of the inbound message (using Add Variable Request 2) in the ProcessVariable table.
- Three PendingEvent records, for transfer, expiry, and cancel respectively (using the steps Add Transfer Event, Add Expiry Event, Add Cancel Event). The records share a common choiceActivityID, and for each the isDone field is set to false.
- A record in the custom table EXState (using Add EXState), which extends the Process table with information specific to email transfers. The next figure shows the EXState table and its relationship to Process. The table adds one field to the mix, numRejects, which is initialized here to zero and is incremented each time the sender’s bank rejects the recipient’s bank’s transfer request.
When the happy path completes, the PendingEvents table has, among its contents, three records similar to the following:
According to this information, process instance 123 has three pending events, whose activityIDs are Cancel, Expiry, and Transfer respectively. These events are set in a single deferred choice, whose choiceActivityID is 1. None of these events has occurred, indicated by isDone being false. The Cancel and Transfer events are triggered by the inbound events types EX.Cancel and EX.Transfer respectively. The Expiry event does not have a triggering event type, but has a timeToFire configured for December 13, 2008; Expiry is a timed event.
When one of these events arrives, it is processed only if the isDone field is false; otherwise it is discarded. When it is processed, the isDone flag is set to true for all three events. Marking all three true in effect marks the whole deferred choice as complete, and prevents a second event from occurring.
The Transfer ProcessThe process that handles the recipient’s bank’s request for transfer is shown in the following figure.
The process begins immediately by querying the PendingEvent table to check that its event is still pending (FindEvent). If it has already been marked as completed, the process rejects the request (Send Reject to Recipient Bank Event Not Found) and quits. Assuming the event is permitted; the process marks the choice as completed (Remove Event) and validates the request (Validate). If validation passes, the process, as already discussed, sends an acceptance to the recipient’s bank (Send Accept Recipient Bank) and a completion notification to the sender (Send Completion Sender), commits the funds (Commit Funds), and then performs the following table updates:
- In the Process table, it sets the instance status to COMPLETED (using Close Process).
- It adds an entry to the ProcessAudit table (using Add Audit), indicating that the transfer succeeded.
- It saves the transfer request message to the ProcessVariable table. If a previous version of the message is already there, the process overwrites it (Update Variable); otherwise, it inserts a new message (Insert Variable).
- It restores the deferred choice (using Restore Event), setting isDone to false for each of the three events (Restore Event).
- It increments the numRejects field in the EXState table (Add Reject).
- It adds an entry to the ProcessAudit table (using Add Audit), indicating that the transfer failed.
- It saves the transfer request message to the ProcessVariable table, using the same logic as above.
The Cancellation ProcessThe process to handle cancellation, shown in the next figure, starts out much the same way.
The process first checks that the event is still pending (Find Event), and if so, disable the deferred choice (Remove Event). The process then notifies the sender and the recipient of the cancellation (Send Recipient Email and Send Abort to Sender), restores the funds (Restore Funds), and updates the tables as follows:
- It marks the status of the instance as ABORTED (Close Process).
- It adds an audit entry indicating cancellation (Add Audit).
- It saves the cancellation event to the ProcessVariable table (Save Variable).
The expiration process is not designed to handle the expiry of a single transfer. Rather, it scans the PendingEvents table for all expired transfers (Get Expired Transfers), and fires a cancellation event for each of them. The outer box labeled For Each Expired is a for loop that, for each record returned by the query, constructs a cancellation message (Create Cancellation Message) and launches a cancellation process (Launch Cancellation Process) to handle the message. It launches the process by sending a message on the JMS queue to which the routing process listens. The routing process, when it receives the event, routes it to the cancellation process. Thus, it is the cancellation process that will disable the deferred choice and abort the instance, not the timer process.
The timer process runs on a predefined schedule. The Poller step defines how often it runs (every fifteen minutes, for example). The timer process is not designed to run at the very moment a particular transfer expires. BusinessWorks manages the schedule internally; the schedule is not configured in our process state model.
For training on TIBCO IProcess mail us at [email protected]