Structured activities (such as if and while) specify an order or condition that affects the circumstance for running a set of other, embedded activities. The embedded activities may be basic, structured, or both.
The flow activity embeds activities that run concurrently. We describe this activity in Chapter 7.
<flow standard-attributes> standard-elements <links>? <link name="NCName" />+ </links> activity+ </flow>
Here's an example.
<flow> <links> <link name="ApplicantLink" /> <link name="SpouseLink" /> </links> <sequence ... name="Calculate credit report for spouse"> <sources> <source linkName="SpouseLink" /> </sources> . . </sequence> <reply partnerLink="CreditCheck" operation="checkFamilyCredit" variable="resultSpouse" messageExchange="spouse"> <targets> <target linkName="SpouseLink" /> </targets> </reply> <sequence ... name="Calculate credit report for applicant"> <sources> <source linkName="ApplicantLink" /> </sources> . . . </sequence> <reply partnerLink="CreditAndAccountPL" operation="creditCheck" variable="resultApplicant" messageExchange="applicant"> <targets> <target linkName="ApplicantLink" /> </targets> </reply> </flow>
The forEach activity issues the embedded activities as a group, either sequentially or concurrently. We describe this activity in Chapter 8.
<forEach counterName="BPELVariableName" parallel="yes|no" standard-attributes> standard-elements <startCounterValue expressionLanguage="anyURI"?> unsigned-integer-expression </startCounterValue> <finalCounterValue expressionLanguage="anyURI"?> unsigned-integer-expression </finalCounterValue> <completionCondition>? <branches expressionLanguage="anyURI"? successfulBranchesOnly="yes|no"?>? unsigned-integer-expression </branches> </completionCondition> <scope>...</scope> </forEach>
Here's an example.
<forEach counterName="loopIndex" parallel="yes"> <startCounterValue>1</startCounterValue> <finalCounterValue> <query>count(/CustomerQuoteInformation/vehicle)</query> </finalCounterValue> <scope> <assign> <copy> <from variable="inputRecord"> <query> (/CustomerQuoteInformation/vehicle)[loopIndex] </query> </from> <to variable="currentVehicle"/> </copy> </assign> <invoke name="CheckVehicleWithDMV" partnerLink="dmvPL" portType="dmvPT"> operation="retrieveLicenseStatus" inputVariable="currentVehicle" outputVariable="receiveDetail" </invoke> </scope> </forEach>
The if activity runs an activity if a Boolean expression evaluates to true. The activity may include one or more embedded elseif activities, each with its own Boolean expression, and may include a single embedded else activity.
<if standard-attributes> standard-elements <condition expressionLanguage="anyURI"?>bool-expr</condition> activity <elseif>* <condition expressionLanguage="anyURI"?>bool-expr</condition> activity </elseif> <else>? activity </else> </if>
Here's an example.
<if> <condition> bpel:getVariableProperty('mvStatusVariable', 'AutoStatus') = 'OWN' </condition> . . <elseif> <condition> bpel:getVariableProperty(mvStatusVariable', 'AutoStatus') = 'INCOMPLETE' </condition> <throw faultName="IncompleteFault" /> </elseif> <else> <throw faultName="StatusFault" /> </else> </if>
The pick activity waits for one of potentially several events to occur, often including a timeout and always including receipt of an inbound message. We describe this activity in Chapter 8.
<pick createInstance="yes|no"? standard-attributes> standard-elements <onMessage partnerLink="NCName" portType="QName"? operation="NCName" variable="BPELVariableName"? messageExchange="NCName"?>+ <correlations>? <correlation set="NCName" initiate="yes|join|no"? />+ </correlations> <fromParts>? <fromPart part="NCName" toVariable="BPELVariableName" />+ </fromParts> activity </onMessage> <onAlarm>* ( <for expressionLanguage="anyURI"?>duration-expr</for> | <until expressionLanguage="anyURI"?>deadline-expr</until> ) activity </onAlarm> </pick>
Here's an example.
<pick name="CustomerResponseToQuote"> <onMessage operation="requestMore" partnerLink="ProcessQuotePL" portType="ProcessQuotePT" variable="furtherConsiderationReq"> <correlations> <correlation initiate="no" set="applicantEMailAddr" /> </correlations> <sequence name="customerWantsUnderwriterToContactPostReview"> <assign name="copyQuoteForReview"> <copy> . . </copy> </assign> <invoke name="underwriterFollowupAndCall" partnerLink="UnderwriterPL" portType=" UnderwriterPT" operation="retrieveAndFollowUp" inputVariable="underwriterReview"/> </sequence> </onMessage> <onAlarm> <for>'PT5M'</for> <invoke .../> </onAlarm> </pick>
The repeatUntil activity defines a loop that always runs at least once and iterates until the Boolean expression at the bottom of the loop evaluates to true.
<repeatUntil standard-attributes> standard-elements activity <condition expressionLanguage="anyURI"?> bool-expr </condition> </repeatUntil>
Here's an example.
<repeatUntil> <invoke name="GetUnderwriterWorkLoad" partnerLink="UnderwriterPL" operation="getWorkLoad" outputVariable="underwriterStatus" /> <condition> $underwriterStatus.result > 100 </condition> </repeatUntil>
A scope activity is a unit of logic that can be compensated without interfering with the behavior of activities and handlers in other scopes. We describe scopes in Chapter 7.
<scope isolated="yes|no"? exitOnStandardFault="yes|no"? standard-attributes> standard-elements <partnerLinks>? ... </partnerLinks> <messageExchanges>? ... </messageExchanges> <variables>? ... </variables> <correlationSets>? ... </correlationSets> <faultHandlers>? ... </faultHandlers> <compensationHandler>? ... </compensationHandler> <terminationHandler>? ... </terminationHandler> <eventHandlers>? ... </eventHandlers> activity </scope>
Two attributes are available:
If you set the isolated attribute of two concurrently running scope activities to yes, you ensure that there is no difference in the common data available to the two scopes whether the first scope runs before the second or the second runs before the first. The default value is no.
If you set the exitOnStandardFault attribute to yes, a BPEL standard fault exits the scope without causing invocation of a fault or termination handler. The only standard fault that is unaffected by this attribute is the concurrency-related fault bpel:joinFailure. The default value is no.
Here's an example.
<scope name="Primary"> <faultHandlers> <catch faultName="QuoteCancelled"> <compensate/> </catch> </faultHandlers> <scope name="StoreQuote"> <compensationHandler> <!-- remove the stored quote --> </compensationHandler> <sequence> <!-- store the quote --> </sequence> </scope> <scope name="InformCustomer"> <compensationHandler> <!-- withdraw the quote by email --> </compensationHandler> <sequence> <!-- confirm the quote by email --> </sequence> </scope> <eventHandlers> <onEvent> . . <scope> <if> <condition>$status="cancelled"</condition> <throw faultName="QuoteCancelled" /> </if> </scope> </onEvent> </eventHandlers> </scope>
The sequence activity embeds activities that run sequentially.
<sequence standard-attributes> standard-elements activity+ </sequence>
Here's an example.
<sequence> <!- wait for 1 year -> <wait> <for>'P1Y'</for> </wait> <invoke name="ContactCustomer" partnerLink="PrintShopPL" portType="PrintShopPT" operation="sendFormLetterByEmail" inputVariable="customerDetail"/> </sequence>
The while activity defines a loop that iterates while a Boolean expression at the top of the loop evaluates to true. If the Boolean expression evaluates to false initially, the activity does not run at all.
<while standard-attributes> standard-elements <condition expressionLanguage="anyURI"?>bool-expr</condition> activity </while>
Here's an example.
<while> <condition>$numberOfDrivers < 5</condition> <invoke ... /> </while>