在 IBM Business Process Manager 中设计事件驱动的业务流程

IBM® Business Process Manager V7.5.1 引入了对 BPMN 2.0 事件子流程的全新支持。这个强大的结构能够设计一个业务流程来处理计划的事件和意外的事件,能够灵活地处理中断正常处理或需要与主要逻辑流并行处理的事件。在本文中,您将学习如何使用 IBM Business Process Manager 中的事件子流程功能,为特定的流程实例和一组合格的实例分发和处理业务事件。

Fintan McElroy, 高级常务 BPM 顾问, IBM

Fintan McElroy 的照片Fintan McElroy 是一名 IBM Software Services for WebSphere (ISSW) 高级顾问,他的职责是帮助 IBM 的客户采用 WebSphere 产品。Fintan 拥有 18 年的 IT 从业经验,担任过各种职位,包括基础架构构造和设计、应用程序构造、业务分析和应用程序开发。自 BPM with SOA 诞生以来,在它尚未用于面向对象的架构和设计方法中时就是它的积极拥护者。Fintan 目前为 IBM 的客户提供咨询,帮助他们通过采用 IBM Business Process Manager 和相关产品在其企业中实现敏捷性。



2012 年 7 月 30 日

简介

Business Process Modeling and Notation (BPMN) 2.0 标准引入了一种称为事件子流程的新事件处理机制,事件子流程在包含它的流程上下文中运行。事件子流程类似于某个活动上的边界事件,仅在包含流程处于活动状态时监听它的触发信号。流程实例完成后,包含的事件子流程就会停止监听事件。事件子流程类似于其他子流程,因为它们都包含在一个父流程中,并且不可在该流程外重用。但它们与其他子流程也存在区别,因为它们未通过传入或传出连接与流程中的其他活动相连接,只能由在流程或它的子流程中发生的事件触发,或者通过一条外部消息触发。

IBM Business Process Manager 7.5.1 引入了对最常见的事件子流程类别的支持:基于消息的事件、基于时间的事件和异常事件。

  • 基于消息的事件可用于业务消息(比如库存不足消息)由事件子流程接收的情形。
  • 基于时间的事件可用于模拟当父流程中的活动未在指定时间量内完成时执行的步骤。
  • 异常事件可在流程中某处出错时触发,比如订单完成系统无响应。

在 3 种类型中,基于消息的事件提供了最高的灵活性,因为它允许使用来自流程外部的通信来触发事件(例如,一个现有的系统客户端也允许处理 IBM Business Process Manager 流程外部的库存订单)。本文主要介绍基于消息的事件子流程。本文的 下载 部分提供的 BPMN_2.0_Event_Sub-Processes_1.0.twx 文件包含一个示例场景,您可以使用本文中介绍的步骤导入并运行它。


使用消息事件的并发处理

本节将介绍该场景的示例流程,展示如何使用一个基于消息的事件子流程来允许对现有流程实例进行并发更新。

图 1 显示了一个将处理某些产品的客户请求的 Order Process,它首先检查客户是否拥有足够的余额,然后调用一个链接的流程来完成请求的订单。如果订单成功完成,则会向客户发送一张商品发票。Fulfill order 已显式建模为一个独立的流程,因为事件子流程的范围限定在一个流程中,并且在此场景中,我们只希望在完成订单的过程中的一组活动的上下文中执行事件子流程。事件子流程将允许进行订单更新,但是,因为在创建订单前更新订单或在准备开发票时允许更新都是无效的,所以这组活动包含在独立的 Fulfill order 链接流程中。

图 1. 订单流程
订单流程

查看图 1 的大图。)

图 2 显示了 Fulfill order 流程。该流程会检查请求的产品是否有足够的库存,然后提供挑选库存产品并将它运送给客户的步骤。基于消息的事件子流程 Handle order updates 是一个不可中断的事件子流程,这意味着它之中的活动会与主要处理路径并行执行。您可从消息图标周围的虚线中看出它是不可中断的(如下所示)。

图 2. Fulfill Order 链接流程
Fulfill Order 链接流程

双击事件子流程展开它,以显示其中的详细活动,如 图 3 中所示。展开之后,您将在图表顶部看到一个痕迹线索,该线索允许您逆向导航到父流程。Update request 启动事件也包含虚线,这表明它已被设置为不可中断。对于这个简单示例,我们仅将所有更新处理封装在单个人工服务中,但在实际应用中,可能要执行多项复杂的处理来反复检查可用的虚拟余额,然后将更新与原始订单合并在一起。

图 3. Handle order updates 事件子流程
Handle order updates 事件子流程

消息启动事件由一个 Undercover Agent (UCA) 实现,如 图 4 中所示。请注意,Interrupt Parent Process? 设置处于未勾选状态,这会使此事件子流程不可中断。Repeatable? 设置已勾选,从而允许在完成订单步骤正在执行时发送对订单的多项更新。

图 4. 消息事件实现设置
消息事件实现设置

消息事件的属性的 Data Mapping 部分是指定关联的地方,在这里还可以将消息中提供的其他数据映射到流程中的变量,如 图 5 中所示。需要使用关联是为了识别更新所针对的 Order process 的特定实例。在本例中,事件消息提供了一个 orderID 参数,它包含要更新的订单的订单标识符。此外,在事件上提供了一个已更新的订单数据结构,它映射到流程变量 updatesToOrder

图 5. 消息事件数据映射
消息事件数据映射

要演示如何发送一个事件供基于消息的事件子流程进行处理,让我们创建一个订单实例。启动该流程后,您就可以查看该实例并使用 Process Inspector 处理第一个任务,如 图 6 中所示。

图 6. Process Inspector 中的订单流程
Process Inspector 中的订单流程

查看图 6 的大图。)

在结果 Coach 中,如 图 7 中所示,我们将提供一些实例数据。请特别注意用作此标识符的 Order ID 值,以后在模拟流程外部执行的更新时需要关联此值。

图 7. 示例订单细节
图 7. 示例订单细节

查看图 7 的大图。)

返回到 Process Inspector,如 图 8 中所示,您可以看到该流程现在已移动到 Fulfill order 链接流程中。事件子流程 Handle order updates 现在处于范围中,所以您会注意到有一个针对该子流程的标志,这表明该事件子流程已准备好接收消息。

图 8. 事件子流程等待标志
事件子流程等待标志

查看图 8 的大图。)

对于示例场景,我们将提供一个 Coach 来模拟由流程(图 9 中所示的 Send Order Update Event Client)外部的客户端执行的订单的更新。

图 9. 订单更新客户端 Coach
订单更新客户端 Coach

图 10 显示了一个已完成的、用于模拟更新的 Coach 示例。请注意,Order ID 与之前用于创建订单的 ID 匹配。对于这个简单示例,我们仅给出了修订后的订单进行相关演示,但在实际中,我们希望此客户端获取现有的订单,并允许对它进行更新。

图 10. 示例订单更新细节
示例订单更新细节

查看图 10 的大图。)

在 Process Inspector 中,您可以确认 Order 流程的实例已收到事件,如 图 11 所示,并且处理它的并行路径已启动。

图 11. 在 Process Inspector 中更新收到的事件
在 Process Inspector 中更新收到的事件

查看图 11 的大图。)

如果下钻到该事件子流程,如 图 12 中所示,您可以看到 Process order update 任务已做好准备(ID 为 21 的标志),但消息启动事件上还有一个标志(ID 20)。这源于消息事件上的 Repeatable 设置;该标志表示等待进一步更新 UCA,以便在 Fulfill order 流程处于激活状态时触发该消息。

图 12. Process Inspector 中的事件子流程细节
Process Inspector 中的事件子流程细节

查看图 12 的大图。)

为了演示拥有可重复事件的能力,图 13 显示了一种情形,其中的工作已在原始更新时完成,但自那以后执行了另一项更新,并且该事件已由事件子流程接收。

图 13. 进一步更新接收的事件
进一步更新接收的事件

查看图 13 的大图。)

对于此场景,我们完成了这项进一步更新,以及 Fulfill order 的主要处理路径上的任务。如果刷新 Process Inspector 中的视图,如 图 14 中所示,您会看到已经在 Order process 流程中执行了从决策网关出发的 “Shipped” 路径,并且活动 Send invoice 现在正在等待操作。

图 14. Process Inspector Send Invoice 中的 Send Invoice 任务
Process Inspector Send Invoice 中的 Send Invoice 任务

查看图 14 的大图。)

Send invoice 活动已完成,然后完成了该流程的这个实例。我们现在希望继续演示 IBM Business Process Manager V7.5.1 中的事件子流程实现的可能导致意外后果的某个方面。为了演示这种情况,我们想象了以下这种不太可能的场景:在该场景中,可以创建另一个具有相同订单标识符的订单,如 图 15 所示。

图 15. 使用相同 ID 创建后续订单
使用相同 ID 创建后续订单

查看图 14 的大图。)

创建新的订单并在 Process Inspector 中查看该实例的进度(如 图 16 中所示)后,我们现在发现我们遇到了一种意外情形。尽管我们未对此订单执行更新,但我们仍然发现更新事件子流程的两个实例已处于激活状态。回想一下,在前一个示例中,我们对订单执行了两次独立的更新,现在我们似乎在这个新实例上再次收到了这些更新。

图 16. 事件子流程的意外激活
事件子流程的意外激活

查看图 16 的大图。)

解释这种异常现象的关键在于再次查看新消息事件设置,如 图 17 中所示。请注意,默认情况下已经禁用和设置 Durable Subscription 设置,这意味着该消息已被保留,并且可用于任何未来的实例。如果您可以绝对保证您选择关联的业务数据始终是惟一的(而不只是对于活动实例是惟一的),就不会出现这种情况。

图 17. Durable Subscription 设置
Durable Subscription 设置

在下一节中,我们将介绍如何修改我们的流程设计,从而使用一种更安全、有保障的惟一关联机制。在考虑如何分发拥有多个潜在的匹配实例的事件时,这样一种机制的重要性会变得更加明显。


有保障的事件惟一性关联

在这个修改后的设计中,我们将使用一个可保证惟一性的内部 IBM Business Process Manager 关联标识符:流程实例 ID 本身。我们向该流程添加一个私有变量,如 图 18 所示,默认情况下会将它设置为在流程启动时获取实例 ID。

图 18. 流程实例 ID 的默认赋值
流程实例 ID 的默认赋值

因为事件子流程在链接的子流程 Fulfill order 内运行,并且将需要访问流程实例 ID 来关联它,所以您应该将该 ID 作为参数传递给链接的流程,如 图 19 中所示。

图 19. 传递给链接的流程的流程实例 ID
传递给链接的流程的流程实例 ID

图 20 显示了修订后的消息事件,它现在可关联到已传递给 Fulfill order 流程的流程实例 ID。

图 20. 用于关联的流程实例 ID
用于关联的流程实例 ID

我们仍然希望允许客户端使用业务数据来识别要更新的订单,而不是使用来自 IBM Business Process Manager 的内部标识符,因此需要在业务标识符与内部标识符之间进行一定的仲裁。图 21 显示了用于消息事件的 UCA,以及该 UCA 用于传递和处理数据参数的附加服务 (Order Update Event Handler)。

图 21. Order Update UCA
Order Update UCA

如果查看附加的服务的变量,如 图 22 中所示,您会看到系统提供了一个订单标识符 (orderID) 作为输入,但提供了一个流程实例标识符 (orderProcessInstanceID) 作为输出。您会在服务的逻辑中看到此转换是如何发生的。

图 22. 订单更新处理程序变量
订单更新处理程序变量

Order Update Event Handler 服务(如 图 23 所示)首先调用一个服务来检索提供的订单标识符的所有活动的流程实例。调用的服务具有默认的流程名称设置。我们传入订单标识符,该服务返回一个流程实例数组(希望其中至少有 1 个成员)。如果找到匹配值,则会使用一段简单脚本来返回第一个流程实例标识符,将它作为 Order Update Event Handler 服务的输出。

图 23. 用于检索匹配实例的已包含的服务
用于检索匹配实例的已包含的服务

如果查看检索实例的服务的输入变量,如 图 24 所示,请注意,流程名称的设置是链接流程的名称,不是父流程的名称。这是因为该名称是我们希望发送更新事件时将会激活的流程实例名称。您稍后会在搜索 API 中看到,您需要通过传递此名称将搜索范围缩小到此类型的实例。

图 24. 检索流程实例变量
检索流程实例变量

服务的正文包含一个脚本元素,它使用 JS API 代码对业务数据列(已在 图 25 中突出显示)执行搜索。

图 25. JS API 显示了业务数据条件
JS API 显示了业务数据条件

图 26 显示了已作为流程上的业务数据搜索字段提供的相应的业务数据列。

图 26. 为进行搜索而公开的业务数据
为进行搜索而公开的业务数据

返回到剩余的 JS API 代码中,如 图 27 所示,已在搜索和执行的搜索上设置了包含对订单标识符业务数据的搜索的条件集。然后,会将结果分析为一个 OrderProcessInstance 对象数组,将该数组作为输出传递给服务的调用方。

图 27. JS API 搜索和结果分析
JS API 搜索和结果分析

您现在可重新运行之前的场景,验证错误传送事件的问题是否已在经过修订的设计中得到解决。图 28 显示了 Process Inspector 中的一个订单的另一个实例。任务主题已修改为显示订单标识符,并执行了一次订单更新,还收到了更新事件。

图 28. Process Inspector 中的第一个流程实例
Process Inspector 中的第一个流程实例

查看图 28 的大图。)

完成第一个实例中的所有任务后,我们会使用同一个订单标识符创建第二个实例,如 图 29 中所示。这次这个新实例未收到意外的事件,并且该标志显示在等待我们希望为此订单实例生成的任何有效的事件消息的事件子流程。

图 29. Process Inspector 中的第二个流程实例
Process Inspector 中的第二个流程实例

查看图 29 的大图。)

我们将在下一节中详细阐述所做的调整,分析如何将事件分发给多个匹配的流程实例。


一对多事件关联

我们现在希望扩展我们的场景,以便允许取消特定客户的任何未完成的订单。我们可以想象这样一种场景,在该场景中,可能有一位客户还未支付未结算的发票,财务部门希望阻止进一步向该客户发放订单。在这种情况下,我们希望发送一个可产生多个潜在匹配的事件。

图 30 显示了修订后的 Fulfill order 流程,它添加了一个额外的事件子流程 Handle order cancellation。在这种情况下,事件子流程是不可中断的(由下面的消息图表周围的实线表示) -- 我们不希望继续执行主要流程路径,而是希望将控制权转移给该事件子流程内的活动。

图 30. 修订后的 Fulfill Order 链接流程
修订后的 Fulfill Order 链接流程

图 31 显示了扩展的事件子流程,其中勾选了 Interrupt Parent Process? 设置。该消息事件周围有一条实线,这与 图 30 中看到的折叠的事件子流程中的视图一致。

图 31. 取消订单消息事件设置
取消订单消息事件设置

对于数据映射,如 图 32 中所示,可以再次使用流程标识符进行关联,但在本例中没有传入额外的业务数据进行处理。

图 32. 取消订单消息事件关联设置
取消订单消息事件关联设置

用于此取消事件的 UCA 如 图 33 中所示。

图 33. Order Cancel UCA
Order Cancel UCA

在本例中,事件处理程序的变量(如 图 34 中所示)对输入和输出是相同的。您很快将看到,我们使用了另一个 UCA 来完成业务数据与内部流程标识符之间的转换,然后将它们分发到目标 UCA。

图 34. Order Cancel 处理程序变量
Order Cancel 处理程序变量

UCA 使用的 UCA 事件处理程序 Order Cancel Event Handler 只是一种简单的直通模式,如 图 35 中所示。

图 35. Order Cancel 处理程序
Order Cancel 处理程序

为了分发事件,我们将创建一个代理 UCA -- 一个没有直接连接到消息事件、但可以用来向取消事件的 UCA 的一个或多个实例发送事件的 UCA,如 图 36 中所示。

图 36. 订单取消分发 UCA
订单取消分发 UCA

查看图 36 的大图。)

当查看事件处理函数的变量时,如 图 37 中所示,您可以看到这里提供了一个客户标识符 (customerID) 作为输入,但没有提供输出变量。这是因为 UCA 不会被消息事件直接引用,所以不需要在映射中使用任何输出变量。相反,您会在服务的逻辑流中看到,处理程序将调用一个帮助器服务来调用实际的 UCA。

图 37. 事件处理程序变量
事件处理程序变量

图 38 显示了该服务的逻辑流。第一步是调用一个在更新 UCA 处理程序中使用的类似服务,但这一次,该服务将搜索一个已为进行流程上的业务数据搜索而公开的客户标识符。如果找到任何匹配值,则会将匹配实例的结果数组传递给另一个服务,该服务将分发最终的订单取消事件。

图 38. 订单取消分发处理程序
订单取消分发处理程序

如果查看分发事件的服务的实现(Distribute Order Cancellation Events,如 图 39 所示),您会看到该服务使用了一种可视的循环模式来处理结果数组,为每个匹配值调用订单处理 UCA,传入每个匹配值的流程实例标识符。

图 39. 分发取消事件的服务
分发取消事件的服务

为了测试一个取消事件的分发,我们为同一个客户创建了该订单流程的两个实例,图 40 显示了 Process Inspector 中的第一个订单流程实例。我们修改了任务主题,以显示将用于模拟某个取消请求的客户标识符。另请注意,两个现在位于范围内的事件子流程现在都有活动的标志。

图 40. Process Inspector 中的客户的第一个订单
Process Inspector 中的客户的第一个订单

查看图 40 的大图。)

图 41 显示了第二个实例,该实例已突出显示,以表明它用于同一个客户。

图 41. Process Inspector 中的客户的第二个订单
Process Inspector 中的客户的第二个订单

查看图 41 的大图。)

为了模拟此取消场景,我们将运行一个测试 Coach,以支持为我们希望取消其未完成订单的客户提供客户标识符。图 42 显示了测试 Coach Send Order Cancellation Distribution Event Client。请注意,它调用的服务 Send Order Cancellation 会调用代理 UCA,然后后者会使用事件处理程序搜索匹配的流程实例,分发事件来触发与取消事件子流程上的消息事件对应的真实 UCA。

图 42. 发送订单取消 Coach
发送订单取消 Coach

图 43 表明我们将在运行 Coach 过程中提供相关的客户标识符来触发取消。

图 43. 指定要匹配的客户
指定要匹配的客户

如果切换回 Process Inspector 并刷新实例,您可以看到第一个订单实例已成功收到了取消事件,如 图 44 所示。请注意,不再有针对 Handle order updates 事件子流程的标志。另外,Handle order cancellation 事件子流程只有一个表示收到的事件的标志,并没有等待接收任何未来事件的独立标志。因为将取消事件设置为中断,所以它现在可全面控制处理过程,无法继续接收任何事件。

图 44. 收到的第一个订单的取消事件
收到的第一个订单的取消事件

查看图 44 的大图。)

如果查看第二个订单实例,如 图 45 所示,您可确认它也收到了取消事件,并且这是现在可在该实例内执行的惟一路径。

图 45. 收到的第二个订单的取消事件
收到的第二个订单的取消事件

查看图 45 的大图。)


结束语

本文介绍了 BPMN 2.0 事件子流程的概念,然后详细介绍了 IBM Business Process Manager V7.5.1 中对基于消息的事件子流程的支持。我们了解了事件关联和使用业务数据建立关联时的一些潜在挑战。本文确定了使用内部惟一关联标识符并在该标识符与业务数据字段之间建立仲裁的一种模式。最后,我们了解了如何支持该模式,为运行的流程实例实现一对多的事件分布。


下载

描述名字大小
样例场景BPMN_2.0_Event_Sub-Processes_1.0.twx1.4MB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=828029
ArticleTitle=在 IBM Business Process Manager 中设计事件驱动的业务流程
publish-date=07302012