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