BPEL活动浅析

来源:互联网 发布:乐德华巡更软件 编辑:程序博客网 时间:2024/04/30 21:31

BPEL活动(Activity)是指BPEL流程中一条语句或者一个步骤的执行。BPEL常用的一些基本活动如下:

  •   <assign>/<invoke>(赋值/调用);
  •   <condition>/<otherwise>(条件/否则);
  •   <sequence>/<flow>(顺序/并行);
  •   <link>/<source>/<target>(链接/源/目标);
  •   <pick>/< onMessage>/ <onAlarm>(选择/监听/闹钟)。

  下面将予以详细的介绍。

  <receive> /<reply>(接收/恢复)

  接收<receive>是整个BPEL的起点,一旦BPEL引擎从客户端接收到请求消息,它将会启动一个BPEL的流程。

  <receive>的属性如下。

  •   name:定义receive的名称,此处为“request”。
  •   partnerLink:对应于BPEL流程定义的partnerLink的名字,实例如下。

<bpel:partnerLink myRole="HouseLoanBrokerService" name="HouseLoanBroker"

partnerLinkType="tns:HouseLoanBrokerPL"/>

  •   portType:对应于合作伙伴链接中partnerLinkType所定义的WSDL的接口portType。
  •   operation:对应于合作伙伴链接中partnerLinkType所定义的WSDL的接口操作(Operation)。
  •   variable:variable="request"表示客户端的请求消息将会被赋值到所定义的变量“request”中。
  •   createInstance:createInstance="yes"表示BPEL将会创建一个新的实例

  下面是房屋贷款的receive实例:

<bpel:receive name="request" partnerLink="HouseLoanBroker"

portType="tns:HouseLoanBroker" operation="getLoanQuote" variable="request"

createInstance="yes">

</bpel:receive>

  恢复<reply>是整个BPEL的终点,BPEL流程将会把响应结果返回给服务请求者。

  < reply >的属性如下:

  •   name:定义receive的名称,此处为“response”。
  •   partnerLink:对应于BPEL流程定义的partnerLink的名字;

<bpel:partnerLink myRole="HouseLoanBrokerService"

name="HouseLoanBroker" partnerLinkType="tns:HouseLoanBrokerPL"/>

  •   portType:对应于合作伙伴链接中partnerLinkType所定义的WSDL的接口portType。
  •   operation:对应于合作伙伴链接中partnerLinkType所定义的WSDL的接口操作(Operation)。
  •   variable:variable=" response "表示BPEL流程会将结果变量“response”返回给服务请求者。

  下面是房屋贷款的reply的实例:

<bpel:reply name="response" partnerLink="HouseLoanBroker"

portType="tns:HouseLoanBroker" operation="getLoanQuote"

variable="response" />

  <assign> /<invoke>(赋值/调用)

  <assign>赋值和<invoke>调用经常是一前一后的两个任务。这是因为在调用合作伙伴的服务时,需要先给合作伙伴的接口的输入变量赋值,然后再调用服务。

  下面是assign的写法实例,它主要是要定义两个元素,一个是<from>,一个<to>;其过程就是要将<from>变量下的某个参数复制到<to>变量下的某个参数中。值得注意的是,两个参数的类型必须一致。此外,不能将整个变量复制给另一变量,只能复制变量下面的参数。

<bpel:assign>

<bpel:copy>

<bpel:from variable="ca-housenumber-response" part="payload"

query="/ca:getHouseNumberResponse/ca:housenumber" />

<bpel:to variable="bk-loanquote-request" part="payload"

query="/bk:getLoanQuoteRequest/bk:housenumber"/>

</bpel:copy>

</bpel:assign>

  <invoke>调用是BPEL中最重要的活动,其他所有的活动都是为了辅助整个活动,它将会调用合作伙伴的服务,得到返回结果。

  <invoke>的属性如下:

  •   name:定义invoke的名称,此处为“bank0”。
  •   partnerLink:对应于BPEL流程定义的partnerLink的名字,实例如下:

<bpel:partnerLink partnerRole="BankService" name="Bank0"

partnerLinkType="bk:BankPL"/>

  •   portType:对应于合作伙伴链接中partnerLinkType所定义的WSDL的接口portType。
  •   operation:对应于合作伙伴链接中partnerLinkType所定义的WSDL的接口操作(Operation)。
  •   inputVariable:表示在调用合作伙伴服务之前,事先定义并且已经赋值的输入变量。
  •   outputVariable:存储合作伙伴服务调用结果的输出变量。

  下面是房屋贷款的invoke的实例:

<bpel:invoke name="bank0" partnerLink="Bank0"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-0"

sm:endpoint="urn:logicblaze:soa:bank:Bank0:bank" />

  <condition> /<otherwise>(条件/否则)

  <condition> /<otherwise>(条件/否则)是BPEL中的条件语句。因为BPEL是流程管理的程序语言,因此它需要根据不同的条件来调用不同的合作伙伴的服务。<condition> /<otherwise>一般会一起使用,<otherwise>表示上述条件都不满足时的下一步活动。

  <condition>通常会调用getVariableData()来得到变量中某一路径下的参数值,再和常量或者其他变量的参数值进行比较。

  下面是房屋贷款中<condition> /<otherwise>的实例。

  首先是房屋数量为0时的情形的一个分支,调用Bank0的服务。

<bpel:switch>

<bpel:case condition="getVariableData('bk-loanquote-request', 'payload',

'/bk:getLoanQuoteRequest/bk:housenumber') = 0 ">

<bpel:invoke name="bank0" partnerLink="Bank0"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-0"

sm:endpoint="urn:logicblaze:soa:bank:Bank0:bank" />

</bpel:case>

  最后用<otherwise>来实现BPEL条件的最后一个分支,房屋数量大于2时的一个分支。

<bpel:otherwise>

<bpel:invoke name="bank3" partnerLink="Bank3"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-3"

sm:endpoint="urn:logicblaze:soa:bank:Bank3:bank" />

</bpel:otherwise>

</bpel:switch>

<sequence> /<flow>(顺序/并行)

  <sequence>表示两个活动是按顺序一前一后地进行,前面的活动不完成,后面的活动不开始。<flow>表示两个或者多个活动可以并行。

 

  下面是<sequence>的实例,表示必须<receive>完成之后,<reply>才能开始,程序如下:

<bpel:sequence>

<bpel:receive name="request" partnerLink="HouseLoanBroker"

portType="tns:HouseLoanBroker" operation="getLoanQuote" variable="request"

createInstance="yes">

</bpel:receive>

<bpel:reply name="response" partnerLink="HouseLoanBroker"

portType="tns:HouseLoanBroker" operation="getLoanQuote"

variable="response" />

</bpel:sequence>

  下面是<flow>的实例,如果按照下面的写法,表示可以同时调用Bank0和Bank1的服务,程序如下:

<bpel:flow>

<bpel:invoke name="bank0" partnerLink="Bank0"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-0"

sm:endpoint="urn:sample:soa:bank:Bank0:bank" />

<bpel:invoke name="bank1" partnerLink="Bank1"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-1"

sm:endpoint="urn:sample:soa:bank:Bank1:bank" />

</bpel:flow>

  <link> /<source>/<target>(链接/源/目标)

  对于比较复杂的并行的流程,通过链接的定义使得流程能从一个活动跳转到另一个活动。每个<link>链接都会定义一个<source>源和一个<target>目标;如果链接<source>源的转换条件满足的话,将会跳到链接<target>源所在的活动;可以通过transitionCondition来给<source>加上转换条件,如果不加条件,那么认为是true。

  下面将房屋贷款的实例做一点改造来说明这个用法。首先定义两个链接“invoke-bank0”和“invoke-bank1”,它们的<source>源都放在<bpel:assign>的活动中。并通过transitionCondition分别给这两个链的源接加上跳转的条件。如果invoke-bank0的源的条件transitionCondition满足的话(即房屋数量为0),它将会跳转到invoke-bank0的目标所在的活动,即invoke Bank0的活动;同理,如果invoke-bank1的源的transitionCondition转换条件(即房屋数量为1)满足的话,它将会跳转到invoke-bank1的目标所在的活动,即invoke Bank1的活动。

<bpel:flow>

<links>

<link name="invoke-bank0"/>

<link name="invoke-bank1"/>

</links>

 

<bpel:assign>

<bpel:copy>

<bpel:from variable="ca-housenumber-response" part="payload"

query="/ca:getHouseNumberResponse/ca:housenumber" />

<bpel:to variable="bk-loanquote-request" part="payload"

query="/bk:getLoanQuoteRequest/bk:housenumber"/>

</bpel:copy>

<source linkName="invoke-bank0"

transitionCondition="getVariableData('bk-loanquote-request', 'payload',

'/bk:getLoanQuoteRequest/bk:housenumber') = 0 "/>

<source linkName="invoke-bank1"

transitionCondition="getVariableData('bk-loanquote-request', 'payload',

'/bk:getLoanQuoteRequest/bk:housenumber') = 1 "/>

</bpel:assign>

<bpel:invoke name="bank0" partnerLink="Bank0"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-0"

sm:endpoint="urn:sample:soa:bank:Bank0:bank" >

<target linkName="invoke-bank0"/>

</bpel:invoke>

<bpel:invoke name="bank1" partnerLink="Bank1"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-1"

sm:endpoint="urn:sample:soa:bank:Bank1:bank" >

<target linkName="invoke-bank1"/>

</bpel:invoke>

</flow>

  <pick> /< onMessage>/ <onAlarm>(选择/监听/闹钟)

  前面所定义的<receive>是整个BPEL流程的一个起点,BPEL引擎处于一种等待接收客户消息的状态。

  BPEL也可以提供另外一种功能,它可以把接收请求消息作为一种活动来处理,请求消息这个活动只是在某段时间有效,过了这段时间,这个请求消息活动就停止了。

  这种情形在现实生活中很多。我们经常可以看到“报名从什么时间开始,截止到什么时间”等。BPEL是通过<pick>、<onMessage>、<onAlarm>.来实现此功能的。

  下面是修改的房屋贷款的实例。

  <onAlarm for="'P15DT10H' ">先将报警闹钟设为15天10小时。在这个时间之内,<onMessage>都会接收房屋贷款的请求消息,调用Bank服务,将结果返回给客户。一旦过了此时间,就不会再接收房屋贷款的请求消息了。

<bpel:pick createInstance="no" name="house-loan">

<bpel:onMessage name="request"

partnerLink="HouseLoanBroker"

portType="tns:HouseLoanBroker"

operation="getLoanQuote"

variable="request">

……

<bpel:invoke name="bank0" partnerLink="Bank0"

portType="bk:Bank" operation="getLoanQuote"

inputVariable="bk-loanquote-request"

outputVariable="bk-loanquote-response-0"

sm:endpoint="urn:sample:soa:bank:Bank0:bank" />

……

<bpel:reply name="response" partnerLink="HouseLoanBroker"

portType="tns:HouseLoanBroker" operation="getLoanQuote"

variable="response" />

</bpel:onMessage>

<onAlarm for="'P15DT10H' ">

<empty/>

</onAlarm>

</bpel:pick>

原创粉丝点击