内容


使用 WS-BPEL 和 IoC 构建可配置工作流程,第 1 部分

了解动态业务工作流程

一个两层的工作流程模型

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 使用 WS-BPEL 和 IoC 构建可配置工作流程,第 1 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:使用 WS-BPEL 和 IoC 构建可配置工作流程,第 1 部分

敬请期待该系列的后续内容。

业务操作是由按顺序执行的步骤和任务组成的。典型的真实业务工作流程中的任务序列在本质上是动态的:该序列通常不是固定的,依赖于只有在执行期间才能决定的因素。本系列包含两篇文章,示范了如何使用 WS-BPEL 和 IoC 构建可配置的动态业务流程。第 1 部分描述了使用 WS-BPEL 和 IoC 实现业务工作流程的整体架构。第 2 部分将会示范如何使用 WS-BPEL 来实现生产管理工作流程。

我将从解释业务工作流程的动态特性开始讨论。然后,我将提供一个用于构建灵活的工作流程解决方案的两层模型。接下来,您会学到如何使用基于 XML 的 IoC 来实现两层中的一层。最后,我将描述 BPEL 在构建工作流程解决方案过程中的作用。

业务工作流程的本质

我将会以制造为例来示范业务工作流程的动态本质。大多数现实生活中的制造企业都会生产很多种类的产品,这些产品中有些是批量生产而有些则是少量生产的。为此,他们必须将两个相对简单的工作流程合并,来形成一个现实的动态工作流程。

管理生产的简单工作流程

第一个简单的生产工作流程适合于制造多种产品的生产工厂:

  1. 生产部门收到生产指令。
  2. 生产部门从生产指令中提取需要生产的产品清单并获取每一个所需的产品的流程细节。流程细节包含的信息如下:
    • 生产一个产品必须要执行的生产任务
    • 必须部署的制造资源(诸如职员或机器)
    • 合适的制造标准、实践、图纸、程序和质量标准
  3. 生产部门为每一个任务 —— 为了生产所需产品而必须执行的 —— 发布工作指令。每一个工作通知都会附带相关的流程细节。

为了充分利用制造资源,生产多种产品的企业一般都会使用相同的制造资源(诸如装配线和机器)来执行多种工作指令。这也就是每一份工作指令都要附带相关流程信息的原因。流程信息让机器操作员或执行工作指令的软件模块知道应该做什么。

我将称这个三步的任务序列为多种生产工作流程 或者简称为多种工作流程

批量生产工作流程

第二个工作流程适用于大量生产少数几个种类的产品而非多种产品的制造企业。他们通常不需要共享制造资源,因为为每一种产品指定生产资源更为经济。

这样的企业通常都会部署广泛的生产计划程序,导致要为每一种产品制作制造时间表。然后他们向特定的资源发布工作指令,以此来部署他们的制造时间表。

如果一个企业只将自己的生产资源用于生产特定产品,那么它就不需要随工作指令一起传送流程信息了。因此该生产工作流程与多种工作流程有很大差异。考虑一下它的五步任务序列:

  1. 企业的生产部门收到生产指令
  2. 生产部门从生产指令中提取需要生产的产品清单。
  3. 生产部门检查需要生产的产品的制造时间表,并将生产指令的要求与现有的制造时间表进行匹配。
  4. 如果生产部门发现现有制造时间表能够满足新的生产要求,那么它会只保留生产指令上指定的所需数量信息。
  5. 如果现行制造时间表无法满足新的生产要求,生产部门会发布新的工作指令,以满足新的生产指令的生产要求。这种工作指令只需指定要生产的产品,无需指定流程细节。

我将称这个五步的序列为批量生产工作流程

合并多种生产工作流程和批量生产工作流程

在典型的真实制造应用程序中,企业通常都生产多种产品,这些产品中的一些为批量生产。这就意味着他们要将上述两种简单工作流程进行合并使用。例如,下面合并的八步工作流程不仅可以处理批量生产,也可以处理多种生产:

  1. 企业的生产部门收到生产指令。
  2. 生产部门从生产指令中提取需要生产的产品清单。
  3. 生产部门检查生产指令上的每一个产品,决定哪些产品是属于多种生产的范畴的,要用共享资源生产;那些是批量生产的产品,要用指定资源生产。
  4. 生产部门获取每一个属于多种生产的产品的流程细节。
  5. 生产部门为(生产多种生产范畴的产品而需要执行的)每一个任务发布工作指令。每一个工作指令都会附带相关的流程细节。
  6. 生产部门检查每一个属于批量生产的产品的当前的制造时间表。
  7. 如果当前的制造时间表足以满足新的生产要求,生产部门会保留当前的制造时间表中的批量生产产品的所需数量。
  8. 如果现有的制造时间表无法满足新的生产要求,生产部门会发布新的工作指令以满足新的生产指令的生产要求。

这个合并的八步工作流程显示出了业务工作流程的动态本质,因为具体的任务序列只能在运行时决定。例如,考虑一下第 3 步。如果生产部门在这一步发现生产指令不包含多种生产产品,它就会跳过第 4 步和第 5 步,而直接跳入第 6 步。同样,如果生产指令不包含任何批量生产产品,就不会执行第 6、第 7 和第 8 步。

业务工作流程的一个两层模型

业务工作流程的动态本质可以在一个两层的模型中进行分析,如图 1 中的分层结构所示:

图 1. 显示为两层模型的业务工作流程
图 1. 显示为两层模型的业务工作流程

在这里您可以看到,上层实现了流程执行逻辑。该层:

  • 逐个控制和执行工作流程中的每一个任务
  • 确定每一个任务的结果
  • 决定接下来要执行哪一个任务

我将称这个层为流程执行层 或简称为执行层

底层由类组成,每一个类都实现一个独立任务的业务逻辑。我将称这层为独立任务层 或简称为任务层

遵循这个两层策略的主要优势就在于其固有的灵活性。它允许您定义细粒度的任务,可以对这种任务进行配置和重新配置,以满足不断变化的工作流程的要求。

粒度是很重要的。例如,比较多种工作流程的第 2 步和批量生产工作流程的第 2 步。多种工作流程的第 2 步执行两个任务(从生产指令中提取需要生产的产品清单并获取每一个所需产品的流程细节)。批量生产工作流程的第 2 步只执行一个任务(从生产指令中提取需要生产的产品清单)。批量生产工作流程的第 2 步的粒度更细,这使得它可以直接融合到合并的工作流程中。这个例子证明细粒度的任务更能适应不断变化的工作流程的要求。

现在,我将识别细粒度的任务,这种任务形成了合并的八步工作流程的独立任务层。然后我将论述执行层是如何利用任务层来实现完整的合并工作流程的。

识别细粒度任务

下面的细粒度任务列表是从合并的八步工作流程提取出来的,正如该列表所表明的一样,细粒度任务获取输入并执行某一特定的任务。下面的每一个任务都可以作为 图 1 的任务层的一部分,通过 Java™ 类的一个方法来实现:

  1. 将一个生产指令作为输入,并返回需要生产的产品清单。稍后,在 任务层 IoC 配置 部分,我将会配置一个名为 items2BProduced 的 Java bean ,它实现该任务的业务逻辑。
  2. 将一个生产产品的名称或标识符作为输入,并返回该生产产品的类型(即,它是多种生产的产品还是批量生产的产品)。一个名为 typeOfItem 的 Java bean 将会实现这个任务的业务逻辑。
  3. 将多种生产的产品名称或 ID 作为输入,并返回流程细节。processDetails Java bean 将会实现这个任务的业务逻辑。
  4. 将多种生产的产品名称或 ID 作为输入,并发布一个工作指令来生产该产品。该工作指令会附带相关的流程细节。一个名为 largeVarietyWO 的 Java bean 将会实现这个任务的业务逻辑。
  5. 将批量生产的产品的名称或 ID 作为输入,并返回其当前制造时间表。manufacturingSchedule Java bean 将会实现这个任务的业务逻辑。
  6. 将当前的制造时间表和一个批量生产的产品的新的生产要求作为输入,并返回在当前制造时间表下不能生产的新的产量要求。additionalProductionRequirement Java bean 将会实现这个任务的业务逻辑。
  7. 将批量生产的产品的名称或 ID 连同其新的生产要求作为输入,并将该生产要求保留在当前的批量生产的产品的制造时间表中。productionReservation Java bean 将会实现这个任务的业务逻辑。
  8. 将批量生产的产品的名称或 ID 作为输入,并发布一个工作指令,生产当前制造时间表中的产品。bulkProductionWO Java bean 将会实现这个任务的业务逻辑。

每一个实现某一单一流程的 Java bean 都独立于其他 bean 来获得输入并执行该流程。

流程执行层的操作

图 1 中的流程执行层使用了 Java 类,这些类实现了序列中的一个单独的任务,如图 2 所示:

图 2. 合并的生产工作流程的流程执行序列
图 2. 合并的生产工作流程的流程执行序列
图 2. 合并的生产工作流程的流程执行序列

图 2 中的序列如下:

  1. 流程执行层从客户机应用程序收到生产指令。
  2. 流程执行层使用 items2BProduced Java bean 从生产指令中提取需要生产的产品清单。
  3. 对于生产指令里面的每一种产品,流程执行层使用 typeOfItem Java bean 来检查它是属于多种生产还是批量生产范畴。
  4. 对于属于多种生产范畴的产品,流程执行层使用 processDetails Java bean 来获取该产品的流程细节。
  5. 流程执行层使用 largeVarietyWO Java bean 为每一个多种生产的产品发布制造工作指令。
  6. 流程执行层使用 manufacturingSchedule Java bean 为每一个批量生产的产品检查当前制造时间表。
  7. 流程执行层使用 additionalProductionRequirement bean 来检查需要的补充生产的量(即当前制造时间表不能满足的生产),按照生产指令中所要求的量生产出每一个批量生产的产品。
  8. 如果无需补充生产(也就是说当前的制造时间表能够满足所有生产指令中所要求的批量生产的产量),流程执行层会使用 productionReservation bean 来保留当前制造时间表中每一个批量生产的产品的生产要求。
  9. 如果需要补充生产,流程执行层会使用 bulkProductionWO bean 为批量生产的产品发布工作指令。

现在,您应该清楚地了解了独立任务层和流程执行层的业务逻辑了。接下来,我将论述独立任务层和流程执行层的实现策略。

使用 IoC 实现任务层

IoC 用于构建灵活、松散耦合的模块,比如我在前面所描述的独立任务层 Java bean。

基于 XML 的 IoC 实现允许使用 XML 来指定:

  • 应用程序中所使用到的 Java bean
  • 每一个为 bean 指定的 Java 类的名称
  • 一个 bean 所依赖的其他 bean

IoC 实现使用 XML 配置来在对 Java 类进行实例化之前了解哪些类需要实例化,以及按照什么样的顺序。这就意味着如果您使用基于 XML 的 IoC 来配置 bean,您无需为实例化 bean 操心。

使用 IoC 来为独立任务配置 Java 类,您就可以专注于实现 Java 类中的独立任务的业务逻辑。至于任务层的类要如何集成到业务工作流程应用程序中,您不必过问。您只需配置 IoC 实现中的 bean,至于实例化 bean、使之能够应用于流程执行层这些工作,可交由 IoC 框架来完成。

这个技巧有一个很大的优点。改变业务场景有时需要向工作流程添加新的任务。这样的话,就必须为新任务实现新的 Java 类。基于 XMl 的 IoC bean 配置使您能够轻松地将新的类集成到现有的工作流程应用程序中。

这也就意味着基于 XML 的 IoC 允许您对工作流程中的每一个任务的业务逻辑分别进行实现和测试。一旦测试了业务逻辑,就可以通过更新 XML 配置文件来将 bean 集成到工作流程应用程序中。

在本文中,我将使用 Spring Framework,它是一个流行的基于 Java 和 XML 的开源 IoC 实现。(参见 参考资料,查看简要描述 IoC 以及 Spring 的 IoC 实现的文章链接。)

任务层 IoC 配置

清单 1 是一个 Spring XML 配置文件。它展示了如何配置前面部分提到的任务层的八个 Java bean。

清单 1. IoC 的 Spring XML 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <!--Business objects for production management-->

    <bean id="items2BProduced"
        class="sample.wf.Items2BProduced" scope="application" />

    <bean id="typeOfItem"
        class="sample.wf.TypeOfItem" scope="application" />

    <bean id="processDetails"
        class="sample.wf.ProcessDetails" scope="application" />

    <bean id="largeVarietyWO"
        class="sample.wf.LargeVarietyWO" scope="application" />

    <bean id="manufacturingSchedule"
        class="sample.wf.ManufacturingSchedule" scope="application" />

    <bean id="additionalProductionRequirement"
        class="sample.wf.AdditionalProductionRequirement" scope="application" />

    <bean id="productionReservation"
        class="sample.wf.ProductionReservation" scope="application" />

    <bean id="workOrderForBulkProductionItem"
        class="sample.wf.WorkOrderForBulkProductionItem" scope="application" />

</beans>

该列表中含有一个 <beans> 标记,它包装了大量的 <bean> 子标记,每一个标记代表一个 Java bean。每一个 <bean> 标记的 id 属性指定了该 bean 的名称。上述任务层的八个 Java bean 全部都可以在清单 1 中找得到。

例如,看一下第一个 <bean> 标记。其 id 属性的值为 items2BProduced,它实现独立任务层的第一个任务。

您可以看到,items2BProduced <bean> 标记的 class 属性的值为 org.manufacturing.Items2BProduced,它是为 items2BProduced bean 指定的 Java 类的完全限定名。类似地,每一个 <bean> 标记的 class 属性为 bean 指定 Java 类。

现在再回头看一下每一个 <bean> 标记的 scope 属性。scope 属性指定 application 作用域、request 作用域或其他作用域中是否存在一个 bean。如果 application 作用域中存在 bean,Spring 框架会在应用程序启动过程中实例化这些 bean。如果一个 bean 含有 request 作用域,它会在收到请求时被实例化。

所有 bean 都有 application 作用域,因此 Spring 会在启动应用程序时将他们全部实例化。本系列的第 2 部分将深入阐述 Spring 如何完成在 bean 各自的作用域中实例化 bean。

为了简洁,我将八个 bean 的配置都包含在了一个 XML 配置文件中。但在现实中,每一个 bean 都可以在的单独的配置文件中配置,这个配置文件代表着由特殊 bean 提供的服务。

实现流程执行逻辑

您已经看到用于实现业务工作流程中的独立任务的类的配置方式。下面,我将描述如何实现 图 1 的流程执行层。

Spring 的 IoC 框架可以在 servlet 环境中正常运行,这意味着任何 servlet 都可以使用 清单 1 中配置的 IoC bean。可以将流程执行层作为一个单独的 Java 类来实现,任何 servlet 都可以用它按工作流程要求来控制独立任务的序列。

但是,以 Java 类的形式实现(硬编码)流程执行层会导致无法使用 IoC 来实现任务层。回想一下,使用 XML 配置 IoC bean 的最大优点是 IoC 允许轻松将新类集成到现有的工作流程应用程序中。如果以 Java 类的形式硬编码流程执行层,那么这个工作流程就不再是可配置的了。您要不要使用 IoC 来配置任务层呢?

解决方案是在流程执行层也使用 XML。我将使用业务流程执行语言(Business Process Execution Language,WS-BPEL)来构建可配置的流程执行层。WS-BPEL 是一个基于 XML 的标准,由结构化信息标准促进组织(Organization for the Advancement of Structured Information Standards,OASIS)定义,OASIS(顾名思义)定义业务流程的执行(参见 参考资料)。

下一部分描述一个工作流程应用程序的架构,该应用程序将 WS-BPEL 作为流程执行层,在独立任务层使用 IoC。

使用 WS-BPEL 构建可配置的工作流程

图 3 展示了在工作流程应用程序中结合使用 WS-BPEL 和 IoC 的架构:

图 3. 在工作流程应用程序中结合使用 WS-BPEL 和 IoC 的架构
图 3. 在工作流程应用程序中结合使用 WS-BPEL 和 IoC 的架构
图 3. 在工作流程应用程序中结合使用 WS-BPEL 和 IoC 的架构

单击 此处 查看完整图。

在图 3 中可以看到多种组件:

  • 请求客户机:请求客户机指任何向工作流程应用程序发送生产指令并期望可以按生产要求执行生产指令的应用程序。这种客户机应用程序可以存在于制造企业的不同地方。例如,当企业的销售部门从顾客那里收到订单,并发布了生产指令来生产顾客购买的产品时,它就可以担任请求客户机的角色。

    工作流程应用程序提供一个接受生产指令的 Web 服务界面。但在本文中,我使用 Web 服务定义语言(Web Service Definition Language,WSDL)和基于 SOAP 的 Web 服务界面。(参见 参考资料,查看关于 WSDL 和 SOAP 的文章链接。)
  • BPEL 引擎:BPEL 引擎实现流程执行层的执行逻辑。我将使用基于 Java 的开源 BPEL 引擎调用 Apache ODE(参见 参考资料)。第 2 部分将示范如何在 Apache ODE 上保存合并的生产管理工作流程。
  • BPEL 文件和合作伙伴链接:BPEL 文件是一个 XML 文件,您要在该文件中配置流程执行层的业务逻辑。(下一部分将开始论述如何在 BPEL 文件中编写 XML 配置。)BPEL 文件包含实现任务层的合作伙伴服务链接。BPEL 称这些链接为合作伙伴链接。稍候我将在 链接到您的服务合作伙伴 部分详细论述合作伙伴链接。
  • WSDL 文件:您可以在 图 3 中找到 识别细粒度任务 中的每一个 bean 的 WSDL 文件。WSDL 文件为实现任务层的 bean 定义基于 XML 的界面。
  • IoC 框架和 IoC bean:Spring 充当着 IoC 框架,您将把每一个实现任务层的 bean 放置其上。

您现在已经准备就绪了,可以开始学习如何在 BPEL 文件中配置合并的生产工作流程了。

实现流程执行逻辑的 BPEL 文件

BPEL 配置文件可以定义工作流程应用程序的流程执行逻辑。例如,考虑一下清单 2 中的 BPEL 文件,它实现了您在 流程执行层的操作 中看到的流程执行逻辑:

清单 2. 一个 BPEL 文件,执行合并的生产工作流程的流程执行逻辑
<?xml version="1.0" encoding="UTF-8"?>
<process name="MergedProductionWorkflow"
    targetNamespace=http://fictitiousManufacturingEnterprise.com/pms
    queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"
    expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"
    xmlns=http://docs.oasis-open.org/wsbpel/2.0/process/executable
    xmlns:xsd=http://www.w3.org/2001/XMLSchema
    xmlns:pms="http://fictitiousManufacturingEnterprise.com/pms">

  <import />

  <import />

  <!--other import tags--/>

  <partnerLinks />

  <variables />

  <sequence />

</process>

在这个代码中您可以看到,BPEL 文件的根标记是 <process>,它代表整个生产工作流程。<process> 标记有很多属性、名称空间声明和子标记,它们一起定义了 MergedProductionWorkflow 的流程执行逻辑。在 清单 2 中,我将 <process> 标签的子标签展示为空标记。稍后,我会展示每个标记的完整细节。

<process> 标记有四个属性:

  • name 属性的值确定您要配置的工作流程的名称(MergedProductionWorkflow)。您在第 2 部分为工作流程编写可部署的描述符时会涉及到这个名称。
  • targetNamespace 属性指定包含这个 BPEL 文件中使用的所有名称的名称空间。这些名称包括:
    • 工作流程名(MergedProductionWorkflow
    • 用于 BPEL 文件中的合作伙伴链接名
    • 用于保存工作流程数据的变量名
  • queryLanguage 属性指定 BPEL 文件中使用的查询语言。您需要用查询语言来提取和使用来源于合作伙伴服务的工作流程数据(例如,生产指令中要生产的产品)。在第 2 部分中,我将阐述如何在 BPEL 文件中使用 XPath(一种流行的查询语言)。
  • expressionLanguage 属性指定 BPEL 中使用的表达语言。您需要用表达语言来表达工作流程数据上的逻辑和数学运算(例如,检查生产指令中的产品数量是否大于零)。

BPEL 文件中的 <process> 标记还包括几个名称空间声明:

  • 第一个名称空间声明代表 BPEL 名称空间。您需要这个名称空间来使用 OASIS 定义的 BPEL 词汇表。
  • xmlns:xsd 名称空间声明指定 XML Schema 名称空间,您需要它来在 BPEL 文件中使用模式特性。在生产管理中需要的最重要的模式特性是定义自定义数据结构的能力。
  • xmlns:pms 名称空间声明代表生产管理系统的名称空间。您需要在 XML 应用程序中定义您自己的名称空间,这样才能够定义客户元素和属性。您还需要客户名称空间来使用 WSDL 定义以及 BPEL 文件中的端口类型。(参见 参考资料,查看阐述如何在 BPEL 中使用 WSDL 定义的文章链接。)

下面,我将逐个论述 <process> 标记的子标记。

导入外部名称空间

WS-BPEL 提供了一个名为 import 的元素,它允许您将外部名称空间和 WSDL 文件导入 BPEL 文件。在使用在 WSDL 或 XML 模式文档中定义的元素之前导入它们。

清单 3 以展开的形式展示了 清单 2<import> 标记。在这里您可以看到,我在合并的生产工作流程的 BPEL 配置中使用了 10 个 <import> 标记。

清单 3. 清单 2 中的 BPEL 文件的展开形式
<?xml version="1.0" encoding="utf-8" ?>
<process name="MergedProductionWorkflow" xmlns:...>

  <import location="ProductionManagementSystem.xsd"
      namespace="http://fictitiousManufacturingEnterprise.com/pms/"
      importType=" http://www.w3.org/2001/XMLSchema" />

  <import location="ProductionManagementSystem.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms/"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="Items2BProduced.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="TypeOfItem.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="ProcessDetails.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="LargeVarietyWO.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="ManufacturingSchedule.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="AdditionalProductionRequirement.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="ProductionReservation.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <import location="BulkProductionWO.wsdl"
      namespace="http://fictitiousManufacturingEnterprise.com/pms"
      importType="http://schemas.xmlsoap.org/wsdl/" />

  <partnerLinks />

  <variables />

  <sequence />
</process>

清单 3 中的每一个 <import> 标记都有三个属性:

  • location 属性指定导入的文档的 URL。您可以指定一个相对 URL(如 Items2BProduced.wsdl)或绝对 URL(如 http://fictitiousManufacturingEnterprise.com/Items2BProduced.wsdl)。
  • namespace 属性指定导入的 WSDL 或 XML 模式的名称空间。清单 3 中的所有的 <import> 标记的名称空间属性都有一个相同的值(http://fictitiousManufacturingEnterprise.com/pms),这是因为生产管理系统的 XML 模式和 WSDL 文件属于同一名称空间。
  • importType 属性表示导入的文档类型。WS-BPEL 支持导入两种文档。如果导入 XML 模式,importType 属性的值应该为 http://www.w3.org/2001/XMLSchema。如果导入 WSDL 文档,就一定要将 http://schemas.xmlsoap.org/wsdl/ 指定为 importType 属性的值。

清单 3 中的第一个 <import> 标记导入了生产管理模式(一个 XML 模式文件)。第二个 <import> 标记导入了一个名为 ProductionManagementSystem.wsdl 的 WSDL 文件,这个文件代表整个合并的生产工作流程。另外八个 <import> 标记代表您在 识别细粒度任务 中看到的八个任务。

第 2 部分将论述实现合并的生产工作流程所需要的生产管理模式和 WSDL。

链接到您的服务合作伙伴

回忆一下在 使用 WS-BPEL 构建可配置工作流程 部分中的讨论:BPEL 应用程序需要实现任务层的合作伙伴服务。每一个合作伙伴服务都要使用 WSDL 界面来公开其功能。因此,您需要为每一个合作伙伴服务在 BPEL 和 WSDL 文件中定义合作伙伴链接(BPEL-WSDL 链接)。

首先,我将阐述如何在 WSDL 文件中定义 BPEL-WSDL 链接。考虑一下在清单 4 中展示的 WSDL 文件,它公开了 Items2BProduced 合作伙伴服务的功能:

清单 4. 在 WSDL 文件中定义 BPEL-WSDL 链接
<?xml version="1.0" encoding="utf-8" ?>
<wsdl:definitions ...... >

    <wsdl:message name="ProductionOrderMessage" />

    <wsdl:message name="ProductionItemsMessage" />

    <wsdl:portType name="Items2BProducedPortType">
       <wsdl:operation name="getItems2BProduced">
          ......
       </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="Items2BProducedBinding">
        ......
    </wsdl:binding>

    <wsdl:service name="Items2BProducedService">
          ......
    </wsdl:service>

    <plnk:partnerLinkType name="Items2BProducedLinkType">
        <plnk:role name="Items2BProduced_Role"
            portType="list:Items2BProducedPortType"/>
    </plnk:partnerLinkType>

</wsdl:definitions>

这里的 WSDL 文件映射到了在 识别细粒度任务 部分引入的 items2BProduced bean 中。清单 4 定义了名为 getItems2BProduced 的操作,它使用了诸如 <wsdl:types><wsdl:message><wsdl:portType><wsdl:operation> 这样的 WSDL 标记。注意:我省略了这些 WSDL 标记的细节。(参见 参考资料,查看详细讨论 WSDL 标记的文章链接。)

看一下 清单 4<plnk:partnerLinkType> 标记,它属于 OASIS 定义的合作伙伴链接名称空间。<plnk:partnerLinkType> 标记的 name 属性定义了合作伙伴链接的名称(例如,清单 4 中的 Items2BProducedLinkType)。BPEL 中将使用相同的名称来使用该合作伙伴服务。

<plnk:partnerLinkType> 标记有一个名为 <role> 的子标记,该子标记指定合作伙伴服务的业务角色。在 清单 4 中,我把前缀为 _Role 的合作伙伴服务的名称用作了业务角色的名称。

<role> 标记的 portType 属性指定 WSDL 端口,该端口公开该合作伙伴服务的功能。

还需要在 BPEL 文件中定义相同的合作伙伴链接,如清单 5 所示:

清单 5. BPEL 文件中的合作伙伴链接标记
<process xmlns="..">

   <import />

   <!--Other import tags--/>

   <partnerLinks>
       <partnerLink name="mergedProductionWorkflowPartnerLink"
          partnerLinkType="pms:MergedProductionWorkflowLinkType"
          myRole="MergedProductionWorkflow_Role"/>

       <partnerLink name="items2BProducedPartnerLink"
          partnerLinkType="pms:Items2BProducedLinkType"
          partnerRole="Items2BProduced_Role" initializePartnerRole="yes"/>

       <partnerLink name="typeOfItemPartnerLink"
          partnerLinkType="pms:TypeOfItemLinkType"
          partnerRole="TypeOfItem_Role" initializePartnerRole="yes"/>

       <partnerLink name="processDetails"
          partnerLinkType="pms:ProcessDetailsLinkType"
          myRole="ProcessDetails_Role" initializePartnerRole="yes"/>

       <partnerLink name="largeVarietyWOPartnerLink"
          partnerLinkType="pms:LargeVarietyWOLinkType"
          partnerRole="LargeVarietyWO_Role" initializePartnerRole="yes"/>

       <partnerLink name="manufacturingSchedulePartnerLink"
          partnerLinkType="pms:ManufacturingScheduleLinkType"
          partnerRole="ManufacturingSchedule_Role" initializePartnerRole="yes"/>

       <partnerLink name="additionalProductionRequirementPartnerLink"
          partnerLinkType="pms:AdditionalProductionRequirementLinkType"
          partnerRole="AdditionalProductionRequirement_Role" initializePartnerRole="yes"/>

       <partnerLink name="productionReservationPartnerLink"
          partnerLinkType="pms:ProductionReservationLinkType"
          partnerRole="ProductionReservation_Role" initializePartnerRole="yes"/>

       <partnerLink name="bulkProductionWOPartnerLink"
          partnerLinkType="pms:BulkProductionWOLinkType"
          partnerRole="BulkProductionWO_Role" initializePartnerRole="yes"/>

    </partnerLinks>

    <variables />

    <sequence />

</process>

该代码展示了 清单 2 中的 <partnerLinks> 标记的展开形式。<partnerLinks> 含有九个 <partnerLink> 子标记。清单 5 中的第一个 <partnerLink> 标记代表合作伙伴链接 —— 用 ProductionManagementSystem.wsdl 文件(它代表整个合并生产工作流程)。其余的 <partnerLink> 标记用每一个合作伙伴服务代表合作伙伴链接。

结束语

在本系列的第一部分中,我论述了用 BPEL 和 IoC 实现业务工作流程的整个架构。我提供了一个两层的模型来分析静态业务工作流程,并且论述了一个可配置的工作流程应用程序的所有主要组件。

在第 2 部分中,我将展开 清单 5<variables><sequence> 标记,并示范如何使用 WS-BPEL 来实现生产管理工作流程。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology, SOA and web services
ArticleID=324031
ArticleTitle=使用 WS-BPEL 和 IoC 构建可配置工作流程,第 1 部分: 了解动态业务工作流程
publish-date=07282008