了解 Web 服务规范: 第 7 部分:Web 服务业务流程执行语言

开始之前

本教程面向使用 Web 服务构建应用程序的开发人员。随着 Web 服务越来越流行,开发人员常常需要创建用于协调多个 Web 服务的程序,以处理业务流程。本文重点关注于 WS-BPEL,它是一个很重要的标准,为这一问题提供了可靠的解决方案,并且成为开发人员常见的选择。

为了完成本教程的学习,您应该对简单对象访问协议 (SOAP) 以及相关的技术(如 WSDL)有基本的了解。要更好地了解这些内容,可以阅读本系列文章的前五部分教程,特别是第 1 部分和第 2 部分。

关于本系列

本系列教程以假想的报社 Daily Moon 为例;为了提高在竞争激烈的环境中的工作效率,其员工将使用各种 Web 服务来创建工作流系统,我们将在此过程中讲述各个 Web 服务基本概念。

第 1 部分比较简单,介绍了 Web 服务背后的基本概念,并演示如何使用 SOAP(以后要讨论的大部分内容的基础规范)来将 Classifieds Department 连接到内容管理系统。

第 2 部分进一步深入介绍了如何使用 Web 服务描述语言(Web Services Description Language,WSDL)定义 Web 服务产生的消息,从而使团队更方便地创建服务以及连接到服务的客户机。

在第 3 部分中,团队希望准备一系列服务,并希望能方便地查找这些服务。与此对应,统一描述、发现和集成(Universal Description, Discovery and Integration,UDDI)提供了可用服务的可搜索注册中心,以便使自己的服务为其他人所注意。

在第 4 部分中,Daily Moon 的发行人 Rudy 决定报社需要为访问其内部系统的 Web 服务制订更好的安全过程。

第 5 部分介绍了团队为了访问这些刚提供了安全保护的服务需要进行哪些更改。

第 6 部分提供了关于构建和验证可互操作的 Web 服务的内容。报社的员工希望能够获得尽可能多的读者,所以他们决定分析他们的 Web 服务,以确保任何想要使用这些 Web 服务的人都能轻松地使用它们。

第 7 部分将介绍 Web 服务业务流程执行语言 (WS-BPEL),并描述了如何通过协调单个服务,使用该语言创建复杂的应用程序。

回页首

关于本教程

在 Web 服务教程系列文章的第 7 部分中,我们发现 Daily Moon 的员工努力地构建这样的应用程序,以使得从客户那里接收分类广告的流程实现自动化。Daily Moon 与某家银行有业务关系,并且员工很希望拥有接收分类广告并且自动地将付款存放入到银行的应用程序。幸运的是,这家与员工有工作联系的银行拥有能用于实现这种存款业务的 Web 服务。员工对这一问题进行研究,并且决定尝试使用 WS-BPEL 以将他们的内部分类广告 Web 服务与银行的 Web 服务紧密联系在一起。有了这两种服务,员工就可以为想象中的业务流程建模,并且构建处理它的应用程序。

本教程向您介绍了关于构建用于协调现有的 Web 服务的复杂应用程序的内容。按这种方式组合 Web 服务,您可以快速地使用大量实用工具程序来构建应用程序。Web 服务的特点是易于发现并易于使用,要构建功能强大的新应用程序,很自然地就会与 Web 服务联系起来。

回页首

先决条件

本教程中所使用的代码并不专门针对任何特定的编程语言或者环境。本教程提供的示例与本教程系列所使用的示例相同。为了完成这些示例的学习,您需要安装下面的软件:

Java 2 Standard Edition 1.4.2 或者更高版本,与您在本教程中构建的服务和客户机一样,所有这些工具都是基于 Java 的。

Apache Axis2 version 1.0,Axis2 是一种功能齐全的 SOAP 工具包,它提供了多种 Web 服务 API(包括 SOAP 和 WSDL)的实现。当涉及到 Web 服务的开发时,像 Axis2 这样的工具包是非常有用的。对于其他编程语言和环境,也存在一些功能范围类似的工具包。Apache 的 Axis 项目有很长的历史,它起源于一项名为 SOAP4J 的 IBM 项目。

Apache Geronimo 或者另一种应用服务器,本系列教程中使用了 Apache Geronimo J2EE 服务器(即 IBM WebSphere® Community Edition 服务器的基础)。您可以使用其他应用服务器来代替,但 Geronimo 是一种简单的、轻量级的、并且可以免费获得的应用服务器,所以对于迅速构建和运行,它是一个很好的选择。

BPWS4J version 2.1,这是 IBM 提供的 BPEL 运行时,它使得您能够运行使用 WS-BPEL 所编写的流程。BPWS4J 的试用期为 90 天。


概述

本教程以业务流程的概述和业务流程执行方面重要技术发展作为开始。

了解当今的业务计算

大多数业务应用程序的存在都是为了简化曾经通过墨水、纸张和人力来完成的处理过程,或者使这一处理过程实现自动化。以前,会计师手工进行计算,使用笔和纸将计算结果记录在分类帐目中,并且频繁地往返于银行。而经纪人则每天重复着一些相似的且单调乏味的任务,银行家、保险精算师、架构师和工程师也都是如此。计算机的应用一直对业务有很大的影响。许多公司采用了 Web 服务,并且日趋成熟,这成为了数十年来科技进步的巅峰时期。许多重要的基础机构(如银行),正在为他们的合作伙伴提供 Web 服务,而合作伙伴可以利用这些 Web 服务,比以往任何时候都更加紧密和有效地组合他们的业务。

每次当您在网上购物时,这种机构组织之间的密切协作的优势就非常明显。显然,业务计算在未来将持续发展。为合作伙伴提供可用的业务,这将获得更大的成功机会,因为这些业务是合作伙伴的业务流程中重要的组成部分。在业务方面,这并不是一个全新的观念,但是软件功能的发展使得人们现在可以快速地实现新的业务,以完成过去单调乏味的工作。

处理颠覆性的技术

要跟上计算机技术的前进步伐并不容易。软件领域似乎每天都在发生着变化。要想编写最新的 Web 服务,软件开发人员需要了解很多相关内容,这主要是因为基础技术变化得太快。Internet 是最近的颠覆性技术,它向所有类型的业务提出了挑战。

技术的飞速发展有助于应用最新的 Web 服务,而这些 Web 服务使用与语言无关的 XML 进行定义,并且重点关注于消息,而无需进行更多的假设或规定。这种方法可以将应用程序与 Internet 软件开发人员所面临的不断变化隔离开来。

Web 服务开发人员能够通过 Web 服务描述隐藏具体的实现,并且可以按照需要对其进行更改。Web 服务的使用者依靠 Web 服务描述以将它们从服务实现的更改中隔离开来。在大多数情况下,您并不知道(或者不需要知道)所使用的服务是如何构建的。

随着 Web 服务越来越流行,最终您将发现,服务的构建和使用将出现在相同的应用程序中。如今常见的联机存储便是一个很好的佐证。如果您正在构建像 Daily Moon 分类服务那样的 Web 服务,那么您可以从希望购买分类广告的个人那里接收相关信息。如果这个广告请求中包含付款信息,那么可以交给银行 Web 服务来进行处理。近来十分流行通过组合 其他有价值的服务来构建服务。

对于使用现有的 Web 服务以处理重要业务流程的应用程序,使用某种方法对其进行描述是非常有用的。如果这种用于描述服务的方法是与语言无关的,并且能够对应用程序进行扩展以使 Web 服务为其使用者和实现者提供相同的优点,那么将更为合适。

本教程介绍了 Web 服务业务流程执行语言 (WS-BPEL),该语言提供一种与语言无关的工具,以便通过组合现有的 Web 服务来构建新的 Web 服务。

回页首

已完成的工作

本系列教程逐步说明了虚构的 Daily Moon 报社的员工将其日常操作更改为基于 Web 服务的系统的过程。在第 1 部分中,Classifieds Department 通过与内容管理系统交互了解了 SOAP 的相关信息,在第 2 部分中,他们创建了自己的服务,并使用 Web 服务描述语言 (WSDL) 对其进行描述。然后,在第 3 部分,他们了解了如何与 UDDI 注册中心交互,并了解了如何在其中查找数据,而这最终使他们为自己的公司创建了一个注册中心,以支持其他组织与 Daily Moon 进行交互。在第 4 部分中,由于 Rudy 坚持要求他的同事 Gene 和 Francis 提供防止系统非授权访问的方法,因此 Gene 和 Francis 必须为其 Web 服务实现 WS-Security。在第 5 部分中,Rudy 意识到他需要为 Web 服务定义相应的规则,以强制客户按照规定的方式访问 Daily Moon 的 Web 服务,从而确保在本系列文章第 4 部分中构建的安全体系。在第 6 部分中,Phil 确保了 WSDL 文档和它所描述的分类 Web 服务与其他 Web 服务之间具有可互操作性。

现在继续这个有关 Daily Moon 员工的例子,本教程描述了这些员工尝试构建一个 Web 服务,以使得报社内分类广告购买的流程实现自动化。本教程向您介绍了 WS-BPEL 以及业务流程建模中的重要概念。


互操作性概述

在深入介绍 WS-BPEL 细节内容之前,本文将引导您按照业务流程的方式进行思考。然后,本文将介绍 WS-BPEL,并讨论组合 Web 服务以构建新的应用程序的方法。您将了解 WS-BPEL 如何使用 Web 服务标准来完成这一工作,而您已经在使用假想的 Daily Moon报社作为示例的系列教程中学习了这些 Web 服务标准。

了解目标

每当您在进行一项工作时,您都是在执行一个流程。无论您是在对收藏的 DVD 进行排序、种植一棵新树、或者运输包裹,都可以通过标识参与者、他们的活动、以及在这一过程中使用的构件来描述您所执行的流程。

在业务领域中,出于多方面的原因,理解流程是很重要的。首要且显而易见的原因是,了解业务流程有助于改善这些流程、节约时间和资金。业务分析师坚持不懈地仔细检查业务流程,寻找提高效率和节约成本的方法。了解业务流程的另一个重要原因是,这些流程常常是重要的知识资产。许多公司能够取得成功,正是由于他们出众的知识,而不是任何有形资产或产品。对于这些组织而言,为其流程编写目录以便能够理解、改善和保护这些流程,这是非常重要的。

有必要学习更多关于业务流程以及如何对其进行建模的内容,如以下部分所示。

了解历史

按照业务流程的方式进行思考,这并不是一个全新的观念。企业必须能够处理日常的管理工作,并考虑如何去完成这些工作,以便维持业务的开展并变得更加高效。如今,企业将注意力集中于如何描述所使用的流程、如何设计新的业务流程、如何执行每个流程、以及如何为以后的深入研究收集有关业务流程的信息。

软件对于业务流程驱动的观点有很大的影响。大多数业务软件存在的目的是使得以前靠手工完成的流程实现自动化。软件已经从最初的电子表格和字处理软件发展为精心设计的客户关系管理软件和面向服务的体系结构。随着软件技术的发展,越来越多的业务流程已经可以实现完全的动化。

因为 Web 服务的广泛采用,所以可以考虑为跨 Web 服务的业务流程实现自动化。例如,某个公司可能拥有自动化订单处理系统、计费系统和执行系统,所有这些系统都提供了 Web 服务接口。有了这些 Web 服务,就能够构建一个应用程序以便使得它们之间的交互实现自动化;例如,可以自动地从客户那里接受并完成一项订单。通过这种方式,Web 服务已经成为用于集成企业应用程序的一项重要技术。

可以使用相同的方法来构建应用程序,这些应用程序依赖于不同的组织所拥有和运行的应用程序。现在,Web 服务为最新的跨企业的业务流程应用程序提供了一个很好的平台。

回页首

探索业务流程管理

现在,业务流程管理是设计、部署和使用各种标准技术监视业务流程的规范。现在的业务流程管理在很大程度上与 Web 服务和本系列教程中所介绍的技术体系有关,这并不足为奇。

业务流程管理领域中最大的进步之一是,描述业务流程的标准方式的创建。最初,如果某个组织需要构建运行业务流程的软件,那么可以使用 Java 或者另一种编程语言来完成。现在,可以通过描述业务流程的标准技术来实现。还有一些用于执行业务流程(来自标准化的描述)的运行时环境。

接下来的部分描述了与业务流程管理相关的主要活动,以及一些用于描述和执行重要的业务逻辑的工具。

回页首

发现和设计流程

作为一名软件专业人员,您一定曾参加过这样的会议,其中一位专家竭尽全力地描述某个应用程序将如何工作。通常,他会在白板上绘制相关的图表,标识所有的重要参与者、活动以及业务流程所涉及到的各种构件。这些图形细化为开发人员询问的问题和所展示的假想场景。

业务流程设计是一个反复的过程,所以通过某些方式记下流程并且对其进行存储,以便以后能够再次调用它以进行改进,这一点是非常重要的。业务需求可能随时间发生更改,因此拥有业务流程存储库以及用于查看和更改它们的标准工具是非常重要的。目前已经存在这样的工具。WS-BPEL 是一种用于编写业务流程的重要工具,以便我们能够查看、更新和执行这些业务流程。

回页首

执行流程

在定义了业务流程之后,就可以构建执行它们的软件系统。可以将使用 WS-BPEL 编写的业务流程作为脚本,应用于业务流程管理应用程序并加以执行。这种方法有很多优点,其中最大的优点就是,使用它可以简化创建和更新业务流程的工作。WS-BPEL 是一种用于从现有的 Web 服务构建应用程序的脚本语言。服务描述本身是可执行的脚本,其中描述了 WS-BPEL 运行时环境能够执行的流程流。

回页首

监视

在使用标准的语言将业务流程编写到脚本中,并在业务流程管理应用程序中加以执行之后,就可以很容易地对其进行监控了。这种监控方式能够为应用程序所执行的每个业务流程实例提供大量的报告信息。例如,您可以要求流程管理应用程序提供有关正在进行处理的当前流程和已经完成的流程的状态。您可以使用业务流程应用程序来收集相关的信息,以便能够轻松地解答许多业务问题,如果不使用这种方法,您将很难找到这些业务问题的答案。


WS-BPEL 介绍

使用正式和标准的语言来描述业务流程,这个观念由来已久。到目前为止,有许多可用于完成此项任务的竞争性标准,包括 IBM 的 Web 服务流语言 (WSFL)、Microsoft 的 XLANG、以及许多其他标准。最后,结合 WSFL 和 XLANG 的优点而创建了 WS-BPEL。在这类标准中,它已成为最流行的标准。

概述

WS-BPEL 依赖于各种各样的标准技术,您或许已经很熟悉这些技术,具体包括:

  • WSDL
  • XML 模式
  • Xpath
  • Web 服务寻址

WSDL 是这些标准中最为重要的,因为 WS-BPEL 将业务流程描述为 Web 服务间的会话,而这些 Web 服务使用 WSDL 进行描述。此外,WS-BPEL 流程是 WSDL 描述的 Web 服务。

学习这种语言

WS-BPEL 是一种 XML 编程语言。在 WS-BPEL 中,可以在业务流程执行环境所执行的 XML 文档中对业务流程进行描述。WS-BPEL 中的一个流程可以分解为一系列称作活动 的操作步骤。所支持的活动的列表如下所示。

  • invoke——在现有的 Web 服务上调用一项操作
  • receive——等待来自外部实体的消息
  • reply——产生一条应答外部实体的消息
  • wait——等待一段指定的时间
  • assign——将一个值从源复制到目标
  • throw——引发一个错误
  • terminate——无条件地中止当前流程
  • empty——提供一个 no-op 占位符

可以使用一组附加的语言关键字,对这些基本活动进行组合,以描述业务流程算法。这些关键字提供了 WS-BPEL 语言的结构特性,下面分别列出了这些关键字。

  • sequence——定义一组操作的有序序列
  • switch——提供选择语句,其工作方式类似于 Java 和 C++ 中的 case
  • while——定义一个 while 循环
  • pick——提供选择语句,其工作方式类似于 if
  • flow——封装一组应该并行执行的操作步骤

使用这组关键字,您可以想象到应该如何在 WS-BPEL 中表示业务流程。您将发现,这种简明语法的功能非常强大,并且易于使用。



流程组合模型

如前所述,可以通过标识参与者、活动、以及其中所涉及的构件来描述业务流程。Web 服务可以是业务流程中的参与者。通常,多个 Web 服务共同协作,以实现一个单独的业务流程。

将流程定义为服务

当您使用 WS-BPEL 定义业务流程,并将其应用于 WS-BPEL 运行时环境中时,您的业务流程将作为自带 WSDL 文档的 Web 服务公开,并根据您的设计方案做好了运行的准备。您的流程定义或许规定了一个或多个与其他 Web 服务的会话,WS-BPEL 使您能够通过组合各种已有的合作伙伴服务,从而高效地创建新的 Web 服务。这是一种构建应用程序的功能强大的方法,特别是在当您的 WS-BPEL Web 服务本身可能用作另一个业务流程的组件的情况下。

从简单的英语开始

作为一个示例,请看 Daily Moon。请记住,这个报社正尝试构建完全自动化的服务,以便处理读者所创建的新的分类广告。Daily Moon 的员工已经构建了自己的 Web 服务用于创建分类广告。现在,员工有了从银行那里获得的描述 Web 服务的 WSDL,他们可以使用这个 Web 服务为用户所创建的每个分类广告存放支付款。他们使用简单的英语文本来描述其流程,并以此作为开始。

  • 最终用户应用程序使用有关创建分类广告和对分类广告进行支付的信息来调用 Daily Moon

  • 将所提供的支付信息提交给银行进行处理。

    • 如果银行批准了该付款,那么再调用分类广告服务以处理所请求的分类广告。在创建了分类广告之后,会向调用者发送一条成功的消息。

    • 如果银行拒绝了该付款,那么将不再进行后续的处理。在这种情况下,会向调用者发送相应的消息以告知他支付失败。

回页首

使用 WSDL

首先构建用以描述最终将公开的端点的 WSDL,而终端用户将调用这个端点以实现对您的业务流程的调用。要创建这个 WSDL,首先定义为实现 Daily Moon 分类处理而使用的不同的消息类型。对于这个示例,其中定义了:

  1. 用于与分类服务进行通信的消息 (classifiedMessage)
  2. 用于与银行服务进行通信的消息 (bankMessage)
  3. 用户用于启动业务流程的消息 (classifiedInfoMessage)
  4. 在业务流程处理期间碰到错误时所使用的消息。

清单 1 显示了包括这些消息的 WSDL 定义。


清单 1. 带有用于 Daily Moon 业务流程消息定义的 WSDL
                    <definitions targetNamespace="http://tempuri.org/services/classifieddefinitions"             xmlns:tns="http://tempuri.org/services/classifieddefinitions"             xmlns:xsd="http://www.w3.org/2001/XMLSchema"             xmlns="http://schemas.xmlsoap.org/wsdl/"><message name="classifiedMessage">  <part name="classifiedName" type="xsd:string"/>   <part name="amount" type="xsd:int"/></message><message name="bankMessage">    <part name="userName" type="xsd:string"/>    <part name="amount" type="xsd:int"/></message><message name="classifiedInfoMessage">    <part name="classifiedName" type="xsd:string"/>    <part name="userName" type="xsd:string"/>    <part name="amount" type="xsd:int"/></message><message name="classifiedErrorMessage">    <part name="errorCode" type="xsd:int"/></message></definitions>

然后,与分类和银行服务的定义一起,将这组 WSDL 消息定义导入到另一个 WSDL 文档中。清单 2 中显示了结果 WSDL。


清单 2. 导入消息定义和分类以及银行 Web 服务的 WSDL 的父 WSDL
                    <definitions       targetNamespace="http://tempuri.org/services/wsdl/classified-approval"      xmlns="http://schemas.xmlsoap.org/wsdl/"      xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"            xmlns:xsd="http://www.w3.org/2001/XMLSchema"      xmlns:lns="http://tempuri.org/services/wsdl/classified-approval"      xmlns:asns="http://tempuri.org/services/classifiedservice"      xmlns:apns="http://tempuri.org/services/bankservice"      xmlns:loandef="http://tempuri.org/services/classifieddefinitions">  <import namespace="http://tempuri.org/services/classifiedservice" location="http://localhost:8080/myservices/service/classifiedservice.wsdl"/>  <import namespace="http://tempuri.org/services/bankservice" location="http://localhost:8080/myservices/service/bankservice.wsdl"/>  <import namespace="http://tempuri.org/services/classifieddefinitions" location="http://localhost:8080/myservices/service/classifieddefinitions.wsdl"/>    <plnk:partnerLinkType name="bankLinkType">    <plnk:role name="bank">      <plnk:portType name="apns:bankPT"/>    </plnk:role>  </plnk:partnerLinkType>  <plnk:partnerLinkType name="classifiedLinkType">    <plnk:role name="classified">      <plnk:portType name="asns:classifiedPT"/>    </plnk:role>  </plnk:partnerLinkType>  <!-- The service name and the TNS represent my service ID QName -->  <service name="bookClassifiedServiceBP"/></definitions>

在 WS-BPEL 中,将流程中所涉及的所有 Web 服务称为合作伙伴 Web 服务。在清单 2 中,您可以看到 WSDL partnerLinkType 的定义,用以标识两个合作伙伴:银行 分类 服务,以及如何将它们连接到各自的端口类型,在 WSDL 文档中对这些端口类型进行了定义。清单 2 中的最后一项内容是为我们的业务流程指定一个服务名称。

回页首

定义 BPEL

现在您已经完成了 WSDL,下面将进行 BPEL 定义。您正在实现的业务流程描述了两个现有的 Web 服务之间的协调。下面需要完成的工作是,按照特定的顺序来调用所涉及到的每个服务,并且传递它们产生的消息。现在,可以使用您最喜爱的编程语言来实现这个逻辑流。学习到这里,您已经了解编写这样的 Java 程序其实是非常容易的。

WS-BPEL 为实现您的业务流程算法提供了一种非常具有吸引力的选择。WS-BPEL 可以作为脚本语言,用于协调一系列 Web 服务。您不仅可以将合适的 Web 服务调用编写为脚本,还可以将结果脚本公开为 Web 服务本身,而完成这些操作只需要进行很少的工作。另外,与用于完成相同任务的编程代码相比,作为一种 XML 语言,WS-BPEL 流程定义更容易更改、更加简明、更易于理解。

回页首

组织文档的结构

BPEL 流程定义于 <process> 元素之中。首先将这个元素添加到您的文件中,如清单 3 所示。


清单 3. BPEL 描述的主要元素
                    <process name="bookClassifiedProcess"><!-- Definition goes here --></process>

流程元素中包含三个主要部分。

创建 BPEL 定义中的第一个部分

第一个部分列出了参与该业务流程的合作伙伴。对于 Daily Moon 示例,具体包括:

  • 分类广告 Web 服务
  • 银行 Web 服务
  • 启动业务流程的最终用户

清单 4 显示了 Daily Moon 业务流程的相关合作伙伴声明。出于可读性的原因,其中删除了命名空间的定义。


清单 4. 带有合作伙伴链接的流程描述
                    <partnerLinks>  <partnerLink name="customer"            partnerLinkType="lns:bankLinkType"           myRole="bank"/>  <partnerLink name="bank"            partnerLinkType="lns:bankLinkType"           partnerRole="bank"/>  <partnerLink name="classified"            partnerLinkType="lns:bookLinkType"           partnerRole="classified"/></partnerLinks>

第一个合作伙伴对应于发起这项业务流程的客户。第二个合作伙伴是银行 Web 服务。第三个合作伙伴是分类 Web 服务。

创建 BPEL 定义中的第二个部分

BPEL 定义中的第二个主要部分创建了一些占位符,在业务流程的执行期间,这些占位符用于合作伙伴之间生成和传递的消息。对于Daily Moon 示例,其中所涉及到的消息包括:

  • 启动业务流程的原始消息,它称为 request 消息。
  • 发送到银行服务以处理支付的消息,它称为 bankMessage 消息。
  • 银行服务用于进行响应的消息,它称为 bankapprovalInfo 消息。
  • (可能)发送给分类服务的消息,它称为 classifiedMessage 消息。
  • 分类服务用于进行响应的消息,它称为 approvalInfo 消息。
  • 在业务流程执行期间碰到错误时的错误消息,它称为 error 消息。

清单 5 显示了 BPEL 描述中的变量定义。在每个示例中,都提供了一个符号名称和一个 WSDL 消息类型。


清单 5. 用于保留业务流程中相关消息的变量定义
                    <variables>  <variable name="request" messageType="classifieddef:classifiedInfoMessage"/>  <variable name="classifiedMessage" messageType="classifieddef:classifiedMessage"/>  <variable name="bankMessage" messageType="classifieddef:bankMessage"/>  <variable name="approvalInfo" messageType="apns:approvalMessage"/>  <variable name="bankapprovalInfo" messageType="asns:approvalMessage"/>  <variable name="error" messageType="classifieddef:classifiedErrorMessage"/></variables>

创建 BPEL 定义中的第三个部分

BPEL 定义中的第三个主要部分用于描述业务流程算法。该算法使用前面介绍过的 BPEL 语言的活动和结构组件来表示。

对业务流程算法进行转换的工作非常简单。您将按特定的顺序执行一个步骤序列,所以下面以清单 6 所显示的序列元素开始。大多数业务流程都建模为序列。


清单 6. 建模为活动序列的业务流程
                    <sequence><!-- Do something interesting --> </sequence>

根据您的算法,第一个活动是从客户那里接受或者接收一个请求。可以使用 <receive> 元素来表示这项活动,如清单 7 所示。


清单 7. 显示接收一条客户消息的序列
                    <sequence>  <receive name="receive1"        partnerLink="customer"         portType="asns:bankPT"         operation="depositToBank"        variable="request"        createInstance="yes">  </receive><!-- Do something interesting --> </sequence>

这个接收活动中重要的部分是,确定您从哪个合作伙伴那里接收消息,以及您将接收到的消息存储到哪个变量中。从本质上讲,这个声明表示“等待在端口类型 BankPT 上调用 depositToBank,并且当这种情况发生时,在变量 request 中存储消息”。

接下来需要做的事情是,从请求消息中将信息复制到将要使用的一些其他消息中。清单 8 显示了用于完成这项任务的一系列赋值活动。


清单 8. 从一个消息中将状态信息复制到另一个消息的赋值活动
                    <assign name="assignclassified">   <copy>      <from variable="request" part="classifiedName"/>      <to variable="classifiedMessage" part="classifiedName"/>   </copy>      <copy>      <from variable="request" part="amount"/>      <to variable="classifiedMessage" part="amount"/>   </copy></assign><assign name="assignbank">   <copy>      <from variable="request" part="userName"/>      <to variable="bankMessage" part="userName"/>   </copy>   <copy>      <from variable="request" part="amount"/>      <to variable="bankMessage" part="amount"/>   </copy></assign>

通过从初始请求中复制 classifiedNameamount  userName 信息,上述的赋值活动准备好了 classifiedMessage  bankMessage

现在您已经准备好调用银行 Web 服务,以便处理来自客户的付款。清单 9 显示了对银行 Web 服务的调用活动的定义。


清单 9. 规定了对银行 Web 服务调用的调用活动
                    <invoke name="invokeBank"        partnerLink="bank"         portType="asns:bankPT"         operation="depositToBank"        inputVariable="bankMessage"          outputVariable="bankapprovalInfo"></invoke>

这项工作很容易理解。它简单地将 bankMessage 发送到 bankPT 并调用 depositToBank 操作,同时在 bankapprovalInfo 中存储响应。

下一步操作依赖于上述的 invokeBank 活动的结果。我们使用一个 switch 语句以处理条件逻辑和一个称为 getVariableData 的特殊 BPEL 函数,以便检查银行批准消息的状态。清单 10 显示了这个对可能的结果进行处理的 switch 语句。


清单 10. 用以处理成功或失败银行事务的 switch 语句
                    <switch>  <case condition="bpws:getVariableData('bankapprovalInfo','accept')=1">    <invoke name="invokeClassified"            partnerLink="classified"             portType="apns:classifiedPT"             operation="bookClassified"            inputVariable="classifiedMessage"              outputVariable="approvalInfo">    </invoke>  </case>  <otherwise>    <assign name="assignMessage">      <copy>        <from expression="'Bank payment failed'"/>        <to variable="approvalInfo" part="accept"/>      </copy>    </assign>  </otherwise></switch>

请注意,如果银行的处理不成功,那么清单 10 中的 switch 语句将在 approvalInfo 消息中放置一个错误字符串。

剩下的工作就是对该客户作出响应。如清单 11 所示,这项工作是非常简单的。能够对该客户作出响应是为什么将客户作为合作伙伴列出的一个原因。更复杂的使用场景(涉及回调)是将流程发起人作为合作伙伴列出的另一个重要原因。


清单 11. 发送应答消息给客户以通知业务流程成功完成的应答活动
                    <reply name="reply"       partnerLink="customer"       portType="asns:bankPT"       operation="depositToBank"       variable="approvalInfo"></reply>

唯一的附加项目是错误处理程序,该错误处理程序说明了当 Web 服务调用产生错误时 BPEL 如何进行应对。清单 12 显示了用于处理分类服务引发的错误的错误处理程序的定义。如果碰到这样的错误,该错误程序将立即发送一条错误消息给客户。


清单 12. 错误处理程序的定义,其中规定了在产生错误时终止流程执行
                    <faultHandlers>  <catch faultName="classifiedFault"          faultVariable="error">    <reply partnerLink="customer"           portType="apns:bankPT"            operation="depositToBank"           variable="error"            faultName="invalidRequest"/>  </catch></faultHandlers>

清单 13 显示了完整的 BPEL 文件,该文件实现了 Daily Moon 的业务流程,以便自动地接收分类广告,并向客户收取使用他们所提供的分类 Web 服务和银行所提供的 Web 服务的费用。


清单 13. 完整的 BPEL 流程定义
                    <process name="bookClassifiedProcess"         targetNamespace="http://tempuri.org/classifiedProcess"         suppressJoinFailure="yes"         xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/"         xmlns:lns="http://tempuri.org/services/wsdl/classified-approval"         xmlns:classifieddef="http://tempuri.org/services/classifieddefinitions"          xmlns:asns="http://tempuri.org/services/bankservice"         xmlns:apns="http://tempuri.org/services/classifiedservice">  <variables>    <variable name="request" messageType="classifieddef:classifiedInfoMessage"/>    <variable name="classifiedMessage" messageType="classifieddef:classifiedMessage"/>    <variable name="bankMessage" messageType="classifieddef:bankMessage"/>    <variable name="approvalInfo" messageType="apns:approvalMessage"/>    <variable name="bankapprovalInfo" messageType="asns:approvalMessage"/>    <variable name="error" messageType="classifieddef:classifiedErrorMessage"/>  </variables>  <partnerLinks>    <partnerLink name="customer"                  partnerLinkType="lns:bankLinkType"                 myRole="bank"/>    <partnerLink name="bank"                  partnerLinkType="lns:bankLinkType"                 partnerRole="bank"/>    <partnerLink name="classified"                  partnerLinkType="lns:bookLinkType"                 partnerRole="classified"/>  </partnerLinks>  <faultHandlers>    <catch faultName="classifiedFault"            faultVariable="error">      <reply partnerLink="customer"             portType="apns:bankPT"              operation="depositToBank"             variable="error"              faultName="invalidRequest"/>    </catch>  </faultHandlers><sequence>  <receive name="receive1" partnerLink="customer"            portType="asns:bankPT"            operation="depositToBank" variable="request"           createInstance="yes">  </receive>  <assign name="assignclassified">    <copy>      <from variable="request" part="classifiedName"/>      <to variable="classifiedMessage" part="classifiedName"/>    </copy>       <copy>      <from variable="request" part="amount"/>      <to variable="classifiedMessage" part="amount"/>    </copy>  </assign>  <assign name="assignbank">    <copy>      <from variable="request" part="userName"/>      <to variable="bankMessage" part="userName"/>    </copy>    <copy>      <from variable="request" part="amount"/>      <to variable="bankMessage" part="amount"/>    </copy>  </assign>  <invoke name="invokeBank" partnerLink="bank"           portType="asns:bankPT"           operation="depositToBank"          inputVariable="bankMessage"            outputVariable="bankapprovalInfo">  </invoke>  <switch>    <case condition="bpws:getVariableData('bankapprovalInfo','accept')=1">      <invoke name="invokeClassified"              partnerLink="classified"               portType="apns:classifiedPT"               operation="bookClassified"              inputVariable="classifiedMessage"                outputVariable="approvalInfo">      </invoke>    </case>  <otherwise>    <assign name="assignMessage">      <copy>        <from expression="'Bank payment failed'"/>        <to variable="approvalInfo" part="accept"/>      </copy>    </assign>  </otherwise></switch><reply name="reply"       partnerLink="customer"       portType="asns:bankPT"        operation="depositToBank"       variable="approvalInfo"></reply></sequence></process>

综述

在典型的 WS-BPEL 业务流程的执行过程中,将涉及到许多不同的应用程序。例如,可以将运行中的 Daily Moon WS-BPEL 作为一个例子,其中有下面的部分正在运行:

  • 分类广告 Web 服务
  • 银行的 Web 服务
  • 将运行 WS-BPEL 流程的 WS-BPEL 运行时环境

进行设置

  1. 在相同的 J2EE 服务器上运行这两个 Web 服务和您的 BPEL 运行时环境。

  2. 下载 Geronimo 并安装它。这个示例使用了 Apache 的 Geronimo 服务器,该服务器可以免费使用,并且很容易进行设置。

  3. 下载用于 Web 服务 Java 运行时(或 BPWS4J)的 IBM 业务流程执行语言。BPWS4J 是一个功能齐全的平台,可用于运行以 BPEL 描述的业务流程。下载 bpws4j 引擎 的版本 2.1。

  4. 从 BPWS4J 分发版中复制 bpws4j.war,并将其放入您的 Geronimo 服务器的部署目录。Geronimo 将发现这个新的 Web 应用程序,并自动部署它。现在,使用 URL http://localhost:8080/bpws4j/admin,您应该能够看见 BPWS4J 管理控制台,如图 1 所示。

图 1. BPWS4J 管理控制台
BPWS4J 管理控制台  

正如其中的大按钮所示,这个管理应用程序可以用于部署、列出、删除 BPWS4J 运行时环境中的 WS-BPEL 业务流程。

在部署您的业务流程之前,先部署您的两个 Web 服务:分类 Web 服务和银行 Web 服务。本教程提供了一个代码包,其中包括捆绑了这两个 Web 服务的称为 myservices.war 的单独文件。建立这个包的副本,并将其放入 Geronimo 的部署目录。Geronimo 将发现这个新的包,并部署这两个 Web 服务。

回页首

部署业务流程

对于不同的WS-BPEL 环境,部署业务流程的操作细节也有所不同,但它们都应该是相当简单的。要在 BPWS4J 上部署业务流程,只需要点击几下鼠标即可。

  1. 在 BPWS4J 管理 Web 应用程序中单击 Deploy 按钮。将会提示您提供所创建的 WSDL 和 BPEL 文档,它们分别为您的业务流程和业务流程本身定义了端点。图 2 显示了这项任务。 

    图 2. 提供流程 WSDL 和 BPEL 文件
    提供流程 WSDL 和 BPEL 文件 

  2. 浏览到 bookclassified.wsdl 和 bookclassified.bpel 文件,并选择 Continue Deployment。将会提示您为业务流程中所涉及到的每个合作伙伴服务提供 WSDL,当然,这里的合作伙伴服务就是您的分类和银行服务。如图 3 所示。 

    图 3. 为所有的合作伙伴 Web 服务提供 WSDL
    为所有的合作伙伴 Web 服务提供 WSDL 

  3. 找到这些 WSDL,并选择 Start Service the Process。BPWS4J 将尝试开始执行您的业务流程。图 4 显示了 Daily Moon 业务流程的成功启动。

图 4. 业务流程的启动
业务流程的启动  

回页首

调用业务流程

下一步操作是通过调用业务流程来测试您的服务。当然,这意味着对该服务进行简单的 SOAP 调用,在为服务创建的 WSDL 中对该服务进行了描述。本文包含完成这项调用的一个 Java 程序,以及一个用于测试的简单批处理脚本。为了使这项测试变得简单,可以限定您的银行服务仅接受任何金额超过 30 的付款,而拒绝其他的付款。使用参数值 40 运行一次业务流程,并期待运行成功。使用参数值 20 运行一次业务流程,并期待运行失败。运行结果如清单 14 所示。


清单 14. 调用您的业务流程
                    C:\bpel\client>testcustomer.cmd http://localhost:8080/bpws4j/axisengine classifiedName userName 40successC:\bpel\client>testcustomer.cmd http://localhost:8080/bpws4j/axisengine classifiedName userName 20Bank payment failed

总结

本教程向您介绍了业务流程管理中的 WS-BPEL 和一些实际的概念。Web 服务无处不在,在这种环境中,有必要使用标准的技术通过编写脚本来实现它们之间的交互,以便将它们组合为支持重要业务流程的、功能更强大的 Web 服务。

WS-BPEL 正是一个示例,它说明了通过本系列教程中介绍的标准技术,能够完成哪些任务。这些标准为应用程序开发人员提供了一系列功能强大的工具,以便集成企业业务应用程序,以及构建新型的跨多个企业的应用程序。




你可能感兴趣的:(了解 Web 服务规范: 第 7 部分:Web 服务业务流程执行语言)