在SOA架构中,编排服务层提供了强大的手段。通过当代面向服务解决方案,它能实现一些关键功能而使系统获益。这个子层次为SOA带来的主要是对系统中逻辑的抽象,以及能够减轻底层服务大量设计约束。
通过抽象业务流程逻辑:
l 可以将关于应用和业务的服务设计为与流程无关的和可复用的。
l 流程服务假定具有状态性,从而可以使其他服务摆脱状态管理。
l 业务流程逻辑集中在单一位置,而不是分布于各处。
而现在主要是通过使用WS-BPEL语言创建业务流程定义来解决编排层的设计。
那下面我们就来介绍一下BPEL语言基础。
Web服务业务流程执行语言(BPEL4WS)最初在2002年7月随同BPEL4WS1.0规范的发布而出现的。它IBM、Microsoft和BEA合作的成果。该文档是从先前的各种语言中得到启发的编排语言,例如IBM的Web服务流程语言(WSFL)和Microsoft的XLANG规范。
- process元素
首先是WS-BPEL流程定义的根元素process开始。它使用name属性为一个名称赋值,并用于建立流程定义相关的命名空间。
<process name="TimesheetSubmissionProcess"
targetNamespace="http://www.xmltc.com/tls/process/"
xmlns="http://schema.xmlsoap.org/ws/2003/03/business-process/"
xmlns:bpl="http://www.xmltc.com/tls/process/"
xmlns:emp="http://www.xmltc.com/tls/employee/">
<partnerLinks>
...
</partnerLinks>
<variables>
...
</variables>
<sequence>
...
</sequence>
...
</process>
Process定义框架
- partnerLinks与partnerLink元素
partnerLink元素建立了端口类型的服务(伙伴),它将参与业务流程的执行过程。伙伴服务能担当流程的客户端,负责调用流程服务。相应地,伙伴服务也能被流程服务自身所调用。
partnerLink元素的内容代表了两个合作伙伴之间的通信交换(流程服务是一个合作伙伴,而其他服务室另一个合作伙伴)。依据通信的种类,流程服务的作用将会不同。因而partnerLink元素包含myRole与partnerLink属性,分别担当流程服务和伙伴服务服务提供者的角色。
也就是说,当流程服务被伙伴客户端服务调用时使用myRole属性,因为在这种情况下,流程服务担当服务提供者。partnerRole属性识别流程服务所调用的伙伴服务(使伙伴服务成为服务提供者)。
当期望的流程服务在相同的伙伴服务中同时担当服务请求者和服务提供者时,myRole和partnerRole将被同时使用。在流程服务和伙伴服务的异步通信中,伙伴服务回调中myRole表明流程服务的角色。
<partnerLinks>
<partnerLink name="client"
partnerLinkType="tns:TimesheetSubmissionType"
myRole="TimesheetSubmissionServiceProvider"/>
<partnerLink name="Invoice"
partnerLinkType="inv:InvoiceType"
partnerRole="InvoideServiceProvider"/>
<partnerLink name="Timesheet"
partnerLinkType="TimesheetServiceProvider"
partnerRole="TimesheetServiceProvider"/>
<partnerLink name="Employee"
partnerLinkType="emp:EmployeeType"
partnerRole="EmployeeServiceProvider"/>
<partnerLink name="Notification"
partnerLinkType="not:NotificationType"
partnerRole="NotificationServiceProvider"/>
</partnerLinks>
partnerLinks和partnerLink元素示例
示例中partnerLinks元素包含了5个partnerLink元素,其中一个内由一个外部客户端伙伴调用流程服务,并由其余4个partnerLink元素来确定流程服务调用的伙伴服务。
- partnerLinkType元素
对于包含在流程中的每个伙伴服务,partnerLinkType元素在流程中定义了partnerLink元素所引用的WSDL portType元素。因此,这些结构通常都直接嵌入到每个伙伴服务的WSDL文档中(包括流程服务)。partnerLinkType结构在每个服务可以担当的角色中包含了一个role元素。同时又要和partnerLink myRole和partnerRole属性相对应,partnerLinkType将包含一个或两个role子元素。
<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="EmployeeType">
<plnk:role name="EmployeeServiceProvider">
<portType name="emp:EmployeeInterface"/>
</plnk:role>
</plnk:partnerLinkType>
</definitions>
WSDL定义结构包含partnerLinkType结构示例
多个partnerLink元素可以引用相同的partnerLinkType元素。当流程服务与多个伙伴服务具有相同关系时,这就十分有用。所有的伙伴服务都能使用相同流程流程服务的portType元素。
- variables元素
WS-BPEL流程服务通常使用variables结构存储与流程逻辑相关的状态信息。整个信息和数据集合被格式化为XSD schema类型,能够在处理过程中将变量置入其中并在以后获取。必须使用messageType、element或type这三种属性之一来预定义允许赋给variable元素的数据类型。
messageType属性允许变量包含整个WSDL定义的消息,而element属性只引用XSD元素结构。Type属性也只代表XSD simpleType,如字符串或整数。
<variables>
<variable name="ClientSubmission"
messageType="bpl:receiveSubmitMessage"/>
<variable name="EmployeeHoursRequestMessage"
messageType="emp:getWeeklyHoursRequestMessage"/>
<variable name="EmployeeHoursResponse"
messageType="emp:getWeeklyHoursResponseMessage"/>
..........
</variables>
Variable元素示例
通常,具有messageType属性的变量是为流程定义所处理的每个输出和输入消息定义的。该属性值来自伙伴流程定义的消息名称。
- sequence元素
sequence结构允许你组织一系列的活动以便它们以预定义的、按顺序执行。同时他还允许嵌套,在序列中定义序列。
- invoke元素
该元素识别了伙伴服务的操作,这是流程定义计划在其执行过程中要调用的。Invoke元素具有5种常见属性:
l partnerLink:通过相应的partnerLink来命名伙伴服务
l portType:用于识别伙伴服务的portType元素
l operation:流程服务需要发送请求到伙伴服务操作
l inputVariable:将用于与伙伴服务操作进行通信的输入消息。它引用了variable元素
l outputVariable:当基于请求-响应的MEP进行通信时采用该元素。返回值存储在单独的variable元素中。
<invoke name="ValidateWeeklyHours"
partnerLink="Employee"
portType="emp:EmployeeInterface"
operation="GetWeeklyHoursLimit"
inputVariable="EmployeeHoursRequest"
outputVariable="EmployeeHoursResponse"/>
invoke示例
- receive元素
receive元素允许我们建立流程服务期望从外部客户端伙伴服务中接受请求的信息。
Receive元素包含了一组属性,主要是用来将要进行的通信。
l partnerLink:在相应的partnerLink结构中识别客户端伙伴服务
l portType:流程服务中的portType会从伙伴服务中等待接受请求信息
l operation: 将会接收请求的流程服务操作
l variable:接收的请求消息将会被存储在流程定义的variable结构中
l createInstance:当将此属性设置成”yes”时,请求可能要创建新的进程实例
receive元素同样可以用于在异步消息交换的过程中的回调消息。
- reply元素
在同步通信中,receive元素和reply元素是成对出现的。Reply元素负责建立关于返回响应消息到所要求的客户端伙伴服务的细节。Reply元素要和它相应的receive元素有同一的partnerLink元素。
它和receive元素有很多相同的属性,这只列出有所不同的:
l variable:流程服务的variable元素拥有返回到伙伴服务消息
l messageExchange:这个是在BPEL2.0中增加的可选属性。它明确允许与消息活动相关联的reply元素能接收消息。
- switch、case与otherwise元素
这三个活动元素主要是表示流程逻辑中的条件选择,就好比java、C/C++中的switch和if/else,在switch中多个case元素能够嵌套,通过检查case中的condition属性中描述的布尔表达式。若为”true”,就执行在case中的活动。
当前面所有的case条件失败时,将执行otherwise结构中的活动。
- assign、copy、from和to元素
这些元素是我们能够在变量之间赋值,从而我们可以在整个进程来传送数据。
<assign>
<copy>
<from variable="TimesheetSubmissionFailedMessage"/>
<to variable="EmployeeNotificationMessage"/>
</copy>
</assign>
Assign结构示例
Copy结构可以处理各种数据传输函数,例如可以抽取部分消息到变量中。From与to元素同样也可以包含可选的part与query属性,允许引用变量的特定的部分或特定的值。
- faultHandlers、catch与catchAll元素
faultHandlers结构可以包含多个catch元素,每个元素都为特定类型的错误进行异常处理。通过接受WSDL定义的故障消息来生成故障,或者通过使用throw元素明确触发故障。而catchAll元素主要是提供默认的错误处理活动。
<faultHandlers>
<catch faultName="SomethingHappened"
faultVariable="TimesheetFault">
.....
</catch>
<catchAll>
.....
</catchAll>
</faultHandlers>
faultHandlers示例
- compensationHandler元素
当所表明的条件发生时,加入一些活动以证明补偿的正当性。这些活动保留在compensationHandler结构中。
- correlationSets元素
主要是用来实现相关性,特别是实现消息和进程实例的相关。消息可以属于多个correlationSets元素。从而也可以在WSDL中定义消息属性。
- flow元素
flow结构允许定义一些系列会并发的活动。可以使用子元素link来定义flow结构中的活动之间的从属关系。
- while元素