Jim Amsden (jamsden@us.ibm.com), STSM, IBM
2008 年 1 月 21 日
在本篇文章中,我們繼續(xù)定義 SOA 解決方案。我們對每一個服務的規(guī)范進行詳細的建模。這些規(guī)范將會定義服務的消費者和生產者之間的契約。這些契約包括被提供的和被要求的接口,那些接口在服務規(guī)范中所扮演的角色,以及那些角色在提供服務中進行交互的規(guī)則和協議是什么。
本文的內容
本系列的第 1 篇文章:“SOA 建模 第 1 部分 服務識別”(請參見左上方的 本系列更多內容)描繪出了識別那些同業(yè)務需求相連接的服務的一種方法的大致輪廓。我們首先捕獲實現業(yè)務任務所必須的業(yè)務目標。然后,對滿足這些目標所必須的業(yè)務操作和過程進行建模。接著,我們將業(yè)務過程視作反映我們的最終解決方案所必須滿足的業(yè)務服務需求契約的一種服務協作。然后,我們使用該需求契約來幫助我們識別它們被要求的服務及它們之間的潛在聯系。這為鏈接到業(yè)務目標的業(yè)務相關服務的識別提供了一種形式化的方法。
在前一篇文章中,我們也查看了如何通過識別于業(yè)務相關的服務來最大化 SOA 解決方案的潛力。我們設計了基于業(yè)務需求的服務拓撲結構,并且將服務連接到反映服務解決方案所必須滿足的 Service Requirements 契約的服務協作上。
在本文中,我們繼續(xù)通過對每一項服務的規(guī)范進行詳細的建模來定義 SOA 解決方案。這些規(guī)范將定義服務的消費者和提供者之間的契約。這些契約包括被提供的和被要求的接口,那些接口在服務規(guī)范中所扮演的角色,以及那些角色在提供服務中進行交互的規(guī)則和協議是什么。
服務規(guī)范概述
我們還沒有準備好開始對服務規(guī)范的細節(jié)進行建模。服務規(guī)范必須為服務的潛在消費者指定其需要知道的每一件事情,以便他們決定是否有興趣使用該服務,以及如何使用它。它還必須指定服務提供者為成功執(zhí)行該服務所必須知道的每一件事情。因此,服務規(guī)范就是消費者的需要同提供者的提供之間的媒介或者契約。
理想情況下,這一信息由單一地點提供。這使得為復用服務而搜索資產庫和獲得所有必要的信息變得十分容易,而且不需要在許多不同的文檔中定位或者搜索相關的元素。服務規(guī)范至少包括這些信息:
如同本系列中所有文章一樣,我們將使用現已存在的 IBM? Rational? 和 IBM? WebSphere? 工具來建立解決方案并將它們鏈接在一起,從而我們能夠根據需求驗證解決方案并且更加有效的對變化進行管理。表1總結了我們將要開發(fā)例子的過程,以及我們將要使用的工具。除此之外,我們通過將 IBM? Software Services Profile 添加到 IBM? Rational? Software Architect 中的 UML 模型中,為服務建模擴展了統一建模語言(UML)。
表1. 開發(fā)過程角色、任務和工具
角色 |
任務 |
工具 |
業(yè)務執(zhí)行官 |
傳達業(yè)務目標 |
IBM? Rational? RequisitePro? |
業(yè)務分析師 |
分析業(yè)務需求 |
IBM? WebSphere? Business Modeler |
軟件架構師 |
設計解決方案的體系結構 |
IBM Rational Software Architect |
Web 服務開發(fā)人員 |
執(zhí)行該解決方案 |
IBM? Rational? Application Developer 和 IBM? WebSphere? Integration Developer |
服務識別回顧
我們首先回顧業(yè)務需求以及滿足它們的被識別的服務,正如我們在 “SOA 建模 第 1 部分 服務識別” 中所詳細描述的那樣。圖1將業(yè)務需求顯示為業(yè)務中角色的一個協作、角色職責、以及角色如何相互作用的規(guī)則。
圖1. 服務需求契約
這一服務協作反映了一個需求契約,該契約來自一個指定服務解決方案必須做什么的業(yè)務過程。它是與體系結構無關的但是正式的需求規(guī)范,它它并不過度約束 SOA 解決方案。所謂與體系結構無關,是指該需求契約只是指定了解決方案必須做什么,但是并沒有指定如何去做。
圖2顯示了被識別的服務規(guī)范的總體情況,該規(guī)范將會制造解決方案并且使用依賴關系,同時指出它們打算如何被使用。
圖2. 服務拓撲結構
最終,圖3展示了您如何使用那些服務來實現您的業(yè)務要求。
圖3. 滿足服務需求契約
這就完成了對服務以及它們是如何同業(yè)務需求相關的識別。本文的剩余篇幅還將解釋如何對服務規(guī)范的細節(jié)進行建模。這些服務規(guī)范在圖2中被詳細表示為接口。它們提供了許多在 Overview 中列出細節(jié)。
在完成這些接口后,您仍然不知道接口所描述的是哪一項服務參與者提供或者需要的服務,也不知道服務功能如何被執(zhí)行(可能使用其他服務)。這些都將在討論服務實現的下一篇文章中加以介紹。
服務規(guī)范的類型
一個服務規(guī)范需要提供如下信息:
- 服務的名稱,指示出它是什么或者它做什么。
- 被提供和被要求的接口,描述服務的功能性的性能。每一個功能性都包括:
- 它的名稱,通常是一個動詞詞組,指示出它做什么
- 任何被要求或者可選的服務數據輸入和輸出
- 任何消費者在使用該功能之前所期望具備的前提條件
- 任何 消費者 期望的并且是 生產者 必須提供的功能成功使用的后期條件
- 即使前提條件已經被滿足,但是功能由于某種原因未能被提供時,任何被提出的期望或者錯誤條件
- 任何通訊協議或者規(guī)則,它們決定功能什么時候后能夠被使用或著按照什么樣的順序被使用。
- 消費者期望被提供使用的或者同服務進行交互的任何功能。
- 在提供服務時,任何執(zhí)行都必須滿足的需求。
- 反映服務想要達到什么樣的成功以及如何對其進行評估的約束。
- 服務消費者所期望得到的和服務提供者被期望提供的質量,例如花費、可用性、性能、腳印、任務的適宜性、和競爭信息等等。
- 使用服務的原則,例如用于維持安全性和完整性或者用于將服務從無能力恢復到成功執(zhí)行的安全性和事務范圍。
顯然,本文不可能涵蓋所有這些內容。特別是,我們將不會關注服務或者策略的質量。對于那些內容,將有專門的文章加以詳細的說明。進一步地,它們可能明確一個服務特定的提供者,而不是特定服務的接口自身。我們要做的是,關注定義和使用一個服務的最根本的必須條件。
下面各小節(jié)詳細描述了每一個在 圖2 中被識別的服務規(guī)范。其介紹順序是從一個非常簡單的沒有協議的服務規(guī)范,到一個反映一個簡單的請求/響應協議的服務規(guī)范,再到一個更加復雜的、涉及到消費者和提供者之間多步協議和交互作用的服務。
時間進度服務
圖4中顯示的 Scheduling 服務規(guī)范十分簡單。服務提供了兩種功能性:一種是對一個生產時間表請求進行響應的能力,一種是創(chuàng)建一個運送時間表的能力。據我們所知,在這種情況下,沒有一種使用這些功能性的協議。這兩者都能夠被消費者以任何順序被使用。
圖4. 時間進度服務規(guī)范
Scheduling 服務規(guī)范是在生產包中定義的一個簡單的 UML 接口。它提供兩種服務操作。每一種操作都具有前提和后期條件,并且它們能夠提出例外。服務操作的參數被要求要么為服務數據(消息),要么為簡單類型。這就確保了參數不會出現被引用調用或者被值調用的狀況,服務數據被放置在哪里(在什么地址空間中),服務消費者或者提供者是否在操作數據的一個副本或者某些持久數據源,等等。所有這些需要確保服務不受其配置地點的限制。服務數據被定義在下面的服務數據模型小節(jié)中。
裝運服務
Shipping 服務協議有一些復雜。想要運送產品的消費者請求運送服務。然而,運送者可能會花一些時間來決定產品被放置在哪里,它們是否在可用清單中或者是否需要被生產,以及運送產品的最有效的方式。因此,運送時間表使用前需要一段時間。消費者通常不希望等到時間表完成,因為這會阻止并行中的其他工作,或者不必要的將系統資源消耗在長進程上。
因此,IT 架構師決定在消費者和提供者之間使用一個簡單的請求響應或者回叫協議。消費者請求運送,過一段時間之后,響應來自運送者的請求來處理完全的時間表。要對這一協議進行建模,我們需要指定生產者和消費者這兩個角色,它們的職責、以及它們進行交互的協議或者規(guī)則。最后一部分是非常重要的,這是因為如果運送者接收不到一個運送請求,那么它們將不能發(fā)送時間表。
服務規(guī)范告訴您需要知道的關于服務的任何事情。這包括您必須滿足的使用服務的需求(有時被稱作 Use 或者 Usage 契約,請參見 Resources 中列出的 Daniels 和 Cheesman 的文章,再加上服務必須滿足的應用的需求(有時被稱作 Realization 契約)。這是您需要為業(yè)務需求捕獲的同一類信息;除了主題區(qū)域和細節(jié)級別是不同的之外。您將在涉及服務消費者和提供者如何進行交互的 Service Requirements 契約中定義該規(guī)范。
在這種情況下,我們使用一個抽象類來定義服務規(guī)范,如圖5所示。
圖5. Shipping 服務規(guī)范
ShippingService 規(guī)范涉及到兩個角色:
- 角色 shipper 是一個提供者的角色。它負責滿足其類型賦予它的運送的職責,即運送接口。
- 角色 orderer 負責處理運送進度表。這通過其
ScheduleProcessing 類型被顯示。
將這些角色指明為提供者和消費者并不是必須的。在一個潛在的長期運行的會話中(可能涉及到多方),這些只是任意的區(qū)別。通過 Service 規(guī)范實現被提供的運送接口和使用被需要的 ScheduleProcessing 接口,也很容易看出誰是消費者、誰是提供者。
在運送者和訂貨人角色之間有一個連接器。它指出了在這些角色之間涉及某些交互作用的協議。requestShipping 交互作用為 ShippingService 類所擁有,它顯示了這個交互作用是什么。
ShippingService 交互作用指定了訂貨方運送方角色之間交互的行為的或者動態(tài)的方面。訂貨方首先發(fā)送一個 requestShipping 消息(或者調用運送方的 requestShipping 操作),一段時間后,必須響應來自運送方的 processSchedule 消息。交互作用涉及到兩條生命線:一條用于訂貨方,另一條用于運送方。這些對象實例就是 Service 規(guī)范類中的訂貨方和運送方屬性。也就是說,消息在哪些角色之間通過連接器被交換。這是一個簡單的、異步的請求/響應或者回叫模式,它是許多服務協議的典型應用。
ShippingService 協議通過使用任何 UML 2 行為被指定,這些行為可以是:活動、交互、狀態(tài)機、或者不透明行為(代碼)。選擇哪一種來使用取決于建模者、他們更加偏愛的風格、或者問題域的適用性。
貨品計價服務
為發(fā)貨單計算初始的和最終的價格,涉及到訂貨者和貨品計價之間一個更加復雜的協議。顯然,initiatePriceCalculation 必須在 completePriceCalculation 之前被調用。然后,訂貨者必須被準備來作為結果的發(fā)貨單。
我們能夠通過使用一個指定發(fā)貨方和訂貨方角色、它們的職責、以及它們之間如何交互的協議(會話或者規(guī)則)的抽象類來捕獲這個協議。這就像 ShippingService 規(guī)范,除了交互作用僅僅是簡單的請求/響應之外。為了服務的有效使用,服務功能性必須以一種順序被調用。
圖6中顯示的 InvoicingService 服務規(guī)范捕獲了這一協議。請注意該服務規(guī)范也執(zhí)行了 Invoicing 用例。一個用力可能被用來反映服務指定的需求。該服務規(guī)范包括兩個角色:發(fā)貨方和訂貨方。這些角色的類型分別是 Invoicing 實現的接口和被使用的 InvoiceProcessing 接口。這些接口封裝了角色(服務或者請求功能或者操作)的職責。服務規(guī)范中的 InvoicingService 活動為使用服務操作指定了協議,在訂貨方和發(fā)貨方角色之間能夠發(fā)生的實際交流。
圖6. InvoicingService 服務規(guī)范
InvoicingService 是一個指定訂貨人和發(fā)貨單之間的會話、交流協議、或者交互規(guī)則的類。協議的細節(jié)在該類的 ownedBehavior 中被捕獲,并被用來為使用這一服務指定有效的交互模式。在這種情況下,該協議被表達為一種 UML 活動。
該協議指示出訂貨方必須在試圖得到完全的價格計算之前,啟動一個價格計算。訂貨方然后必須響應一個請求(在本例中是回叫)來處理最終的貨物。一些請求貨品計價服務的消費者只需執(zhí)行這三種操作,但是這些指定操作的順序是受到協議約束的。沒有一個 InvoicingService 活動中的 ActivityPartitions 反映 InvoicingService 類中的角色或者屬性。一個屬于某個分區(qū)的操作祈禱行動指示出祈禱處于分區(qū)所反映的角色(行動的目標輸入碼正是活動分區(qū)所反映的角色)。
在這種情況下,在訂貨人和貨品計價服務之間只有一種交互作用,所以服務規(guī)范類只有一個 ownedBehavor 。在另一種情況下,消費者和提供者之間會有超過一種的交互作用,每一種都是用不同的協議。服務規(guī)范將擁有一個 ownedBehavior 為每一個會話指定有效的交互模式。
您并不知道哪個服務提供者執(zhí)行了一個 InvoicingService 。您也不知道哪個服務消費者可能使用它。您只知道任何一個消費者使用服務必須做什么,以及任何一個提供者執(zhí)行它時必須做什么。
購買規(guī)范
最后,我們來看處理定購單的服務規(guī)范,如圖7所示。
圖7. Purchasing 服務規(guī)范
如同 Scheduling 服務規(guī)范一樣,Purchasing 是一個簡單的接口,它僅僅擁有一個為消費者處理定購單提供功能的操作,而這些消費者將返回一個完全的發(fā)貨單。伴隨而來的副作用是,訂購的條目被生產(如果需要的話)并且運送給消費者。
該服務接口反映了在原始的 Process Purchase Order 業(yè)務過程中指定的功能性的能力。它反映了從那個業(yè)務過程中識別和設計的服務。
服務拓撲結構重溫
至此,服務規(guī)范被更加完整的定義。我們能夠查看前面 圖3 中所顯示服務拓撲結構?;仡櫵@示了被識別服務的實例如何能夠被使用來滿足業(yè)務 Service Requirements 契約。但是那個圖表沒有很好的顯示服務自身,它們是如何被連接的,以及在它們的交互作用中涉及到什么協議。既然服務規(guī)范已經被完成,您創(chuàng)建一個新的圖表,來指示使用這些服務的服務參與方如何進行交互來實現該需求。您將在本系列的下一篇文章 “SOA 建模 第三部分 服務實現” 中再次看到這一圖表,在那里它將被當作本例子中最終的完整的服務解決方案的出發(fā)點被使用。
圖8顯示了一個抽象的 Order Processing 組件,它為顯示服務拓撲結構的另一個視圖提供了上下文環(huán)境。它部分反映了將要提供或者需求服務(或者既提供又需求)的必須滿足 Process Purchase Order 需求契約的順序處理參與方。我們尚不精確的知道這些部分是什么(它們沒有類型),但是我們能夠通過指出它們在定義其如何交互的服務規(guī)范中扮演什么角色,結合它們想要滿足的需求是什么,來指定它們需要做什么。
圖8. 服務交互的細節(jié)
Order Processing 組件各部分之間的連接器,指出了各部分之間預期的交互作用。連接器的名稱與它們契約的名稱相對應,在這種情況下,這是相應的服務規(guī)范的協議。這指示出這些部分將必須提供和要求服務規(guī)范所指定的接口,并且根據服務規(guī)范的協議各部分將會使用的這些接口。在本系列的下一篇文章對服務實現的描述中,將對這件事是如何完成的進行建模。
我們還看到這些被放在一起的部分將會以一種滿足 Process Purchase Order 需求契約的方式相互作用。因此,Order Processing 總結出以下兩點:
- 服務消費者和提供者(或者稱之為參與者)需要滿足業(yè)務需求,
- 表示這些參與者如何相互作用的連接和協議同樣如此。
服務數據模型
package org::crm 中定義的 Customer Relationship Management (CRM) 數據模型,定義了在這個例子中的 Purchase Order Process 模型中所有服務操作所使用的所有數據(請參見圖9)。CRM 包反映了 Customer Relationship Management 服務數據模型的設計,該模型能夠在許多服務中被復用,甚至是由不同公司所提供的服務。服務數據是如何被發(fā)現和格式化的,以及它是如何同持久實體或者物理數據源相關聯的,已經超出了本文的范圍。我們這里所介紹的是該服務數據是什么,以及該模型如何被捕獲。
圖9. CRM 服務域模型
圖9中所顯示的服務數據中的每一個 <message> 。服務數據就是在服務消費者和提供者之間進行交換的數據。用于服務操作的參數的數據類型既可以是消息也可以是簡單類型。
請注意: 服務數據消息同 Web Services Description Language (WSDL) 消息并不一致。服務操作能夠擁有任何數量的消息或者簡單類型的輸入和輸出。服務操作能夠被設計用作輸入、輸出、和錯誤消息,但是這并不是必須的,而且還將導致不合需要的郵戳數據耦合。
消息作為 數據傳遞對象(DTOs) 能夠被輕易的在分布式環(huán)境中的地址空間之間進行交換。服務消費者和提供者并不關心數據存放的實際位置,因此他們假定自己擁有一些實際持久域數據的視圖的一個拷貝。消息沒有同一性。由于它們的等同性是基于它們內容的值的,而不是基于它們的身份的,所以它們是值對象。
消息反映了在可能的分布式環(huán)境中,服務消費者和提供者之間的數據交換。服務提供者通常也需要訪問持久的數據,用于它們的執(zhí)行設計。服務數據和服務執(zhí)行設計中所使用的持久域數據之間的關系就是服務提供者及其服務功能性的執(zhí)行的職責。通常,服務數據是域數據的一個選集和投影(或者視圖)。雖然如此,服務數據如何從域數據中得到或者更新,取決于服務執(zhí)行。服務數據對象(SDOs) 對于服務數據消息來說是一個非常有用的執(zhí)行。它們還具備管理變化集和自動將變化提交到持久存儲區(qū)的能力。服務參與者執(zhí)行可能會用到這些功能,但是它們不需要在模型中被處理。
數據模型使用一個 <id> 規(guī)則來識別唯一可以識別類的實例的屬性。這將成為貫穿服務模型的主題。這是因為 Web 服務和面向 Web 服務的 Business Process Execution Language (BPEL) 特別依賴實例相關性的業(yè)務數據或者基于值的對象同一性。
下一步工作展望
在本文中,我們對每一個被識別服務的服務規(guī)范進行詳細的建模。這些規(guī)范將會指示被提供的和被要求的接口,那些接口在服務規(guī)范中所扮演的角色,以及那些角色在提供服務中進行交互的規(guī)則和協議是什么。服務規(guī)范定義了消費者請求和生產者服務之間的契約。
本系列的下一篇文章 “SOA 建模 第三部分 服務實現” 解釋了服務是如何被真正實現的。服務實現首先決定哪些組件將會提供哪些服務。該決定對于服務可用性、分發(fā)、安全、事務范圍、和耦合具有非常重要的含義。在這些決定做出之后,我們可以對每一項服務功能是如何執(zhí)行的進行建模,從而對需求服務是如何被使用的進行建模。然后,我們將使用包含在 Rational Software Architect 中的 UML-to-SOA 轉換特性來創(chuàng)建 Web Services 解決方案,該方案能夠在 Rational Application Developer 或者 WebSphere Integration Developer 中被直接使用,來執(zhí)行、測試、和配置完全的解決方案。
|