由于越來(lái)越多的公司正投身到 Web 服務(wù)的浪潮中,研究者們預(yù)測(cè) Web 服務(wù)所提供的不僅僅是單端流程。一般來(lái)說(shuō),復(fù)雜應(yīng)用程序在重要領(lǐng)域日益增多,越來(lái)越多的公司將 Web 服務(wù)作為復(fù)雜流程互動(dòng)的一部分,WSC 正好順應(yīng)這一趨勢(shì)。
WSCI 是基于 XML 的接口描述語(yǔ)言,它一般與 WSDL 結(jié)合在一起使用。它的目的是通過(guò) Web 服務(wù)的力量使公司創(chuàng)建出反映當(dāng)今動(dòng)態(tài)的、持續(xù)變化的業(yè)務(wù)需求的業(yè)務(wù)流程。公司可以將他們的應(yīng)用程序軟件和資源作為 Web 服務(wù),以便其它公司能夠找到并將其應(yīng)用到他們自己的業(yè)務(wù)流程中。創(chuàng)建業(yè)務(wù)處理過(guò)程不僅需要對(duì)所有組件的協(xié)作模式有一個(gè)清晰的定義,也需要一個(gè)描述標(biāo)準(zhǔn)的業(yè)務(wù)到業(yè)務(wù)(B2B)互動(dòng)的方法。
下面部分說(shuō)明了一個(gè)簡(jiǎn)單在線股票交易公司如何使用 Web 服務(wù)和 WSDL 發(fā)布服務(wù),這種方法的缺點(diǎn)及 WSC 如何克服這些缺點(diǎn)。本文討論的范圍是解釋 WSC,提供 WSC 的價(jià)值信息以及學(xué)習(xí)它更多的特性。
使用 Web 服務(wù)的在線交易公司
通過(guò)這個(gè)簡(jiǎn)單的股票交易例子,可以很好的解釋 WSC 的要求和角色。為了簡(jiǎn)潔,我們大致概述涉及到的大多數(shù)行為。我并不是要討論買(mǎi)賣(mài)股票的所有步驟,因?yàn)檫@不是本文的討論范圍。而是會(huì)給出一個(gè)簡(jiǎn)單的股票交易應(yīng)用程序樣例。下面的圖 1 描述了一個(gè)使用在線 Web 應(yīng)用程序進(jìn)行股票買(mǎi)賣(mài)的簡(jiǎn)單及一步一步的業(yè)務(wù)流程。
圖 1. 股票交易業(yè)務(wù)流程
實(shí)例
在線股票交易應(yīng)用程序從第三方服務(wù)(例如 xmethods.net)獲得股票的詳細(xì)信息, 并將它提供給用戶。 用戶可能選他或她所感興趣的股票,并且需要更多的詳細(xì)信息。在線股票公司使用其中一個(gè)第三方提供的 Web 服務(wù)來(lái)獲得詳細(xì)信息。
一旦用戶決定要買(mǎi)哪種股票,他或她就會(huì)下購(gòu)買(mǎi)訂單。在線股票應(yīng)用程序通過(guò)其內(nèi)部流程從股票市場(chǎng)買(mǎi)到股票。之后,在線交易應(yīng)用程序需要用戶確認(rèn)購(gòu)買(mǎi)訂單,并且為用戶強(qiáng)制設(shè)置確認(rèn)訂單超時(shí)時(shí)間。如果一分鐘沒(méi)有確認(rèn)訂單,系統(tǒng)則會(huì)向用戶發(fā)送超時(shí)信息。
一旦訂單被用戶確認(rèn)后,在線交易應(yīng)用程序從用戶帳戶中扣減必要的費(fèi)用。要實(shí)現(xiàn)這一操作,它會(huì)使用現(xiàn)存的一個(gè)第三方 Web 服務(wù)。使用一個(gè) Web 服務(wù)來(lái)驗(yàn)證信用卡,使用第二個(gè) Web 服務(wù)來(lái)扣減費(fèi)用。 這兩步都必須處理為一個(gè)邏輯工作單元(即事務(wù)),其中任何一個(gè)服務(wù)的失敗都會(huì)向用戶發(fā)送失敗的信息。如果信用卡被成功驗(yàn)證,并且這些錢(qián)也成功地從用戶帳戶中轉(zhuǎn)出, 在線股票交易應(yīng)用程序就會(huì)從市場(chǎng)購(gòu)買(mǎi)所需的股票數(shù)。用戶可以下多個(gè)購(gòu)買(mǎi)訂單,并且每一個(gè)訂單將會(huì)作為一個(gè)單獨(dú)的邏輯單元來(lái)處理。
賣(mài)方的訂單步驟和買(mǎi)方的訂單步驟是相似的。用戶下訂單并在交貨時(shí)確認(rèn)。一旦確認(rèn)了,在線應(yīng)用程序下賣(mài)方訂單,在證實(shí)用戶帳單詳細(xì)信息后從用戶帳戶劃帳。
為了增加業(yè)務(wù)渠道,并與其它系統(tǒng)進(jìn)行協(xié)作操作,在線交易公司發(fā)布了一個(gè) 買(mǎi)/賣(mài) Web 服務(wù)應(yīng)用程序作為 。在一個(gè)簡(jiǎn)單的 Web 服務(wù)例子中,您可以映射上面介紹的步驟到一個(gè) WSDL 文件里。用戶使用一些 Web 服務(wù)軟件,例如 Microsoft VBA 編輯器,或者使用外部應(yīng)用程序調(diào)用 Web 服務(wù),從而調(diào)用 WSDL 操作來(lái)設(shè)置買(mǎi)方或賣(mài)方訂單。以下鏈接地址可以說(shuō)明如何在 VBA 中實(shí)現(xiàn)這個(gè)任務(wù)。 上面的圖 1描述了業(yè)務(wù)過(guò)程之間的 WSDL 操作及圖形.
WSDL 的缺點(diǎn)
一個(gè)定義得很好的買(mǎi)賣(mài)股票 Web 服務(wù)運(yùn)行的前提是所有過(guò)程都是自動(dòng)的,換句話說(shuō),它們彼此不分享任何狀態(tài)。 但是在這種情況下,WSDL 自身解決了業(yè)務(wù)整合過(guò)程中的一些核心需求,例如:
流程順序使用買(mǎi)/賣(mài) Web 服務(wù)的消費(fèi)者,能以任何順序調(diào)用這些操作。例如,服務(wù)消費(fèi)者可以在調(diào)用 placeBuyOrder 或者 placeSellOrder 操作之前調(diào)用現(xiàn)金轉(zhuǎn)移操作。WSDL 不會(huì)禁止以任何順序調(diào)用操作,使用 WSDL 的 Web 服務(wù)應(yīng)用程序必須在上面的邏輯應(yīng)用中迎合這一特點(diǎn)。
消息相關(guān)性相關(guān)性是發(fā)送信息給別人,期望收到回復(fù),并在返回的消息實(shí)例中使用通用數(shù)據(jù)和發(fā)送消息實(shí)例相連(或者說(shuō),相關(guān)聯(lián))時(shí),所涉及的一個(gè)簡(jiǎn)單理念。在業(yè)務(wù)過(guò)程的互動(dòng)中,理解和描述出消息實(shí)例間的相關(guān)性是非常重要的。 WSDL 不具有關(guān)聯(lián)消息實(shí)例的能力。換句話說(shuō),它不會(huì)保留這些操作的狀態(tài)。 在一個(gè)典型的業(yè)務(wù)整合流程中,流程之間能分享狀態(tài)以便提供一個(gè)相關(guān)聯(lián)的流程。所有使用 WSDL 發(fā)布的操作都是無(wú)狀態(tài)的,它在消息實(shí)例間沒(méi)有相關(guān)性。
在本例中,當(dāng)用戶把下訂單作為下一步操作時(shí),Web 服務(wù)應(yīng)用程序要求用戶確認(rèn)訂單。用戶也許決定改變股票數(shù)量或是改變購(gòu)買(mǎi)時(shí)間。因?yàn)橛唵伪恍薷牧耍蛩鸵俅蜗沦?gòu)買(mǎi)訂單。這種相互間來(lái)回的會(huì)話可能會(huì)發(fā)生幾次,用戶可能會(huì)下幾次訂單,或者說(shuō),用戶與 Web 服務(wù)應(yīng)用程序間發(fā)起多次對(duì)話。但是,使用 WSDL 的 Web 服務(wù)沒(méi)有關(guān)聯(lián)消息實(shí)例的能力。
工作單元(事務(wù))為了讓 Web 服務(wù)成為長(zhǎng)信息交換的一部分,清楚地定義信息交換什么時(shí)候開(kāi)始觸發(fā),什么時(shí)候考慮終止,考慮哪個(gè)部分以事務(wù)方式管理,這些問(wèn)題都是很重要的。
本例中,placeBuyOrder, confirmBuyOrder 這些操作和 debit money 流程必須在一個(gè)單元中完成。Web 服務(wù)必須成功執(zhí)行這三個(gè)操作,或者必須在執(zhí)行前把這些操作恢復(fù)到一致?tīng)顟B(tài),您不能把 WSDL 中發(fā)布的操作來(lái)進(jìn)行分布式事務(wù)。在 WSDL 中,事務(wù)的范圍是限制在單個(gè)的操作中,不能超越一個(gè)操作的范圍。
異常處理雖然 WSDL 使用錯(cuò)誤代碼來(lái)拋出異常,但是它不能處理一些人工模型,比如檢查特殊消息,聲明超時(shí)異常,或者聲明僅用于 Web 服務(wù)一些局部操作但不是全程服務(wù)的異常。
在互動(dòng)流程中有一個(gè)合適的異常人工模型是很有必要的。本例中,如果用戶確認(rèn)買(mǎi)賣(mài)訂單的時(shí)間超過(guò)一分鐘,Web 服務(wù)就會(huì)發(fā)出超時(shí)異常。
上下文在業(yè)務(wù)互動(dòng)流程中,在參與的流程間建立一個(gè)上下文環(huán)境來(lái)共享信息是很重要的。這些信息可能是一系列的聲明、異常事件、或是事務(wù)特性。WSDL 不會(huì)為流程提供任何可以在上下文環(huán)境中處理的特征。
圖 2. 使用 WSDL 的股票交易
WSC 如何提供幫助
WSC 幫助解決以上提到的基于 WSDL 及擴(kuò)展功能的業(yè)務(wù)整合流程中的所有缺點(diǎn)。下節(jié)解釋了 WSCI 如何處理這些問(wèn)題:
上下文
要集成一些服務(wù)來(lái)創(chuàng)建復(fù)雜的業(yè)務(wù)服務(wù),這些服務(wù)需要共享上下文環(huán)境信息。上下文元素組成一個(gè)環(huán)境以執(zhí)行活動(dòng)。同時(shí),上下文元素也確保一系列的活動(dòng)作為一個(gè)組來(lái)執(zhí)行,這些有上下文環(huán)境信息的所有活動(dòng)能共享聲明、異常事件及事務(wù)屬性。
上下文定義有局部屬性和局部過(guò)程定義。局部屬性只對(duì)在當(dāng)前環(huán)境下執(zhí)行的活動(dòng)有效。局部過(guò)程定義指定在當(dāng)前環(huán)境下實(shí)例化的過(guò)程。為了調(diào)用或產(chǎn)生局部過(guò)程,必須是從本地過(guò)程定義可見(jiàn)的上下文中。
?
在下面的 清單 1 中, 局部過(guò)程定義在買(mǎi)賣(mài)股票中有不同的上下文。如果在購(gòu)買(mǎi)庫(kù)存的過(guò)程中發(fā)生錯(cuò)誤,它僅限于買(mǎi)的過(guò)程。例如,如果環(huán)境沒(méi)有定義,買(mǎi)的過(guò)程中發(fā)生的錯(cuò)誤會(huì)拒絕用戶使用 Web 服務(wù),而不是發(fā)送狀態(tài)給 placeSellOrder 。以下給出 WSCI 定義的一部分:
清單 1. 上下文元素示例
<context>
?<foreach select="ns1:arrayOfStockList/leg[position()>1]">
??<process name = "PlaceBuyOrder" instantiation = "other">
???<action name = "PlaceBuyOrder"
?????role= "tns:trader"
?????operation= "tns:placeBuyOrder">
???</action>
??</process>
?</foreach>
?<process name = "ConfirmBuyOrder" instantiation = "other">
??<action name = "ConfirmBuyOrder"
????role= "tns:trader"
????operation= "tns:confirmBuyOrder" >
???<correlate correlation =
???"defs:buyStockCorrelation" instantiation= "true" />
??</action>
??<exception>
???<onTimeout property =
???"tns:confirmationTime"
???? type= "duration"
???? reference="tns:PlaceBuyOrder@end">
???? <compensate transaction = "tns:reverseBuyOrders"/>
???</onTimeout>
??</exception>
?</process>
?<process name="transferMoney" instantiation="other">
??<action name = "cashTransaction"
????role= "tns:trader"
????operation= "tns:debitMoney" >
??</action>
?</process>
?<exception>
??<onMessage>
???<action name = "reverseBuyOrders"
????role= "tns:trader"
????operation= "tns:cancelBuyOrder">
???</action>
???<fault code = "tns:creditCardTxFaultCode"/>
??</onMessage>
?</exception>
</context>
流程順序
為了順序地調(diào)用更多的微小業(yè)務(wù)流程,并在全局業(yè)務(wù)流程下將它們組合在一起, WSC 使用了接口元素順序。如它的名稱所示,它能確保系統(tǒng)順序調(diào)用流程。當(dāng)服務(wù)消費(fèi)者要買(mǎi)股票時(shí),在買(mǎi)的流程之前接口元素調(diào)用現(xiàn)金轉(zhuǎn)移操作。這是通過(guò)在順序元素中定義所有操作的順序來(lái)完成的, 如以下清單 2 所示。
清單 2. 順序元素示例
<sequence>
??????? <!-- Web service Choreography Sequence -->
?<operation name="placeBuyOrder">
??<input message="buySellOrderRequest"/>
??<output message="buySellOrderResponse"/>
?</operation>
?<operation name="confirmBuyOrder">
??<input message="buySellOrderResponse"/>
??<output message="buySellOrderResponse"/>
?</operation>
?<operation name="debitMoney">
??<input message="creditCardDetails"/>
??<output message="debitMoneyResponse"/>
?</operation>
</sequence>
信息相關(guān)性
在 WSCS 中,當(dāng)信息傳到服務(wù)時(shí),就暗示著可以建立實(shí)例。WSC 建立的實(shí)例可以用數(shù)據(jù)信息中的關(guān)鍵字識(shí)別。本例中,將 confirmBuyOrder 和 placeBuyOrder 過(guò)程建立關(guān)聯(lián)是很重要的,因?yàn)槊總€(gè)過(guò)程都可能在之前的實(shí)例中發(fā)生. 當(dāng)確認(rèn)訂單發(fā)送到服務(wù)消費(fèi)者時(shí),消費(fèi)者可能會(huì)修改訂單(例如,客戶可能會(huì)因?yàn)閮r(jià)格改變修改數(shù)量),并再次下購(gòu)買(mǎi)訂單。這樣的對(duì)話可能在服務(wù)消費(fèi)者與 Web 服務(wù)單發(fā)生幾次。
服務(wù)消費(fèi)者可能下不只一份購(gòu)買(mǎi)訂單,也會(huì)觸發(fā)不只一次對(duì)話。您必須識(shí)別每一次對(duì)話。這樣就會(huì)用到 placeOrderId。提供了這種機(jī)制,服務(wù)消費(fèi)者想下多少訂單就能下多少,并且每次參與都是一個(gè)獨(dú)立的對(duì)話。每一次對(duì)話,都會(huì)創(chuàng)建一個(gè)唯一的 placeOrderId。
要實(shí)現(xiàn)這樣的功能,可以使用包含唯一 ID 的屬性來(lái)定義關(guān)聯(lián)元素。在這個(gè)特例中,股票代碼如清單 3所示。
清單 3. 關(guān)聯(lián)元素示例
<correlation name = "buysellCorrelation"
property = "tns:placeOrderId" />
工作單元
WSCI 使用事務(wù)元素為 Web 服務(wù)行為建模,并且將一組行為作為一個(gè)工作單元。Web 服務(wù)使用 WSCI 事務(wù)與其它服務(wù)通信,它要么完全執(zhí)行完這些活動(dòng),要么將其存恢復(fù)到執(zhí)行之前的一致?tīng)顟B(tài)。
在買(mǎi)賣(mài)股票的例子中,在線股票交易公司與第三方(例如第三方信用卡 Web 服務(wù))提供的不同 Web 服務(wù)對(duì)話。如果發(fā)生異常事件或是不能與任一個(gè)第三方完成事務(wù),Web 服務(wù)必須保證能回到前一個(gè)狀態(tài)。這是通過(guò)使用事務(wù)元素和補(bǔ)償元素來(lái)實(shí)現(xiàn)的。 清單 4 說(shuō)明了這部分的代碼.
清單 4. 事務(wù)元素示例
<transaction name = "reverseBuyOrder"= "atomic">
<compensation>
<action name = "reverseBuyOrder"= "tns:trader"=
"tns:reverseBuyOrder"/>
</compensation>
</transaction>
The transaction can be called in a compensation element when
an exception occurs as shown below:
<onTimeout property = "tns:confirmationTime"= "duration"=
"tns:PlaceBuyOrder@end">
<compensate transaction = "tns:reverseBuyOrder"/>
</onTimeout>
異常處理
在業(yè)務(wù)整合過(guò)程中,異常處理和選取適當(dāng)?shù)穆酚膳c處理正常情況一樣重要。 維持,WSCI 使用了異常元素。WSCI 允許聲明異常行為,由 Web 服務(wù)在編排好的點(diǎn)顯示出來(lái)。異常行為的聲明是上下文定義的一部分,并與異常進(jìn)行關(guān)聯(lián),使用一些 Web 服務(wù)執(zhí)行的行為以回應(yīng)異常。異常是 WSCI 的建模能力,其設(shè)計(jì)的目的是為在 Web 服務(wù)編排的斷點(diǎn)中顯示的行為建模。它們不必表現(xiàn)出任何“技術(shù)錯(cuò)誤”
WSCI 能拋出一些異常,它們來(lái)自于 WSDL 、信息內(nèi)容或事件(例如,超時(shí)事件)的錯(cuò)誤信息。異常發(fā)生后,與異常相關(guān)的行為被執(zhí)行,從而實(shí)現(xiàn)當(dāng)前環(huán)境終止。所以,WSCI 支持“恢復(fù)異常”的概念,它不會(huì)導(dǎo)致整個(gè)系統(tǒng)重排而停止(和 JAVA 中try/catch的概念相似)。但是,在沒(méi)有異常行為定義的情況下,錯(cuò)誤的發(fā)生會(huì)使上下文終止,提交到父上下文中。理論上說(shuō),異常處理行為在父上下文中定義,就會(huì)成為所有子上下文的默認(rèn)行為,反過(guò)來(lái)說(shuō),在上下文定義中的異常處理行為可以在父上下文中使用來(lái)作異常處理。
在 清單 5中, 當(dāng)用戶確認(rèn)訂單的時(shí)間超過(guò)一分鐘,應(yīng)用程序就會(huì)超時(shí)。在 WSC 中,是通過(guò)超時(shí)特性來(lái)處理的。超時(shí)元素實(shí)際上是在異常事件中使用的事件元素。一分鐘后,超時(shí)事件被觸發(fā),系統(tǒng)使用補(bǔ)償元素回到上一次的 placeBuyOrder 狀態(tài)。
清單 5. 異常和超時(shí)元素示例
<exception>
<onTimeout property = "tns:expiryTime"
type = "duration"
reference="tns:ReserveSeats@end">
<compensate transaction = "tns:seatReservation"/>
</onTimeout>
</exception>
圖 3. 使用 WSCI 的股票交易
WSCI 的其它特點(diǎn)
下面表 1列出了 WSCI 的其它有用特點(diǎn)。要查看完整的清單,請(qǐng)參考 WSCI 文檔。
表 1. WSCI 元素
元素名稱 | 簡(jiǎn)短描述 | 示例 |
?Selector | ?選擇器元素從消息中選擇屬性值。在抽取復(fù)雜的消息到一系列屬性時(shí)它很有用。 | ?
您可以使用選擇器元素從 getAllStocksResponse 消息中獲取持有的總的股票數(shù)量: <selector property = "tns:stockCount" |
?Call | ?調(diào)用元素在動(dòng)作間調(diào)用任意操作(例如,調(diào)用第三方 Web 服務(wù))。這是自動(dòng)進(jìn)行的,如果在調(diào)用的流程里發(fā)生錯(cuò)誤,動(dòng)作也會(huì)失敗。 | ?
如果應(yīng)用程序?yàn)榱藢徍撕椭匦聟f(xié)調(diào)一致,要將所有的事務(wù)寫(xiě)入日志,就可以調(diào)用任意一個(gè)流程來(lái)記錄: <process name = "DebitMoney" instantiation = "other"> |
?All activity | ?所有活動(dòng)元素與順序活動(dòng)相似,所有在其中定義的操作都會(huì)被執(zhí)行,但是在這個(gè)元素中定義的活動(dòng)能以任意順序執(zhí)行。 | ?
本例中,購(gòu)買(mǎi)訂單和從信用卡減錢(qián)操作可以用任何次序執(zhí)行: <all> |
?Foreach | ?在循環(huán)中執(zhí)行活動(dòng),和 Java 的循環(huán)很相似。 | ?
為每一個(gè)在 arrayOfStocks中的股票執(zhí)行 PlaceSellOrder 操作: <foreach select="ns1:arrayOfStockList/leg[position()>1]"> |
?Switch | ?switch 元素從基于條件的活動(dòng)清單中選擇一個(gè)活動(dòng)。 | ?
條件的次序是很重要的,條件為真的首先執(zhí)行。這個(gè) Java 的 case 語(yǔ)句很相似: <switch> |
?Until | ?在布爾值的基礎(chǔ)上執(zhí)行所有活動(dòng)。它至少執(zhí)行這些活動(dòng)一次,與 Java 中的 do while 語(yǔ)句相似。 | ?<until> <condition>tns:creditCardProcessed</condition> <process name = "DebitMoney" instantiation = "other"> <action name = "debitMoney" role = "tns:trader" operation = "tns:debitMoney"> </action> </process> </until> |
?While | ?基于條件布爾值,要么所有活動(dòng)都不執(zhí)行,要么執(zhí)行很多次,和 Java 中的 while 語(yǔ)句相似。 | ?<while> <condition>tns:creditCardProcessed</condition> <process name = "DebitMoney" instantiation = "other"> <action name = "debitMoney" role = "tns:trader" operation = "tns:debitMoney"> </action> </process> </while> |
?Delay | ?使用指定的延遲時(shí)間后運(yùn)行活動(dòng),如果在活動(dòng)中發(fā)生異常,活動(dòng)可能會(huì)在指定時(shí)間前完成。 | ?<exception> <delay property = "tns:delayTime" type = "duration" reference="tns:delayBuyingStock"> </delay> </exception> |
?Call | ?這個(gè)元素實(shí)例化一個(gè)流程并且等待它執(zhí)行完畢,call 元素對(duì)調(diào)用內(nèi)部流程很有用。 | ?<call process = “tns:audit" /> |
?Spawn | ?實(shí)例化一個(gè)流程但并不等待它執(zhí)行完畢。 | ?<Spawn process = “tns:logBuyTransaction" /> |
?Join | ?等待 spawned 流程的實(shí)例執(zhí)行完畢。如果沒(méi)有實(shí)例存在或所有實(shí)例都完成了,活動(dòng)也完成了。 | ?<join process = “tns:logBuyTransaction" /> |
結(jié)束語(yǔ)
到現(xiàn)在為止,還沒(méi)有一個(gè)標(biāo)準(zhǔn)的方法來(lái)描述通過(guò) Web 服務(wù)與其它服務(wù)編排互動(dòng)的方式來(lái)進(jìn)行的信息流交換。針對(duì)這個(gè)問(wèn)題, BEA 系統(tǒng)、Intalio、SAP AG、以及 Sun Microsystems 開(kāi)發(fā)了 WSCI 。本文中,通過(guò)一個(gè)簡(jiǎn)單的例子您已學(xué)到了 WSCI 所提供的一些基本功能。但是我只揭開(kāi)了它的表面的部分,為了更深入地了解 WSCI,您也許想看看 WSCI 規(guī)范,并且使用 WSCI 來(lái)編寫(xiě)些簡(jiǎn)單的應(yīng)用程序樣例。