Author: alex.guizar(a)jboss.com
Date: 2009-11-05 15:24:31 -0500 (Thu, 05 Nov 2009)
New Revision: 237
Added:
trunk/samples/quickstart/atm/img/
trunk/samples/quickstart/atm/img/atmAccountMenu.png
trunk/samples/quickstart/atm/img/atmAccountOps.png
trunk/samples/quickstart/atm/img/atmAccountUnit.png
trunk/samples/quickstart/atm/img/atmConnection.png
trunk/samples/quickstart/atm/img/atmMain.png
trunk/samples/quickstart/atm/img/atmNamePrompt.png
trunk/samples/quickstart/atm/img/atmParticipants.png
trunk/samples/quickstart/atm/img/atmStatus.png
trunk/samples/quickstart/atm/img/atmTicket.png
trunk/samples/quickstart/atm/img/atmWelcomeScreen.png
trunk/samples/quickstart/atm/img/atmWithdraw.png
trunk/samples/quickstart/atm/img/style.css
trunk/samples/quickstart/atm/readme.html
Log:
RIFTSAW-34: Readme for ATM example
Added: trunk/samples/quickstart/atm/img/atmAccountMenu.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmAccountMenu.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmAccountOps.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmAccountOps.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmAccountUnit.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmAccountUnit.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmConnection.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmConnection.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmMain.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmMain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmNamePrompt.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmNamePrompt.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmParticipants.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmParticipants.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmStatus.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmStatus.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmTicket.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmTicket.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmWelcomeScreen.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmWelcomeScreen.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/atmWithdraw.png
===================================================================
(Binary files differ)
Property changes on: trunk/samples/quickstart/atm/img/atmWithdraw.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/samples/quickstart/atm/img/style.css
===================================================================
--- trunk/samples/quickstart/atm/img/style.css (rev 0)
+++ trunk/samples/quickstart/atm/img/style.css 2009-11-05 20:24:31 UTC (rev 237)
@@ -0,0 +1,123 @@
+ * {
+ font-family: "Sans Serif";
+ font-size: 14px
+ }
+
+ A {
+ color: #0000CC;
+ }
+
+ A:active {
+ color: #0000CC;
+ }
+
+ A:visited {
+ color: #0000CC;
+ }
+
+ P, OL, UL, LI, DL, DT, DD, BLOCKQUOTE {
+ color: #000000;
+ }
+
+ TD, TH, SPAN {
+ color: #000000;
+ }
+
+ BLOCKQUOTE {
+ margin-right: 0px;
+ }
+
+
+ H1, H2, H3, H4, H5, H6 {
+ color: #003399;
+ font-weight: 500;
+ margin-top: 10px;
+ padding-top: 5px;
+ }
+
+ H1 { font-size: 150%; }
+ H2 { font-size: 140%; }
+ H3 { font-size: 110%; font-weight: bold; }
+ H4 { font-size: 110%; font-weight: bold;}
+ H5 { font-size: 100%; font-style: italic; }
+ H6 { font-size: 100%; font-style: italic; }
+
+ TABLE {
+ border-collapse: collapse;
+ border-spacing: 0;
+ /*border: 1px dashed #CCCCCC;*/
+ empty-cells: hide;
+ width: 100%
+ }
+
+ TD {
+ padding: 4pt;
+ }
+
+
+ TT {
+ font-size: 90%;
+ font-family: monospace;
+ color: #111111;
+ }
+
+ PRE {
+ font-size: 100%;
+ font-family: monospace;
+ padding: 5px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #CCCCCC;
+ background-color: #F4F4F4;
+ }
+
+ HR {
+ width: 100%;
+ height: 1px;
+ background-color: #CCCCCC;
+ border-width: 0px;
+ padding: 0px;
+ color: #CCCCCC;
+ }
+
+ .variablelist {
+ padding-top: 10;
+ padding-bottom: 10;
+ margin: 0;
+ }
+
+ .itemizedlist {
+ padding-top: 0;
+ padding-bottom: 0;
+ margin: 0;
+ list-style-type: disc;
+
+ }
+
+ .orderedlist{
+ padding-top: 0;
+ padding-bottom: 0;
+ margin: 0;
+ }
+
+ .term {
+ font-weight: bold;
+ }
+
+ .note
+ {
+ padding-bottom: 5px;
+ padding-left: 5px;
+ padding-right: 5px;
+ background-color: #FFFFCC;
+ }
+
+ .warning
+ {
+ padding-bottom: 5px;
+ padding-left: 5px;
+ padding-right: 5px;
+ background-color: #FBDADA;
+ }
+
+
Property changes on: trunk/samples/quickstart/atm/img/style.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/samples/quickstart/atm/readme.html
===================================================================
--- trunk/samples/quickstart/atm/readme.html (rev 0)
+++ trunk/samples/quickstart/atm/readme.html 2009-11-05 20:24:31 UTC (rev 237)
@@ -0,0 +1,1099 @@
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
+ <title>ATM Example</title><link rel="stylesheet"
href="img/style.css" type="text/css"><meta
name="generator" content="DocBook XSL Stylesheets
V1.65.1"></head><body alink="#0000ff" bgcolor="white"
text="black" vlink="#840084" link="#0000ff"><div
class="chapter" lang="en"><div
class="titlepage"><h2 class="title"><a
name="tutorial.atm"></a>ATM Example</h2></div><p>This
example is about a process that manages the interaction between an
+ automated teller machine and the information system of a bank. The process drives
ATMs in
+ performing the operations listed below.</p><div
class="orderedlist"><ol type="1"><li><p>Connect
to the server</p></li><li><p>Log a customer
on</p></li><li><p>Query the state of the
session</p></li><li><p>Obtain the account
balance</p></li><li><p>Withdraw and deposit
funds</p></li><li><p>Log the customer
off</p></li><li><p>Disconnect from the
server</p></li></ol></div><p>Not all operations are
available at the same time. Most require another operation to
+ complete for becoming available.</p><p>Four different modules participate
in this orchestration. The picture below shows
+ the relationships between modules plus the deployment configuration.</p><div
class="figure"><a
name="tutorial.atm.participants"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="523"><tbody><tr style="height: 171px;"><td
align="center"><img src="img/atmParticipants.png"
alt="Participants of the ATM process"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 1. Participants of the ATM
process</b></p></div><p>Initially, the teller machine connects to
the front end service. Inside the bank,
+ the front end contacts the ticket issuer module to generate a number that uniquely
+ identifies the teller. Subsequent message exchanges with the bank indicate the
ticket
+ number.</p><p>When an account holder comes and authenticates him or
herself, the teller asks the
+ front end to initiate a customer session. The front end resorts to the account system
for
+ checking access rights.</p><p>Once access is granted, the account holder
looks at the account balance, deposits/withdraws
+ funds or terminates the session. Because a given customer is not supposed to use
multiple ATM at
+ the same time, these exchanges carry the customer credentials instead of the
ticket.</p><p>The front end contacts the account system as required to ensure
the balance is accurate.
+ Even tough the account system allows negative balances for the sake of other credit
operations,
+ ATMs do not dispense cash on credit. The front end must ensure enough funds exist and
reject
+ withdrawals that would result in a negative balance.</p><div
class="section" lang="en"><div class="section"
lang="en"><div class="titlepage"><h3
class="title"><a name="tutorial.atm.def.bpel"></a>BPEL
process</h3></div><p>First of all, an explanation of the top level
elements. The partner link <tt class="varname">
+ atm</tt> represents the relationship between a teller machine and the
process.
+ The process plays the <span
class="emphasis"><em>FrontEnd</em></span> role, as the
attribute <tt class="literal">
+ myRole</tt> indicates. Similarly, <tt
class="varname">ticket</tt> links the process to
+ the ticket issuer service, which assumes the <span
class="emphasis"><em>TicketIssuer</em></span> role.
+ Account operations are available through the <tt
class="varname">account</tt> partner link.
+ Neither <tt class="varname">ticket</tt> nor <tt
class="varname">account</tt> place any responsibility
+ on the process, hence they specify <tt
class="literal">partnerRole</tt> but not <tt
class="literal">
+ myRole</tt>.</p><p>The variables <tt
class="varname">connected</tt> and <tt
class="varname">logged</tt> are
+ status flags. The <tt class="varname">atm</tt> correlation
set distinguishes ATMs from each
+ other based on the ticket number property.</p><pre
class="programlisting"><process name="AtmFrontEnd"
targetNamespace="http://jbpm.org/examples/atm"
+
xmlns:acc="http://jbpm.org/examples/account"
xmlns:atm="http://jbpm.org/examples/atm"
+
xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
+
xmlns:tic="http://jbpm.org/examples/ticket"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <import
importType="http://schemas.xmlsoap.org/wsdl/"
location="atm.wsdl"
+
namespace="http://jbpm.org/examples/atm" />
+ <import
importType="http://schemas.xmlsoap.org/wsdl/"
location="interface/frontend.wsdl"
+
namespace="http://jbpm.org/examples/atm" />
+ <import
importType="http://schemas.xmlsoap.org/wsdl/"
location="interface/ticket.wsdl"
+
namespace="http://jbpm.org/examples/ticket" />
+ <import
importType="http://schemas.xmlsoap.org/wsdl/"
location="interface/account.wsdl"
+
namespace="http://jbpm.org/examples/account" />
+
+ <partnerLinks>
+ <partnerLink myRole="FrontEnd" name="atm"
partnerLinkType="atm:Atm-Front">
+ <documentation>relationship with the
ATM</documentation>
+ </partnerLink>
+ </partnerLinks>
+
+ <variables>
+ <variable name="connected" type="xsd:boolean">
+ <documentation>ATM connection flag</documentation>
+ </variable>
+ <variable name="logged" type="xsd:boolean">
+ <documentation>customer access flag</documentation>
+ </variable>
+ <variable messageType="tic:ticketMessage"
name="ticketMsg">
+ <documentation>ticket number wrapper</documentation>
+ </variable>
+ </variables>
+
+ <correlationSets>
+ <correlationSet name="atmInteraction"
properties="atm:ticketId">
+ <documentation>conversation with a connected
ATM</documentation>
+ </correlationSet>
+ </correlationSets>
+
+ ...
+
+</process></pre><p>Let's move on to the control flow. The
next figure is the outlook of the
+ ATM front end process.</p><div class="figure"><a
name="tutorial.atm.main"></a><div class="mediaobject"
align="center"><table summary="manufactured viewport for HTML
img" border="0" cellpadding="0" cellspacing="0"
width="176"><tbody><tr style="height: 252px;"><td
align="center"><img src="img/atmMain.png" alt="ATM main
sequence"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 2. ATM main
sequence</b></p></div><p>We define a main sequence for handling
the life cycle of an ATM connection. It consists
+ of these activities: create a ticket, initialize the status flags and handle the
new
+ connection.</p><pre class="programlisting"><sequence
name="MainSeq">
+
+ <scope name="TicketCreationUnit">
+ ...
+ </scope>
+
+ <assign name="InitializeStatus" validate="no">
+ <documentation>initialize the status
flags</documentation>
+ <copy>
+ <from>true()</from>
+ <to variable="connected" />
+ </copy>
+ <copy>
+ <from>false()</from>
+ <to variable="logged" />
+ </copy>
+ </assign>
+
+ <scope name="ConnectionUnit">
+ <documentation>handle the ATM connection</documentation>
+ ...
+ </scope>
+
+</sequence></pre><p>Each scope delimits a nested unit of work,
with its own variables, correlation sets
+ and fault/event handlers. They help break a long and complex process into
manageable
+ pieces. Let us take a closer look at the <tt
class="literal">TicketCreationUnit</tt></p>.
+
+ <div class="figure"><a
name="tutorial.atm.ticket"></a><div class="mediaobject"
align="center"><table summary="manufactured viewport for HTML
img" border="0" cellpadding="0" cellspacing="0"
width="210"><tbody><tr style="height: 207px;"><td
align="center"><img src="img/atmTicket.png" alt="Ticket
creation unit"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 3. Ticket creation
unit</b></p></div><p>The start point is to accept a connection
from some ATM, which results in the
+ creation of a new process instance. Next, the process contacts a partner service
to
+ create a new ticket, and then returns the ticket number to the ATM. Observe that
+ the activity <tt class="literal">CreateTicket</tt>
initiates the correlation set <tt class="literal">
+ atmInteraction</tt>. Future incoming messages containing this ticket number
will be
+ delivered to the newly created process instance.</p><pre
class="programlisting"><scope
name="TicketCreationUnit">
+
+ <partnerLinks>
+ <partnerLink name="ticket"
partnerLinkType="atm:Front-Ticket" partnerRole="TicketIssuer">
+ <documentation>relationship with the ticket
issuer</documentation>
+ </partnerLink>
+ </partnerLinks>
+
+ <variables>
+ <variable messageType="tic:ticketRequest"
name="ticketReq">
+ <documentation>ATM connection request</documentation>
+ </variable>
+ <variable messageType="atm:connectRequest"
name="connectReq">
+ <documentation>ticket creation request</documentation>
+ </variable>
+ </variables>
+
+ <sequence name="TicketCreationSeq">
+
+ <receive createInstance="yes" name="AcceptConnection"
operation="connect"
+ partnerLink="atm" portType="atm:FrontEnd"
variable="connectReq">
+ <documentation>receive a connection
request</documentation>
+ </receive>
+
+ <invoke inputVariable="ticketReq" name="CreateTicket"
operation="createTicket"
+ outputVariable="ticketMsg" partnerLink="ticket"
portType="tic:TicketIssuer">
+ <documentation>generate a ticket
number</documentation>
+ <correlations>
+ <correlation initiate="yes" pattern="in"
set="atmInteraction" />
+ </correlations>
+ </invoke>
+
+ <reply name="SendTicketNumber" operation="connect"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="ticketMsg">
+ <documentation>send the ticket number back to the
ATM</documentation>
+ <correlations>
+ <correlation initiate="no" set="atmInteraction"
/>
+ </correlations>
+ </reply>
+
+ </sequence>
+
+</scope></pre><p>The diagram that follows is a close look at
the control flow of the <tt class="literal">
+ connectionUnit</tt>:</p><div class="figure"><a
name="tutorial.atm.connection"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="381"><tbody><tr style="height: 250px;"><td
align="center"><img src="img/atmConnection.png"
alt="Connection unit"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 4. Connection
unit</b></p></div><p>The local variables <tt
class="varname">logOnReq</tt> and <tt
class="varname">statusRsp</tt>
+ are placeholders for message exchanges.</p><p>Connection handling
consists of listening for ATM requests and
+ processing them one at a time. This is an iterative behavior. The
+ <tt class="literal">connectionLoop</tt> activity causes the
front end to keep taking
+ requests as long as the <tt class="varname">connected</tt>
flag stays turned on.</p><p>At this point, the process accepts any of the
following two requests: initiate a
+ customer session or terminate the connection. The <tt
class="literal">connectionMenu</tt>
+ structure performs the activity associated with the first request to
arrive.</p><pre class="programlisting"><scope
name="ConnectionUnit">
+ <documentation>handle the ATM connection</documentation>
+
+ <variables>
+ <variable messageType="atm:logOnRequest"
name="logOnReq">
+ <documentation>customer log on request</documentation>
+ </variable>
+ <variable messageType="atm:statusResponse"
name="statusRsp">
+ <documentation>connection status
response</documentation>
+ </variable>
+ </variables>
+
+ <while name="ConnectionLoop">
+ <documentation>accept ATM requests, one at a
time</documentation>
+ <condition>$connected</condition>
+
+ <pick name="ConnectionMenu">
+ <documentation>listen for either disconnect or log on
request</documentation>
+
+ <onMessage operation="disconnect" partnerLink="atm"
portType="atm:FrontEnd"
+ variable="ticketMsg">
+ ...
+ </onMessage>
+
+ <onMessage operation="logOn" partnerLink="atm"
portType="atm:FrontEnd"
+ variable="logOnReq">
+ ...
+ </onMessage>
+
+ </pick>
+
+ </while>
+
+</scope></pre><div class="itemizedlist"><ul
type="disc"><li><p><span
class="emphasis"><em>logOn</em></span>: the <tt
class="literal">AccountUnit</tt> scope
+ encapsulates the access to the account belonging to a registered
customer.</p><pre class="programlisting"><onMessage
operation="logOn" partnerLink="atm" portType="atm:FrontEnd"
+ variable="logOnReq">
+
+ <correlations>
+ <correlation initiate="no" set="atmInteraction" />
+ </correlations>
+
+ <scope name="AccountUnit">
+ <documentation>handle account access</documentation>
+ ...
+ </scope>
+
+</onMessage></pre></li><li><p><span
class="emphasis"><em>disconnect</em></span>: <tt
class="literal">setDisconnected</tt> turns off the
+ <tt class="varname">connected</tt> flag, causing the
<tt class="literal">connectionLoop</tt> to
+ break shortly after.</p><pre
class="programlisting"><onMessage operation="disconnect"
partnerLink="atm" portType="atm:FrontEnd"
+ variable="ticketMsg">
+
+ <correlations>
+ <correlation initiate="no" set="atmInteraction" />
+ </correlations>
+
+ <assign name="SetDisconnected" validate="no">
+ <documentation>turn off connected flag</documentation>
+ <copy>
+ <from>false()</from>
+ <to variable="connected" />
+ </copy>
+ </assign>
+
+</onMessage></pre></li></ul></div><p>To spice
up the process, <tt class="literal">ConnectionUnit</tt> defines an
event for
+ handling status requests on par with the primary activity. The <tt
class="literal">status
+ </tt> event lets the ATM query the connection status as long as the
+ scope is active.</p><div class="figure"><a
name="tutorial.atm.status"></a><div class="mediaobject"
align="center"><table summary="manufactured viewport for HTML
img" border="0" cellpadding="0" cellspacing="0"
width="584"><tbody><tr style="height: 349px;"><td
align="center"><img src="img/atmStatus.png" alt="Status
event"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 5. Status
event</b></p></div><p>The following snippet shows the event
handling code. The status flags are queried
+ to determine the status of the connection.</p><pre
class="programlisting"><eventHandlers>
+ <onEvent messageType="tic:ticketMessage" operation="status"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="ticketMsg">
+
+ <correlations>
+ <correlation initiate="no" set="atmInteraction"
/>
+ </correlations>
+
+ <scope name="StatusUnit">
+
+ <sequence name="StatusSeq">
+
+ <if name="StatusDecision">
+
+ <condition>$logged</condition>
+ <assign name="SetStatusLogged"
validate="no">
+ <copy>
+ <from>'logged'</from>
+ <to part="status" variable="statusRsp"
/>
+ </copy>
+ </assign>
+
+ <elseif>
+ <condition>$connected</condition>
+ <assign name="SetStatusConnected"
validate="no">
+ <copy>
+ <from>'connected'</from>
+ <to part="status" variable="statusRsp"
/>
+ </copy>
+ </assign>
+ </elseif>
+
+ <else>
+ <assign name="Assign" validate="no">
+ <copy>
+ <from>'disconnected'</from>
+ <to part="status" variable="statusRsp"
/>
+ </copy>
+ </assign>
+ </else>
+
+ </if>
+
+ <reply name="SendStatus" operation="status"
partnerLink="atm" portType="atm:FrontEnd"
+ variable="statusRsp" />
+
+ </sequence>
+
+ </scope>
+
+ </onEvent>
+
+</eventHandlers></pre><p>The <tt
class="literal">AccountUnit</tt> scope lies at the core of the ATM
front end
+ process. It encapsulates the logic to serve account holder requests. The next
+ picture summarizes its control flow.</p><div
class="figure"><a
name="tutorial.atm.account.unit"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="481"><tbody><tr style="height: 455px;"><td
align="center"><img src="img/atmAccountUnit.png"
alt="Account unit"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 6. Account
unit</b></p></div><p>The scope declares a number of local
variables for incoming and outgoing messages.
+ Apart from them, one variable, <tt
class="varname">newBalance</tt>, stores the
+ result of evaluating the remaining amount after a
withdrawal.</p><p>One correlation set, <tt
class="varname">customerInteraction</tt>, distinguishes logged
+ account holders from each other through the customer name property. One feature
of
+ correlation sets opens a potential pitfall. In order to ensure consistency
constraints,
+ correlation sets are immutable. However, the ATM most likely will serve a
different customer
+ at each iteration. For this reason, the <tt
class="varname">customerInteraction</tt> declaration
+ appears inside the loop rather than outside. In this way, the set can assume
different
+ values in every new session.</p><p>Account handling works as follows.
The front end must verify the customer
+ actually holds an account. Verification is outside the responsibilities of the
process;
+ it is a function of the bank account system. Therefore, the front end invokes
the
+ account system to check the customer access privilege. If the system grants
+ access, the front end turns on the <tt
class="varname">logged</tt> flag and acknowledges the
+ log on request. Conversely, when the system denies access, the front end sends a
+ <tt class="literal">unauthorizedAccess</tt> back to the
ATM. It leaves the <tt class="varname">logged
+ </tt> flag off so that the account access ends
immediately.</p><p>Note that the aforementioned fault appears in the WSDL
definition of the operation.
+ If it did not appear, jBPM BPEL would report an error at deployment
time.</p><pre class="programlisting"><portType
name="FrontEnd">
+ ...
+ <operation name="logOn">
+ <input message="tns:logOnRequest" />
+ <output message="tns:logOnResponse" />
+ <fault name="<span
class="bold"><b>unauthorizedAccess</b></span>"
message="tns:unauthorizedAccess" />
+ </operation>
+ ...
+</portType></pre><p>After completing the <tt
class="methodname">logOn</tt> operation either way,
+ the process enters a loop that accepts account requests one at a time.
+ The next section will describe the logic inside <tt
class="literal">accountLoop</tt>.</p><pre
class="programlisting"><scope name="AccountUnit">
+ <documentation>handle account access</documentation>
+
+ <partnerLinks>
+ <partnerLink name="account"
partnerLinkType="atm:Front-Account"
+ partnerRole="AccountSystem">
+ <documentation>relationship with the account
system</documentation>
+ </partnerLink>
+ </partnerLinks>
+
+ <variables>
+ <variable messageType="acc:accessMessage"
name="accessMsg">
+ <documentation>access check response</documentation>
+ </variable>
+ <variable messageType="acc:customerMessage"
name="customerMsg">
+ <documentation>customer name wrapper</documentation>
+ </variable>
+ <variable messageType="atm:logOnResponse"
name="logOnRsp">
+ <documentation>customer access
acknowledgment</documentation>
+ </variable>
+ <variable messageType="atm:unauthorizedAccess"
name="unauthorizedAccess">
+ <documentation>customer access fault</documentation>
+ </variable>
+ <variable messageType="acc:balanceMessage"
name="balanceMsg">
+ <documentation>account balance wrapper</documentation>
+ </variable>
+ <variable messageType="atm:balanceChange"
name="balanceChange">
+ <documentation>balance change request</documentation>
+ </variable>
+ <variable messageType="acc:accountOperation"
name="accountOperation">
+ <documentation>account system operation
request</documentation>
+ </variable>
+ <variable name="newBalance" type="xsd:double">
+ <documentation>resulting balance after
withdrawal</documentation>
+ </variable>
+ <variable messageType="atm:insufficientFunds"
name="insufficientFunds">
+ <documentation>withdraw fault</documentation>
+ </variable>
+ </variables>
+
+ <correlationSets>
+ <correlationSet name="customerInteraction"
properties="atm:customerId">
+ <documentation>conversation with a logged
customer</documentation>
+ </correlationSet>
+ </correlationSets>
+
+ <sequence name="AccountSeq">
+
+ <assign name="PrepareAccessCheck" validate="no">
+ <documentation>populate access check
request</documentation>
+ <copy>
+ <from part="customerName" variable="logOnReq"
/>
+ <to part="customerName" variable="customerMsg"
/>
+ </copy>
+ </assign>
+
+ <invoke inputVariable="customerMsg" name="CheckAccess"
operation="checkAccess"
+ outputVariable="accessMsg" partnerLink="account"
portType="acc:AccountSystem">
+ <documentation>check account access
privilege</documentation>
+ <correlations>
+ <correlation initiate="yes" pattern="out"
set="customerInteraction" />
+ </correlations>
+ </invoke>
+
+ <if name="AccessDecision">
+ <documentation>decide outcome of customer access
request</documentation>
+ <condition>$accessMsg.granted</condition>
+
+ <sequence name="AccessGrantedSeq">
+ <documentation>grant customer access</documentation>
+
+ <assign name="SetLoggedOn" validate="no">
+ <documentation>turn on logged flag</documentation>
+ <copy>
+ <from>true()</from>
+ <to variable="logged" />
+ </copy>
+ </assign>
+
+ <reply name="GrantAccess" operation="logOn"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="logOnRsp">
+ <documentation>send acknowledgment back to
ATM</documentation>
+ </reply>
+
+ </sequence>
+
+ <else>
+
+ <sequence name="AccessDeniedSeq">
+ <documentation>deny customer
access</documentation>
+
+ <assign name="PrepareAccessDenial"
validate="no">
+ <documentation>populate access
fault</documentation>
+ <copy>
+ <from part="customerName" variable="logOnReq"
/>
+ <to part="detail"
variable="unauthorizedAccess">
+ <query>customerName</query>
+ </to>
+ </copy>
+ </assign>
+
+ <reply name="DenyAccess" operation="logOn"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="unauthorizedAccess"
+ faultName="atm:unauthorizedAccess">
+ <documentation>send fault back to
ATM</documentation>
+ </reply>
+
+ </sequence>
+
+ </else>
+
+ </if>
+
+ <while name="AccountLoop">
+ ...
+ </while>
+
+ </sequence>
+
+</scope></pre><p>Inside <tt
class="literal">AccountLoop</tt>, the process waits for one of four
+ possible requests. These requests appear as <tt
class="literal">onMessage</tt> branches
+ of <tt class="literal">AccountMenu</tt>.</p><div
class="figure"><a
name="tutorial.atm.account.menu"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="725"><tbody><tr style="height: 133px;"><td
align="center"><img src="img/atmAccountMenu.png"
alt="Account menu"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 7. Account
menu</b></p></div><p>The above diagram represents the following
structure.</p><pre class="programlisting"><while
name="AccountLoop">
+ <documentation>accept account requests, one at a
time</documentation>
+ <condition>$logged</condition>
+
+ <pick name="AccountMenu">
+
+ <onMessage operation="logOff">
+ ...
+ </onMessage>
+
+ <onMessage operation="getBalance">
+ ...
+ </onMessage>
+
+ <onMessage operation="deposit">
+ ...
+ </onMessage>
+
+ <onMessage operation="withdraw">
+ ...
+ </onMessage>
+
+ <onAlarm for="'PT2M'">
+ ...
+ </onAlarm>
+
+ </pick>
+
+</while></pre><div class="itemizedlist"><ul
type="disc"><li><p><span
class="emphasis"><em>logOff</em></span>: <tt
class="literal">setLoggedOff</tt>
+ turns off the <tt class="varname">logged</tt> flag to
break the
+ <tt class="literal">customerLoop</tt> and terminate the
customer access.</p><pre class="programlisting"><onMessage
operation="logOff" partnerLink="atm"
+ portType="atm:FrontEnd" variable="customerMsg">
+
+ <correlations>
+ <correlation set="customerInteraction" />
+ </correlations>
+
+ <assign name="SetLoggedOff" validate="no">
+ <documentation>turn off logged flag</documentation>
+ <copy>
+ <from>false()</from>
+ <to variable="logged" />
+ </copy>
+ </assign>
+
+</onMessage></pre></li><li><p><span
class="emphasis"><em>getBalance</em></span>: the <tt
class="literal">BalanceSeq</tt>
+ queries the account system for the current balance and hands that back to
+ the ATM.</p><pre
class="programlisting"><onMessage operation="getBalance"
partnerLink="atm" portType="atm:FrontEnd"
+ variable="customerMsg">
+
+ <correlations>
+ <correlation initiate="no" set="customerInteraction"
/>
+ </correlations>
+
+ <sequence name="BalanceSeq">
+
+ <invoke inputVariable="customerMsg" name="QueryBalance"
+ operation="queryBalance" outputVariable="balanceMsg"
partnerLink="account"
+ portType="acc:AccountSystem">
+ <documentation>get current account
balance</documentation>
+ </invoke>
+
+ <reply name="TellBalance" operation="getBalance"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="balanceMsg">
+ <documentation>return balance to ATM</documentation>
+ </reply>
+
+ </sequence>
+
+</onMessage></pre></li><li><p><span
class="emphasis"><em>deposit</em></span>: the <tt
class="literal">DepositSeq</tt>
+ posts the positive update to the account system. The front end process gets
the
+ new balance in return and makes it available to the ATM.</p><pre
class="programlisting"><onMessage operation="deposit"
partnerLink="atm" portType="atm:FrontEnd"
+ variable="balanceChange">
+
+ <correlations>
+ <correlation initiate="no" set="customerInteraction"
/>
+ </correlations>
+
+ <sequence name="DepositSeq">
+
+ <assign name="PrepareDeposit" validate="no">
+ <documentation>populate balance update
request</documentation>
+ <copy>
+ <from part="customerName" variable="balanceChange"
/>
+ <to part="body" variable="accountOperation">
+ <query>customerName</query>
+ </to>
+ </copy>
+ <copy>
+ <from part="amount" variable="balanceChange"
/>
+ <to part="body" variable="accountOperation">
+ <query>amount</query>
+ </to>
+ </copy>
+ </assign>
+
+ <invoke inputVariable="accountOperation"
name="UpdateBalance"
+ operation="updateBalance" outputVariable="balanceMsg"
+ partnerLink="account" portType="acc:AccountSystem">
+ <documentation>post positive balance
update</documentation>
+ <correlations>
+ <correlation initiate="no" pattern="out"
set="customerInteraction" />
+ </correlations>
+ </invoke>
+
+ <reply name="TellNewBalance" operation="deposit"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="balanceMsg">
+ <documentation>make new balance available to
ATM</documentation>
+ </reply>
+
+ </sequence>
+
+</onMessage></pre></li><li><p><span
class="emphasis"><em>withdraw</em></span>: because withdraw
is most involved account operation,
+ it appears in a separate diagram.</p><div
class="figure"><a
name="tutorial.atm.withdraw"></a><div class="mediaobject"
align="center"><table summary="manufactured viewport for HTML
img" border="0" cellpadding="0" cellspacing="0"
width="446"><tbody><tr style="height: 437px;"><td
align="center"><img src="img/atmWithdraw.png" alt="Withdraw
sequence"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 8. Withdraw
sequence</b></p></div><p><tt
class="literal">WithdrawSeq</tt> first queries the account system for
the
+ current balance. Later, it evaluates the amount that would remain in the
account
+ after the negative update.</p><pre
class="programlisting"><onMessage operation="withdraw"
partnerLink="atm" portType="atm:FrontEnd"
+ variable="balanceChange">
+
+ <correlations>
+ <correlation initiate="no" set="customerInteraction"
/>
+ </correlations>
+
+ <sequence name="WithdrawSeq">
+
+ <assign name="PrepareBalanceQuery" validate="no">
+ <documentation>populate balance query
request</documentation>
+ <copy>
+ <from part="customerName" variable="balanceChange"
/>
+ <to part="customerName" variable="customerMsg"
/>
+ </copy>
+ </assign>
+
+ <invoke inputVariable="customerMsg" name="QueryBalance"
+ operation="queryBalance" outputVariable="balanceMsg"
partnerLink="account"
+ portType="acc:AccountSystem">
+ <documentation>get current account
balance</documentation>
+ <correlations>
+ <correlation initiate="no" pattern="out"
set="customerInteraction" />
+ </correlations>
+ </invoke>
+
+ <assign name="EvaluateNewBalance" validate="no">
+ <documentation>
+ evaluate amount that would remain in account
+ </documentation>
+ <copy>
+ <from>$balanceMsg.balance -
$balanceChange.amount</from>
+ <to variable="newBalance" />
+ </copy>
+ </assign>
+
+ <if name="BalanceDecision">
+ ...
+ </if>
+
+ </sequence>
+
+</onMessage></pre><p>If there are enough funds, the <tt
class="literal">PositiveBalanceSeq</tt>
+ posts the negative update to the account system, gets the new balance and
returns
+ that to the ATM.</p><pre
class="programlisting"><if name="BalanceDecision">
+ <documentation>decide outcome of withdraw
request</documentation>
+ <condition>$newBalance >= 0.0</condition>
+
+ <sequence name="PositiveBalanceSeq">
+ <documentation>accept withdrawal</documentation>
+
+ <assign name="PrepareWithdraw" validate="no">
+ <documentation>populate balance update
request</documentation>
+ <copy>
+ <from part="customerName" variable="balanceChange"
/>
+ <to part="body" variable="accountOperation">
+ <query>customerName</query>
+ </to>
+ </copy>
+ <copy>
+ <from>-$balanceChange.amount</from>
+ <to part="body" variable="accountOperation">
+ <query>amount</query>
+ </to>
+ </copy>
+ </assign>
+
+ <invoke inputVariable="accountOperation"
name="UpdateBalance"
+ operation="updateBalance" outputVariable="balanceMsg"
+ partnerLink="account" portType="acc:AccountSystem">
+ <documentation>post negative balance
update</documentation>
+ <correlations>
+ <correlation initiate="no" pattern="out"
set="customerInteraction" />
+ </correlations>
+ </invoke>
+
+ <reply name="TellNewBalance" operation="withdraw"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="balanceMsg">
+ <documentation>return new balance to
ATM</documentation>
+ </reply>
+
+ </sequence>
+
+ <else>
+ ...
+ </else>
+
+</if></pre><p>Otherwise, the <tt
class="literal">negativeBalanceSequence</tt> rejects the withdraw
+ by returning a fault to the ATM. The update is not posted.</p><pre
class="programlisting"><else>
+
+ <sequence name="NegativeBalanceSeq">
+ <documentation>reject withdrawal</documentation>
+
+ <assign name="PrepareRejection" validate="no">
+ <documentation>populate withdraw fault</documentation>
+ <copy>
+ <from part="customerName" variable="balanceChange"
/>
+ <to part="detail"
variable="insufficientFunds">
+ <query>customerName</query>
+ </to>
+ </copy>
+ <copy>
+ <from part="balance" variable="balanceMsg" />
+ <to part="detail"
variable="insufficientFunds">
+ <query>amount</query>
+ </to>
+ </copy>
+ </assign>
+
+ <reply name="RejectWithdraw" operation="withdraw"
partnerLink="atm"
+ portType="atm:FrontEnd" variable="insufficientFunds"
+ faultName="atm:insufficientFunds">
+ <documentation>return fault to ATM</documentation>
+ </reply>
+
+ </sequence>
+
+</else></pre></li><li><p>The final <tt
class="literal">onAlarm</tt> branch terminates the customer session
after
+ two minutes, if no account request arrives earlier.</p><pre
class="programlisting"><onAlarm>
+ <for>'PT2M'</for>
+
+ <assign name="SetLoggedOff" validate="no">
+ <documentation>
+ turn off logged flag after a period of inactivity
+ </documentation>
+ <copy>
+ <from>false()</from>
+ <to variable="logged" />
+ </copy>
+ </assign>
+
+</onAlarm></pre></li></ul></div></div><div
class="section" lang="en"><div
class="titlepage"><h3 class="title"><a
name="tutorial.atm.def.wsdl"></a>WSDL
interfaces</h3></div><p>To better organize WSDL definitions, the process
uses four interface documents for
+ the ATM service.</p><p>The first document, <tt
class="literal">ticket.wsdl</tt> contains the interface
+ of the ticket issuer service. Here we assume this service is already deployed
+ somewhere and the WSDL definitions came from there.</p><pre
class="programlisting"><definitions
targetNamespace="http://jbpm.org/examples/ticket"
+
xmlns:tns="http://jbpm.org/examples/ticket"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <message name="ticketRequest">
+ <documentation>ticket creation request</documentation>
+ </message>
+
+ <message name="ticketMessage">
+ <documentation>ticket number wrapper</documentation>
+ <part name="ticketNo" type="xsd:int" />
+ </message>
+
+ <portType name="TicketIssuer">
+ <documentation>interface to ticket issuer
service</documentation>
+
+ <operation name="createTicket">
+ <documentation>generate a ticket number, distinct from previous
calls</documentation>
+ <input message="tns:ticketRequest" />
+ <output message="tns:ticketMessage" />
+ </operation>
+
+ </portType>
+
+</definitions></pre><p>Another document, <tt
class="literal">account.wsdl</tt> describes the
+ published functions of the account system. One custom XML Schema definition,
+ <tt class="literal">AccountOperation</tt>, introduces a
data transfer type for
+ account operations.</p><pre
class="programlisting"><definitions
targetNamespace="http://jbpm.org/examples/account"
+
xmlns:tns="http://jbpm.org/examples/account"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <types>
+
+ <schema
targetNamespace="http://jbpm.org/examples/account"
+
xmlns="http://www.w3.org/2001/XMLSchema">
+
+ <complexType name="AccountOperation">
+ <annotation>
+ <documentation>account data transfer
type</documentation>
+ </annotation>
+ <sequence>
+ <element name="customerName" type="xsd:string"
/>
+ <element name="amount" type="xsd:double" />
+ </sequence>
+ </complexType>
+
+ </schema>
+
+ </types>
+
+ <message name="customerMessage">
+ <documentation>customer name wrapper</documentation>
+ <part name="customerName" type="xsd:string" />
+ </message>
+
+ <message name="accessMessage">
+ <documentation>access check response</documentation>
+ <part name="granted" type="xsd:boolean" />
+ </message>
+
+ <message name="balanceMessage">
+ <documentation>account balance wrapper</documentation>
+ <part name="balance" type="xsd:double" />
+ </message>
+
+ <message name="accountOperation">
+ <documentation>account operation request</documentation>
+ <part name="body" type="tns:AccountOperation" />
+ </message>
+
+ <portType name="AccountSystem">
+ <documentation>published account
functions</documentation>
+
+ <operation name="checkAccess">
+ <documentation>tell whether a customer has an active
account</documentation>
+ <input message="tns:customerMessage" />
+ <output message="tns:accessMessage" />
+ </operation>
+
+ <operation name="queryBalance">
+ <documentation>retrieve the balance of an
account</documentation>
+ <input message="tns:customerMessage" />
+ <output message="tns:balanceMessage" />
+ </operation>
+
+ <operation name="updateBalance">
+ <documentation>increase/decrease the balance of an
account</documentation>
+ <input message="tns:accountOperation" />
+ <output message="tns:balanceMessage" />
+ </operation>
+
+ </portType>
+
+</definitions></pre><p>The third document, <tt
class="literal">frontend.wsdl</tt>, contains the interface
+ the process presents to ATMs. Because it reuses a number of messages from the
ticket issuer
+ and the account system, it imports the WSDL documents that describe these
services.</p><p>Some custom XML schema definitions appear in the <tt
class="literal">types</tt> section.
+ They define the elements that the front end interface uses to inform ATMs of
business
+ logic errors and the types that characterize those
elements.</p><p>WSDL messages, in terms of the foregoing definitions and
predefined schema types,
+ define the exchange format between the ATM and the bank front end. Finally,
+ the <tt class="literal">FrontEnd</tt> port type lists the
bank functions available to ATMs.</p><pre
class="programlisting"><definitions
targetNamespace="http://jbpm.org/examples/atm"
+
xmlns:tns="http://jbpm.org/examples/atm"
+
xmlns:tic="http://jbpm.org/examples/ticket"
xmlns:acc="http://jbpm.org/examples/account"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <import
namespace="http://jbpm.org/examples/ticket"
location="ticket.wsdl" />
+ <import
namespace="http://jbpm.org/examples/account"
location="account.wsdl" />
+
+ <types>
+
+ <schema
targetNamespace="http://jbpm.org/examples/atm"
+
xmlns="http://www.w3.org/2001/XMLSchema">
+
+ <complexType name="UnauthorizedAccess">
+ <sequence>
+ <element name="customerName" type="xsd:string"
/>
+ </sequence>
+ </complexType>
+
+ <element name="unauthorizedAccess"
type="tns:UnauthorizedAccess" />
+
+ <complexType name="InsufficientFunds">
+ <sequence>
+ <element name="customerName" type="xsd:string"
/>
+ <element name="amount" type="xsd:double" />
+ </sequence>
+ </complexType>
+
+ <element name="insufficientFunds"
type="tns:InsufficientFunds" />
+
+ </schema>
+
+ </types>
+
+ <message name="connectRequest" />
+
+ <message name="logOnRequest">
+ <part name="ticketNo" type="xsd:int" />
+ <part name="customerName" type="xsd:string" />
+ </message>
+
+ <message name="logOnResponse" />
+
+ <message name="statusResponse">
+ <part name="status" type="xsd:string" />
+ </message>
+
+ <message name="balanceChange">
+ <part name="customerName" type="xsd:string" />
+ <part name="amount" type="xsd:double" />
+ </message>
+
+ <message name="unauthorizedAccess">
+ <part name="detail" element="tns:unauthorizedAccess"
/>
+ </message>
+
+ <message name="insufficientFunds">
+ <part name="detail" element="tns:insufficientFunds"
/>
+ </message>
+
+ <portType name="FrontEnd">
+ <documentation>bank functions available to
ATMs</documentation>
+
+ <operation name="connect">
+ <documentation>initiate bank
connection</documentation>
+ <input message="tns:connectRequest" />
+ <output message="tic:ticketMessage" />
+ </operation>
+
+ <operation name="disconnect">
+ <documentation>terminate bank
connection</documentation>
+ <input message="tic:ticketMessage" />
+ </operation>
+
+ <operation name="status">
+ <documentation>retrieve bank connection
status</documentation>
+ <input message="tic:ticketMessage" />
+ <output message="tns:statusResponse" />
+ </operation>
+
+ <operation name="logOn">
+ <documentation>initiate customer
access</documentation>
+ <input message="tns:logOnRequest" />
+ <output message="tns:logOnResponse" />
+ <fault name="unauthorizedAccess"
message="tns:unauthorizedAccess" />
+ </operation>
+
+ <operation name="logOff">
+ <documentation>terminate customer
access</documentation>
+ <input message="acc:customerMessage" />
+ </operation>
+
+ <operation name="getBalance">
+ <documentation>retrieve account
balance</documentation>
+ <input message="acc:customerMessage" />
+ <output message="acc:balanceMessage" />
+ </operation>
+
+ <operation name="deposit">
+ <documentation>increase account
balance</documentation>
+ <input message="tns:balanceChange" />
+ <output message="acc:balanceMessage" />
+ </operation>
+
+ <operation name="withdraw">
+ <documentation>decrease account
balance</documentation>
+ <input message="tns:balanceChange" />
+ <output message="acc:balanceMessage" />
+ <fault name="insufficientFunds"
message="tns:insufficientFunds" />
+ </operation>
+
+ </portType>
+
+</definitions></pre><p>The last document, <tt
class="literal">atm.wsdl</tt>, contains extensibility elements that
+ glue together the BPEL process and the WSDL definitions. At the beginning, the
document
+ imports the previous three documents to reference their definitions. Later,
+ it defines some properties for correlation purposes. <tt
class="varname">ticketId</tt>
+ distinguishes ticket numbers in messages exchanged within an ATM connection,
+ while <tt class="literal">customerId</tt> represents
customer names in messages
+ exchanged during a customer session. The property aliases adjacent to these
+ property definitions map these properties to key information items inside
messages.</p><p>Partner link types characterize the relationship between ATMs
and the process
+ (<tt class="varname">Atm-Front</tt>), the process and the
ticket issuer
+ (<tt class="varname">Front-Ticket</tt>) as well as the
process and the account system
+ (<tt class="varname">Front-Account</tt>). They define the
roles these services play and
+ specify the interface they present to each other. The coordinator does not call
back the
+ ATM. The ticket issuer or the account system do not call back the coordinator
either.
+ Therefore, all partner link types have a single role.</p><pre
class="programlisting"><definitions
targetNamespace="http://jbpm.org/examples/atm"
+
xmlns:tns="http://jbpm.org/examples/atm"
+
xmlns:atm="http://jbpm.org/examples/atm"
+
xmlns:acc="http://jbpm.org/examples/account"
+
xmlns:tic="http://jbpm.org/examples/ticket"
+
xmlns:plt="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
+
xmlns:vprop="http://docs.oasis-open.org/wsbpel/2.0/varprop"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <import
namespace="http://jbpm.org/examples/atm"
+ location="interface/frontend.wsdl" />
+ <import
namespace="http://jbpm.org/examples/account"
+ location="interface/account.wsdl" />
+ <import
namespace="http://jbpm.org/examples/ticket"
+ location="interface/ticket.wsdl" />
+
+ <vprop:property name="customerId" type="xsd:string">
+ <vprop:documentation>customer name
property</vprop:documentation>
+ </vprop:property>
+
+ <vprop:propertyAlias propertyName="tns:customerId"
+ messageType="tns:logOnRequest" part="customerName">
+ </vprop:propertyAlias>
+ <vprop:propertyAlias propertyName="tns:customerId"
+ messageType="tns:balanceChange" part="customerName" />
+ <vprop:propertyAlias propertyName="tns:customerId"
+ messageType="acc:customerMessage" part="customerName" />
+ <vprop:propertyAlias propertyName="tns:customerId"
+ messageType="acc:accountOperation" part="body">
+ <vprop:query>/body/customerName</vprop:query>
+ </vprop:propertyAlias>
+
+ <vprop:property name="ticketId" type="xsd:int">
+ <vprop:documentation>ticket number
property</vprop:documentation>
+ </vprop:property>
+
+ <vprop:propertyAlias propertyName="tns:ticketId"
+ messageType="tic:ticketMessage" part="ticketNo" />
+ <vprop:propertyAlias propertyName="tns:ticketId"
+ messageType="tns:logOnRequest" part="ticketNo" />
+
+ <plt:partnerLinkType name="Atm-Front">
+ <plt:documentation>
+ relationship between the ATM and the process
+ </plt:documentation>
+ <plt:role name="FrontEnd" portType="tns:FrontEnd"
/>
+ </plt:partnerLinkType>
+ <plt:partnerLinkType name="Front-Ticket">
+ <vprop:documentation>
+ relationship between the process and the ticket issuer
+ </vprop:documentation>
+ <plt:role name="TicketIssuer" portType="tic:TicketIssuer"
/>
+ </plt:partnerLinkType>
+ <plt:partnerLinkType name="Front-Account">
+ <plt:documentation>
+ relationship between the process and the account system
+ </plt:documentation>
+ <plt:role name="AccountSystem"
portType="acc:AccountSystem" />
+ </plt:partnerLinkType>
+
+</definitions></pre></div><div class="section"
lang="en"><div class="titlepage"><h3
class="title"><a
name="tutorial.atm.def.deploy"></a>Deployment</h3></div>
+<p>TODO</p>
+</div></div><div class="section" lang="en"><div
class="titlepage"><h2 class="title" style="clear:
both;"><a name="tutorial.atm.test"></a>Integration
tests</h2></div><p>Once our process is up and running, we need to make
sure that it is working as expected.
+ Here we create a JUnit test case and exercise
+ several scenarios.</p><div class="section"
lang="en"><div class="titlepage"><h3
class="title"><a
name="tutorial.atm.test.remote"></a>Remote web service
access</h3></div><p>This is the setup code for establishing a connection
with the ATM front end:</p><pre class="programlisting">private
FrontEnd frontEnd;
+
+protected void setUp() throws Exception {
+ AtmFrontEndService frontEndService = new AtmFrontEndService();
+
+ // obtain dynamic proxy for web service port
+ frontEnd = frontEndService.getFrontEndPort();
+}</pre><p>The test scenarios are described next.</p><div
class="orderedlist"><ol type="1"><li><p><tt
class="literal">testConnect</tt>: establish a connection to the
bank.</p><pre class="programlisting">public void testConnect()
throws RemoteException {
+ // connect to bank
+ int ticketNumber = frontEnd.connect();
+ assertTrue(ticketNumber > 0);
+
+ // check atm is connected
+ String status = frontEnd.status(ticketNumber);
+ assertEquals("connected", status);
+
+ // disconnect from bank
+ frontEnd.disconnect(ticketNumber);
+}</pre></li><li><p><tt
class="literal">testLogOnAuthorized</tt>: initiate a session as an
authorized
+ customer.</p><pre class="programlisting">public void
testLogOnAuthorized() throws RemoteException {
+ // connect to bank
+ int ticketNumber = frontEnd.connect();
+
+ // begin customer session
+ final String customerName = "admin";
+ try {
+ frontEnd.logOn(ticketNumber, customerName);
+ }
+ catch (UnauthorizedAccess e) {
+ fail("log on of authorized customer should succeed");
+ }
+
+ // end customer session
+ frontEnd.logOff(customerName);
+
+ // disconnect from bank
+ frontEnd.disconnect(ticketNumber);
+}</pre></li><li><p><tt
class="literal">testLogOnUnauthorized</tt>: initiate a session as an
unauthorized
+ customer.</p><pre class="programlisting">public void
testLogOnUnauthorized() throws RemoteException {
+ // connect to bank
+ int ticketNumber = frontEnd.connect();
+
+ // begin customer session
+ final String customerName = "misterx";
+ try {
+ frontEnd.logOn(ticketNumber, customerName);
+ fail("log on of unauthorized customer should fail");
+ }
+ catch (UnauthorizedAccess e) {
+ assertEquals(customerName, e.getCustomerName());
+ }
+
+ // disconnect from bank
+ frontEnd.disconnect(ticketNumber);
+}</pre></li><li><p><tt
class="literal">testDeposit</tt>: deposit funds</p><pre
class="programlisting">public void testDeposit() throws RemoteException,
UnauthorizedAccess {
+ // connect to bank
+ int ticketNumber = frontEnd.connect();
+
+ // begin customer session
+ final String customerName = "manager";
+ frontEnd.logOn(ticketNumber, customerName);
+
+ // get current balance
+ double previousBalance = frontEnd.getBalance(customerName);
+
+ // deposit some funds
+ double newBalance = frontEnd.deposit(customerName, 10);
+ // check the new balance is correct
+ assertEquals(previousBalance + 10, newBalance, 0);
+
+ // end customer session
+ frontEnd.logOff(customerName);
+
+ // disconnect from bank
+ frontEnd.disconnect(ticketNumber);
+}</pre></li><li><p><tt
class="literal">testWithdrawUnderBalance</tt>: withdraw funds not
exceeding account
+ balance.</p><pre class="programlisting">public void
testWithdrawUnderBalance() throws RemoteException,
+ UnauthorizedAccess {
+ // connect to bank
+ int ticketNumber = frontEnd.connect();
+
+ // begin customer session
+ final String customerName = "manager";
+ frontEnd.logOn(ticketNumber, customerName);
+
+ // get current balance
+ double previousBalance = frontEnd.getBalance(customerName);
+
+ // withdraw some funds
+ try {
+ double newBalance = frontEnd.withdraw(customerName, 10);
+ // check new balance is correct
+ assertEquals(previousBalance - 10, newBalance, 0);
+ }
+ catch (InsufficientFunds e) {
+ fail("withdraw under balance should succeed");
+ }
+
+ // end customer session
+ frontEnd.logOff(customerName);
+
+ // disconnect from bank
+ frontEnd.disconnect(ticketNumber);
+}</pre></li><li><p><tt
class="literal">testWithdrawOverBalance</tt>: withdraw funds exceeding
account
+ balance.</p><pre class="programlisting">public void
testWithdrawOverBalance() throws RemoteException,
+ UnauthorizedAccess {
+ // connect to bank
+ int ticketNumber = frontEnd.connect();
+
+ // begin customer session
+ final String customerName = "shipper";
+ frontEnd.logOn(ticketNumber, customerName);
+
+ // get current balance
+ double previousBalance = frontEnd.getBalance(customerName);
+
+ // try to withdraw an amount greater than current balance
+ try {
+ frontEnd.withdraw(customerName, previousBalance + 1);
+ fail("withdraw over balance should fail");
+ }
+ catch (InsufficientFunds e) {
+ assertEquals(customerName, e.getCustomerName());
+ // check account balance has not changed
+ assertEquals(previousBalance, e.getAmount(), 0);
+ }
+
+ // end customer session
+ frontEnd.logOff(customerName);
+
+ // disconnect from bank
+ frontEnd.disconnect(ticketNumber);
+}</pre></li></ol></div></div><div
class="section" lang="en"><div
class="titlepage"><div><div><h3
class="title"><a
name="tutorial.atm.test.interactive"></a>Interactive
execution</h3></div></div><div></div></div><p>Last,
but not least, the ATM example offers a rich client built from Swing
+ components. This program resembles an actual teller machine. It has a double
goal:</p><div class="itemizedlist"><ul
type="disc"><li>Let you click your way through the process instead of
writing unit tests to
+ explore new scenarios.</li><li>Assist you in demonstrating the BPEL
technology to your customer, manager or
+ colleague using an easy-to-follow
interface.</li></ul></div><p>To bring up the interactive terminal,
call:</p><pre class="synopsis">ant
launch.terminal</pre><p>After a brief message exchange to connect to the front
end service, the frame below
+ appears.</p><div class="figure"><a
name="tutorial.atm.welcome.screen"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="370"><tbody><tr style="height: 144px;"><td
align="center"><img src="img/atmWelcomeScreen.png"
alt="Welcome screen"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 9. Welcome
screen</b></p></div><p>Click <span
class="emphasis"><em>Log On</em></span> to access an
account. The terminal
+ prompts for a customer name. Type in any name from the <tt
class="literal">accounts.xml</tt>
+ file in the <tt class="literal">account</tt>
example.</p><div class="figure"><a
name="tutorial.atm.name.prompt"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="251"><tbody><tr style="height: 117px;"><td
align="center"><img src="img/atmNamePrompt.png"
alt="Customer name prompt"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 10. Customer name
prompt</b></p></div><p>The top-level frame presents the available
account operations.</p><div class="figure"><a
name="tutorial.atm.account.operations"></a><div
class="mediaobject" align="center"><table
summary="manufactured viewport for HTML img" border="0"
cellpadding="0" cellspacing="0"
width="370"><tbody><tr style="height: 144px;"><td
align="center"><img src="img/atmAccountOps.png"
alt="Account operations"
align="middle"></td></tr></tbody></table></div><p
class="title"><b>Figure 11. A!
ccount
operations</b></p></div><p>Enjoy!</p></div></div></div></body></html>
\ No newline at end of file
Property changes on: trunk/samples/quickstart/atm/readme.html
___________________________________________________________________
Name: svn:mime-type
+ text/plain