在我們能夠設計編排層之前,我們需要很好地理解如何正式地表達流程的操作特征。本書使用
WS-BPEL
語言來演示流程邏輯如何能夠被作為具體定義的一部分來描述(
圖
16.1
),從而能夠通過相適應的編排引擎來實現和執行。
圖
16.1.
常見的
WS-BPEL
流程定義結構
雖然你很可能會使用流程建模工具并因此不需要從草稿開始編寫你的流程,
WS-BPEL
元素的知識仍舊是有用的和必需的。
WS-BPEL
建模工具經常會涉及到這些元素和結構,而且你可能深入到它們生成的代碼中做進一步的精化。
注意
如果你已經輕松了解了
WS-BPEL
語言,請向前跳到
面向服務業務流程設計(
循序漸進的流程
)
章節。
在我們進入
WS-BPEL
語言的細節之前,讓我們簡要討論一下這個規范是如何形成的。
Web
服務業務流程執行語言(
BPEL
4WS
)最初在
2002
年
7
月被構思和發布,伴以
BPEL
4WS 1.0
規范,這是
IBM
、
Microsoft
和
BEA
合作的成果。這個文檔提議了從先前的各種語言中得到靈感的編排語言,例如
IBM
的
Web
服務流程語言(
WSFL
)
與
Microsoft
的
XLANG
規范。
隨著來自于
SAP
和
Siebel Systems
等其他貢獻者的加入,版本
1.1
的
BPEL
4WS
規范在一年不到的時間,于
2003
年
5
月發布了。這個版本獲得了更多的關注與廠商支持,導致了大量的商業上遵循
BPEL
4WS
的可用編排引擎。正是在這個發布之前,
BPEL
4WS
規范被提交到
OASIS
技術委員會,使得這個規范能夠被開發成為一個官方的、開放的標準。
技術委員會正在下一個版本
BPEL
4WS
的最終發布流程中。它已經宣布了語言本身被重新命名為
Web
服務業務流程執行語言,或者是
WS-BPEL
(并被賦予
2.0
版本號)。
WS-BPEL
所規劃的變更目前已經對外公布,并可在
OASIS
的
Web
網站
www.oasis-open.org
上獲得。
在本節的元素描述中加入了注釋,以利于指出
BPEL
4WS
與
WS-BPEL
之間的語法變動。為了簡單起見,在本書中我們提到的業務流程執行語言就是指
WS-BPEL
。
現在是學習
WS-BPEL
語言的時候了。如果你還沒有準備好,推薦你在繼續本節之前閱讀第
6
章。第
6
章中涉及了編排、協調、原子事務和業務活動等相關概念,因而在此就不再重復。本章同時也假設你已經通讀了第
13
章中提供的
WSDL
教程。
讓我們從
WS-BPEL
流程定義的根元素開始。它使用
name
屬性來給一個名稱賦值,并用于建立流程定義相關的命名空間。
示例
16.1.
process
定義框架
<process name=“TimesheetSubmissionprocess”
targetNamespace=“http://www.xmltc.com/tls/process/”
xmlns=
“http://schemas.xmlsoap.org/ws/2003/03/
business-process/”
xmlns:bpl=“http://www.xmltc.com/tls/process/”
xmlns:emp=“http://www.xmltc.com/tls/employee/”
xmlns:inv=“http://www.xmltc.com/tls/invoice/”
xmlns:tst=“http://www.xmltc.com/tls/timesheet/”
xmlns:not=“http://www.xmltc.com/tls/notification/”>
<partnerLinks>
...
</partnerLinks>
<variables>
...
</variables>
<sequence>
...
</sequence>
...
</process>
process
結構包含一系列常見的子元素,在下列章節中說明。
partnerLink
元素建立了端口類型的服務(伙伴),將參與業務流程的執行過程。伙伴服務能夠擔當流程的客戶端,負責調用流程服務。作為替代,伙伴服務也能夠被流程服務自身所調用。
partnerLink
元素的內容代表了兩個合作伙伴之間的通信交換
---
流程服務是一個合作伙伴其他服務是另一個合作伙伴。依據通信的種類,流程服務的作用將會變化。例如,被外部服務所調用的流程服務可能擔當
“工單提交流程(
TimesheetSubmissionProcess
)”的角色。然而,當這個同樣的流程服務調用具有發票校驗的不同服務的時候,它擔當了不同的角色,或許是“發票客戶(
InvoiceClient
)”。
partnerLink
元素因而包含
myRole
與
partnerRole
屬性,分別設立了流程服務和伙伴服務服務提供者的角色。
為簡單起見,
myRole
屬性用于流程服務被伙伴客戶端服務所調用時,因為在這個情況下流程服務擔當了服務提供者。
partnerRole
屬性識別了流程服務所調用的伙伴服務(使伙伴服務成為服務提供者)。
注意當期望的流程服務在相同的伙伴服務中擔當服務請求者和服務提供者的時候,
myRole
與
partnerRole
屬性都能夠被相同的
partnerLink
元素所使用。例如,在流程和伙伴服務的異步通信過程中,在伙伴服務回調期間
myRole
的設置顯示出流程服務的角色。
示例
16.2.
partnerLinks
結構包含一個
partnerLink
元素,在該元素內流程服務被一個外部客戶端伙伴所調用,并且四個
partnerLink
元素確定了被流程服務所調用的伙伴服務
<partnerLinks>
<partnerLink name=“client”
partnerLinkType=“tns:TimesheetSubmissionType”
myRole=“TimesheetSubmissionServiceProvider”/>
<partnerLink name=“Invoice”
partnerLinkType=“inv:InvoiceType”
partnerRole=“InvoiceServiceProvider”/>
<partnerLink name=“Timesheet”
partnerLinkType=“tst:TimesheetType”
partnerRole=“TimesheetServiceProvider”/>
<partnerLink name=“Employee”
partnerLinkType=“emp:EmployeeType”
partnerRole=“EmployeeServiceProvider”/>
<partnerLink name=“Notification”
partnerLinkType=“not:NotificationType”
partnerRole=“NotificationServiceProvider”/>
</partnerLinks>
你會在
示例
16.2
中注意到,每個
partnerLink
元素同樣也包含了
partnerLinkType
屬性。這涉及到
partnerLinkType
結構,在下面說明。
對于包含在流程中的每個伙伴服務,
partnerLinkType
元素在流程定義中確定了被
partnerLink
元素引用的
WSDL
portType
元素。因此,這些結構典型地都直接嵌入到每個伙伴服務的
WSDL
文檔中(包括流程服務)。
正如
partnerLink myRole
與
partnerRole
屬性所定義的那樣,
partnerLinkType
結構為每個服務可以擔當的角色包含一個
role
元素。其結果是,
partnerLinkType
將具有一個或兩個
role
子元素。
示例
16.3. WSDL
定義
結構包含
partnerLinkType
結構
<definitions name=“Employee”
targetNamespace=“http://www.xmltc.com/tls/employee/wsdl/”
xmlns=“http://schemas.xmlsoap.org/wsdl/”
xmlns:plnk=
“http://schemas.xmlsoap.org/ws/2003/05/partner-link/”
...
>
...
<plnk:partnerLinkType name=“EmployeeServiceType” xmlns=
“http://schemas.xmlsoap.org/ws/2003/05/partner-link/”>
<plnk:role name=“EmployeeServiceProvider”>
<portType name=“emp:EmployeeInterface”/>
</plnk:role>
</plnk:partnerLinkType>
...
</definitions
>
注意多個
partnerLink
元素可以引用相同的
partnerLinkType
。這當流程服務與多個伙伴服務具有相同關系的時候十分有用。所有的伙伴服務因而能夠使用相同的流程服務的
portType
元素。
注意
在
2.0
版本的
WS-BPEL
規范中,提議了
portType
元素的變更以便作為
role
元素的一個屬性存在。
WS-BPEL
流程服務通常使用
variables
結構來保存與即時工作流邏輯關聯的狀態信息。整個消息和數據集合被格式化為
XSD schema
類型,能夠在處理過程中被置入變量并在以后獲取。數據的類型能夠被賦予
variable
元素,它需要用下面三個屬性之一來預定義:
messageType
,
element
,或
type
.
messageType
屬性允許變量包含整個
WSDL
定義的消息,而
element
屬性完全引用了
XSD
元素結構。
type
屬性能夠用于僅代表
XSD
simpleType
,如
string
或
integer
。
示例
16.4.
variables
結構僅包含一些后續被工單提交流程所使用的
variable
子元素
<variables>
<variable name=“ClientSubmission”
messageType=“bpl:receiveSubmitMessage”/>
<variable name=“EmployeeHoursRequest”
messageType=“emp:getWeeklyHoursRequestMessage”/>
<variable name=“EmployeeHoursResponse”
messageType=“emp:getWeeklyHoursResponseMessage”/>
<variable name=“EmployeeHistoryRequest”
messageType=“emp:updateHistoryRequestMessage”/>
<variable name=“EmployeeHistoryResponse”
messageType=“emp:updateHistoryResponseMessage”/>
...
</variables>
典型地來講,具有
messageType
屬性的變量是為流程定義所處理的每個輸入和輸出消息定義的。這個屬性的值是來自于伙伴流程定義的消息名稱。
WS-BPEL
提供內置函數,允許存儲在變量中或者是與變量關聯的信息能在業務流程執行期間被處理。
getVariableProperty
(
variable name
,
property name
)
這個函數允許從變量中接收全局的屬性值。它完全接受了作為輸入的值和屬性名稱,并返回所要求的值。
getVariableData
(
variable name
,
part name
,
location path
)
由于變量通常用于管理狀態信息,這個函數要求提供訪問數據的其他部分處理邏輯。
getVariableData
函數具有一個強制的變量名稱參數和兩個能夠用于指定變量數據的可選變量。
在我們的示例中我們多次使用
getVariableData
函數來從變量中獲取消息數據。
示例
16.5.
兩個
getVariableData
函數被用于接收來自于不同變量的特定數據
getVariableData
(
'InvoiceHoursResponse'
,
'ResponseParameter'
)
/SPAN>
getVariableData
(
'input'
,
'payload'
,
'/tns:TimesheetType/Hours/...'
)
sequence
結構允許你組織一系列的活動以便它們以預定義的、有順序的次序執行。
WS-BPEL
提供了大量能夠用于在流程定義中表示工作流邏輯的活動。在本節中剩余的元素描述解釋了一組基本的用于我們將要進行案例研究示例的一部分活動。
示例
16.6.
sequence
結構框架僅包含了
WS-BPEL
所提供的許多活動元素中的一些
<sequence>
<receive>
...
</receive>
<assign>
...
</assign>
<invoke>
...
</invoke>
<reply>
...
</reply>
</sequence>
注意
sequence
元素可以嵌套,允許你在序列中定義序列。
該元素識別了伙伴服務的操作,這是流程定義計劃在其執行過程中要調用的。
invoke
元素配備了五個常見屬性,進一步詳細說明了條文的細節(
表
16.1
)。
表
16.1.
invoke
元素屬性
屬性
|
描述
|
partnerLink
|
該元素通過相應的
partnerLink
來命名伙伴服務。
|
portType
|
該元素用于識別伙伴服務的
portType
元素。
|
operation
|
流程服務需要發送請求到的伙伴服務操作。
|
inputVariable
|
輸入消息將用于和伙伴服務操作進行通信。注意這里所提及的是作為變量,因為它引用了具有
messageType
屬性的
WS-BPEL
變量。
|
outputVariable
|
當基于請求
-
響應的
MEP
進行通信的時候采用該元素。返回值存儲在單獨的
variable
元素中。
|
/SPAN>
示例
16.7.
invoke
元素確定了目標伙伴服務的細節
<invoke name=“ValidateWeeklyHours”
partnerLink=“Employee”
portType=“emp:EmployeeInterface”
operation=“GetWeeklyHoursLimit”
inputVariable=“EmployeeHoursRequest”
outputVariable=“EmployeeHoursResponse”/>
receive
元素允許我們建立流程服務期望從外部客戶端伙伴服務中接收請求的信息。在這個案例中,流程服務被視作是等待調用的服務提供者。
receive
元素包含一組屬性,它們中的每一個都被賦值,涉及到預期進來的通信(
表
16.2
)。
表
16.2.
receive
元素屬性
屬性
|
描述
|
partnerLink
|
客戶端伙伴服務在相應的
partnerLink
結構中被識別。
|
portType
|
流程服務
portType
會等待從伙伴服務中接收請求消息。
|
operation
|
會接收請求的流程服務操作。
|
variable
|
進來的請求消息將會被存儲在流程定義的
variable
結構中。
|
createInstance
|
當這個屬性被設置成“
yes
”的時候,這個特殊請求的可能負責創建新的進程實例。
|
注意這個元素同樣能夠被用于在異步消息交換的過程中接收回調消息。
示例
16.8.
用于工單提交流程定義的
receive
元素預示著客戶端的伙伴服務負責啟動工單文擋提交流程
<receive name=“receiveInput”
partnerLink=“client”
portType=“tns:TimesheetSubmissionInterface”
operation=“Submit”
variable=“ClientSubmission”
createInstance=“yes”/>