用于业务流程管理的 Bonita

第 1 部分: 配置一个简单的工作流

当人们按照某种协调的方式交互,实现一个普通的业务目标时,就会出现一个业务流程。工作从一个人流动到另一个人,个人执行他或她的任务或者业务角色。例如,考虑这样一个简单的工作流,查看顾客入住酒店的情况。前台接待员为来客预订房间。然后订房信息被发送给客房部和酒店的会计部。客房部确保为客人准备好房间,同时会计部会记录客人的费用。

业务流程的管理就是对工作流程的管理。业务流程管理(BPM)工具允许您以一种计算机系统能够理解并且能执行的方式来描述工作流。就的那套方法是使用某种编程语言编写代码。BPM 的方法是使用 BPM 软件,通过配置从管理上完成任务,甚至连一行代码也无需编写。Business Process Modeling Notation(BPMN)是一个标准,让您使用图表表现工作流的业务需求。首先,您使用 BPMN 工作流编辑器,制作业务流程的 BPMN 表示。然后您在 BPMN 工作流引擎上存放 BPMN 表示,工作的真正流程是在 BPMN 工作流引擎上处理的。

有些优秀的基于 Java 的开源 BPM 解决方案是可用的。在这个两部分的文章中,您将会了解这些方案之一 — Bonita Open Solution — 配置一个酒店入住业务流程的工作流。Bonita 包含图形 BPMN 编辑器和工作流引擎。

配置工作流的任务

配置一个工作流需要完成四项任务:

  1. 使用 BPMN 制作工作流。
  2. 设计工作流执行中的人员交互的表格。
  3. 指定工作流中使用的外部应用程序。您往往需要外部应用程序来满足您的工作流需求。
  4. 定义所有参与其中的员工(或者人员)的业务角色,指定谁来执行工作流中的哪个活动。业务角色决定了谁能够访问到哪个活动。决定所有这些是访问控制政策 的一部分。

在第 1 部分中,我将会使用 Bonita 制作订房工作流,说明第一个任务。在第 2 部分中,我将会展示如何设计工作流的两个表格,并说明它们如何使用常用于工作流的两个流行开源应用程序:PostgreSQL 数据库和 JasperReports 报告引擎。定义访问控制政策不在本文的讨论范围;在 参考资料 部分获取该主题的另一文章链接。

简单工作流的 BPMN 表示

为了向您介绍 BPMN,我将以酒店前台的订房流程为例。该流程需求最简单的结构就是客人到达前台,要求一间房间。前台的工作人员确认可入住的房间,如果房间可入住,就进行预订。(请注意,为了简单,我并没有考虑整个工作流,正如简介中所述,只是从酒店前台到客房部和会计部。)

该简单流程的 BPMN 表示(使用 Bonita 的工作流编辑器绘出的)如图 1 所示:

图 1. 使用 BPMN 表示一个预订酒店房间的简单工作流
使用 Bonita 中的 BPMN,预订酒店房间的简单工作流的图表

在 图 1 中最左边的浅绿色圆形是开始 元素。它表示工作流的开始,正如 BPMN 所定义的。

在开始元素右边的箭头表示迁移。它可以是各种不同的迁移,之后您在本文也会了解到。这是一个简单的迁移,仅仅指向工作流的第一个活动

工作流的活动

在 图 1 中第一个迁移右边的是一个圆角的矩形。图 1 中包含了三个这样的矩形。它们表示能够自动完成或者由用户执行的工作流活动或者任务。最左边的矩形 — 名为 EnterRoomInformation — 包含一个人的符号,表示这是一个用户活动。在这个活动中,接待员使用一个表格来输入用户要求的房间类型信息。

BPM 和 ERP 的比较

企业资源规划(ERP)工具(见 参考资料)提供了管理业务流程的另一个方法。当配置一个 ERP 实现时,您要执行 BPM 中类似的任务(工作流制作、表格设计、链接外部应用程序、以及定义访问控制政策)。因为 ERP 工具是随着时间推移不断演化的,所以它们逐个完善,提供更丰富的工作流功能。所有 ERP 工具都提供预配置工作流,并且部分能让您在工作流类型— 管理业务流程一般所需的工作流种类中选择。您可以根据业务需求,使用工作流类型来快速配置应用程序。ERP 工具的演变结果是,它们不具有 BPM 工具的标准化。对 ERP 工具尝试解决的相同问题,BPM 是更有组织,更标准化的解决方案。

中间的矩形名为 CheckRoomAvailablity。它的插头连线符号表示,这是一个动态活动,意味着它在后端完成。几个类型的自动活动能够按这一方式完成 — 例如,确认所要求的房间是否可入住的数据库操作。

第三个(最右边的)矩形,名为 BookRoom,既有人也有插头符号,这就意味着用户执行该活动的一部分,剩余部分由某些自动处理在后端完成。BookRoom 活动的人为部分是接待员提供订房信息。剩余的就是动态活动(保存订房信息的数据库事务)。

总体来说,第一个活动简单地收集所需房间的数据,第二个确认所需房间是否可入住。第三个动作完成订房剩下的工作。

简单且有条件的迁移

请注意,在 图 1 中简单迁移(箭头)从 EnterRoomInformation 活动指向 CheckRoomAvailability 活动。这个简单迁移意味着在接待员收集到客房查询信息后,下一步往往是检查所需类型的房间是否可入住。

下一个迁移 — 从 CheckRoomAvailability 活动到 BookRoom 活动 — 并非一个简单迁移。这取决于 CheckRoomAvailability 活动的输出 — 即所需房间是否可入住。如果可入住,工作人员可能会帮客人预订,因此就进行 BookRoom 活动。如果不可入住,工作人员可能会确认其他类型的房间是否可入住,因此控制就需要返回到 EnterRoomInformation 活动。

因此,在这里您需要做出决定,选择哪个分岔。无论您何时做出这个决定,执行路径都会分岔。这个分岔由一个内有十字的菱形表示(BPMN 术语中的 gate 或者 gateway)。您可以在 图 1 中看到 gate 元素用两个不同的可能执行方案连接 CheckRoomAvailability 活动的输出。

三条带箭头的线连接到 gate。每条线都表示一个迁移:

  • 第一条线是 gate 的输入,它是由 CheckRoomAvailability 活动产生的,并终止在 gate。这是一个简单的,非条件的迁移。
  • 第二个迁移时从 gate 到 EnterRoomInformation 活动。这个迁移表示当指定类型的房间不可入住时的情况。这是一个条件迁移。
  • 第三个迁移,从 gate — 另一个条件迁移 — 指向 BookRoom 活动,这时所需类型的房间是可入住的。

请注意,gate 元素是迁移交汇的点。每个进入 gate 或者离开 gate 的迁移都了解其自身属性(即,无论它是简单的或者条件的)。

现在您已经看到如何使用 BPMN 表示一个预定房间的简单流程。下一部分会介绍如何在 Bonita 中配置这个工作流。如果您想跟随本文的动手练习,现在就可以下载,安装并加载 Bonita(见 参考资料)。

在 Bonita 中配置简单的工作流

Bonita 的图表工具易于使用,允许从选项板拖放到名为白板 的编辑窗口。在组件放入到白板之后,您可以根据业务流程需求,逐个配置每个组件。

图 2 显示了 Bonita 的欢迎页面,它包含普通任务的快速链接,如创建一个新的流程或者打开当前已有流程:

图 2. Bonita 的欢迎页面
Bonita 欢迎页面的屏幕截图

您可以单击 New 按钮来开始配置您的订房工作流。打开一个名为 MyProcessDiagram(版本 1.0)的新流程,如图3 所示:

图 3. 新流程
屏幕截图显示 Bonita 中新创建的流程

您可以在 图 3 中看到,Bonita 屏幕被水平分为两部分,每个部分又垂直进行划分。

左上部分包含一个 BPMN 元素的选项板,您可以使用它配置工作流。

右上部分是一个流程白板,您可以把 BPMN 元素从选项板拖放到其中。白板是个真实的流程设计视图。如 图 3 所示,Bonita 在创建新流程时自动添加三个 BPMN 元素:开始、迁移和名为 Step1 的活动。

左下部分是一个概览窗口,显示您创建的整个工作流的概览。该功能对快速跳至工作流的特殊部分十分有帮助,特别是当工作流定义很大,并且在无滚动条的情况下不能完全显示在白板中。

右下部分是详细窗口,用于您配置独立的 BPMN 元素。它显示了您在配置中设置的 BPMN 属性。因为当前没有选中任何 BPMN 元素,所以 图 3 中的详细窗口显示了工作流的属性。例如,您可以看到详细窗口有一个名为 Diagram 的选项卡,它包含一个 Name 字段,其值为 MyProcessDiagram。将 MyProcessDiagram 改为 RoomBookingDiagram,然后单击 Bonita 主工具栏上的 Save 按钮。

在 Bonita 中配置用户活动

单击 Step1 活动开始配置订房工作流。它的属性显示在详细窗口中,如图 4 所示:

图 4. Step1 活动的属性详细信息
Step1 活动的属性详细信息

当您单击 Step1 活动时,上下文选项板— BPMN 元素图标的一个小子集 — 显示在它周围,如图 5 所示:

图 5. Step1 活动显示它的上下文选项板
显示上下文选项板的 Step1 活动

上下文选项板使您方便地添加下一个活动或者迁移到您的工作流。在本文的练习中,您将会经常使用到上下文选项卡。

您可以从 图 4 中看到,详细窗口有多个选项卡,您可以使用它们来控制每个 BPMN 元素的行为 — 例如 Step1 活动 — 您拖放到 Bonita 的白板中的活动。这些选项卡提供了丰富的功能,覆盖了管理业务流程几乎所有可能的需求。在本文中,我并没有讲到所有 BPMN 功能。在这个简单的订房案例中,您只需要了解详细窗口的 General,Data,Connectors 和 Forms 选项卡。

如 图 4 所示,General 选项卡让您指定活动的名称,描述,类型和属性。在 Name 文本字段输入 EnterRoomInformation 作为活动的名称,替换 Step1。请注意,EnterRoomInformation 现在是活动的名称,显示在白板上。

Description 字段允许您提供关于 BPMN 元素的文档。在 Description 字段输入 Show a form to fetch the information about the room required by the customer

接着,您将指定该活动的类型。因为 EnterRoomInformation 活动需要填充一个数据输入表格来指定所订房间类型,所以这是一个由使用订房工作流应用程序的接待员执行的用户活动。Activity 类型字段是一个下拉列表。EnterRoomInformation 活动的类型可以是 Human,它是默认选择的。

因为 EnterRoomInformation 活动是一个用户活动,您需要为它开发一个数据输入表格。在第 2 部分中,您将会设计并实现该表格,然后使用详细窗口的 Forms 选项卡,将它添加到活动。也是在第 2 部分,您将会使用 Data 选项卡来定义变量,这些变量上包含有客人所需房间类型的数据。

将自动活动添加到工作流

接下来,您要添加一个迁移,还有一个名为 CheckRoomAvailability 的活动到工作流中。CheckRoomAvailability 活动接收到来自 EnterRoomInformation 表格的数据,查看酒店的数据库(这您将会在第 2 部分中配置),然后设置一个标志显示房间是否可入住。

单击 EnterRoomInformation 活动来激活它的上下文选项卡。把 step 元素图标(一个小框)从上下文选项的右上角拖出,然后把它放在 EnterRoomInformation 活动的后面。如图 6 所示,迁移和另一个 Step1 元素被添加到工作流:

图 6. 添加新的迁移和 Step1 元素到您的工作流
添加新的迁移和 Step1 元素到您的工作流

新创建的 Step1 元素的详细窗口显示了活动的名称,描述和类型字段。输入 CheckRoomAvailability 作为活动的名称。在 Description 字段中,输入 一个自动流程,查询数据库中所需类型的房间是否可用。从 Activity 类型的下拉列表中选择 Automatic。图 7 显示了您所配置的 CheckRoomAvailability 活动:

图 7. 配置 CheckRoomAvailability 活动
配置 CheckRoomAvailability 活动

添加房间可入住标志到您的工作流

如果所需房间可入住,CheckRoomAvailability 活动就设置一个名为 isRequiredRoomTypeAvailable 的标志。工作流中的下一个迁移取决于 isRequiredRoomTypeAvailable 标志是设置或者不存在,所以您需要在 Bonita 中定义 isRequiredRoomTypeAvailable 标志作为一个变量。

Bonita 允许您为每个独立的活动和整个工作流定义变量。当只在特定活动中需要变量时,就定义一个活动级的变量。如果该变量的使用扩展到多个活动,您可以将变量定义为工作流级,这样任意元素都能访问它。

在订房工作流中,isRequiredRoomTypeAvailable 标志需要定义为工作流级的变量,因为多元素需要访问它。CheckRoomAvailability 活动设置了标志,然后下一个迁移会检查标志的状况。

要定义一个工作流级的变量,单击环绕整个工作流的矩形,如图 8 中强调的:

图 8.订房工作流的详细窗口
订房工作流的详细窗口

请注意,详细窗口现在显示了整个订房工作流的属性。

单击详细窗口的 Data 选项卡,然后单击 Add 按钮。打开一个 Add 新变量对话框,如图 9 所示:

图 9. 添加新变量到您的工作流
添加新变量到您的工作流

在 Name 文本字段输入 isRequiredRoomTypeAvailable。在 Description 字段,输入 A workflow-level flag to show whether the required type of room is available or not。从 Data 类型下拉列表中选择 Boolean,然后选择 false 作为标志的默认值。单击底部的 Finish 按钮。您可以看到 isRequiredRoomTypeAvailable 变量已经被添加到 Data 选项卡,如下图 10 所示:

图 10. 显示 isRequiredRoomTypeAvailable 变量被添加到文本框的 Data 选项卡
显示 isRequiredRoomTypeAvailable 变量被添加到文本框的 Data 选项卡

您刚刚定义了 CheckRoomAvailability 活动,带有名为 isRequiredRoomTypeAvailable 的工作流级标志。然而,您还没有配置真正的数据库和 SQL 语句,它们会读取房间可用信息,然后设置(或者重设)isRequiredRoomTypeAvailable 标志。我将会在第 2 部分中说明如何完成所有这些内容。现在,我正要说明如何配置下一个动态迁移,它需要根据房间是否可入住进行决策制定。

有决策制定的动态迁移

单击 CheckRoomAvailability 活动来激活它的上下文选项板。从上下文选项板中拖出带有加号的菱形,然后将它放在 CheckRoomAvailability 活动的右边,在此放置一个 gate 元素,如图 11 所示:

图 11. 在BPMN 流程中用于决策制定的 gate 元素
在 BPMN 流程中用于决策制定的 gate 元素

gate 元素有两个类型:

  • XOR gate :如果 gate 中有一个十字,它就用于将一条流分叉为多条。
  • AND gate :如果 gate 中有一个加号,它就用于会合两条流。

您从 简单的,有条件的迁移 部分了解到需要一个将一条流分为多条的 gate 。为了设置 gate 的正确类型,单击白板中的 gate 元素,然后在 General 选项卡中选择 XOR 作为 Gate 类型属性,如图 12 所示:

图 12. 选择 XOR gate 将一条流分为多条
选择 XOR  gate 将一条流分为多条

现在从上下文选项卡单击并将 step 元素图标拖到 gate 的右边。在 gate 的右边放置一个名为 Step1 的新活动。在详细窗口的 General 选项卡,将新活动的名称改为 BookRoom,类型改为 Human。现在 gate 就配置完了,这个流程如图 13 所示:

图 13. 将 BookRoom 活动放置在 gate 的旁边
将 BookRoom 活动放置在 gate 旁边

Bonita 中的业务角色

BookRoom 元素的左上角是一个表示人为的符号,右上角是一个十字(两者在 图 13 中都可见)。十字说明您没有指定谁来实施这个活动。单击 Actors 选项卡,然后单击 Choose 按钮。打开一个 Assign actors 对话框,如图 14 所示:

图 14. Assign actors 对话框
Assign actors 对话框

Assign actors 对话框告诉您选择能执行 BookRoom 活动的人员组。Bonita 允许您根据工作流所需的业务角色 定义人员组。业务角色的讨论不在本文范围内。您可以简单地使用已经在 Bonita 中定义,名为 Initiator 的默认人员组。Initiator 组由创建工作流的任何人组成。

从文本框选择 Initiator,然后单击详细窗口底部的 Finish 按钮。Initiator 被添加到 Actors 选项卡的列表中,如图 15 所示:

图 15. 在 Actor 选项卡的列表中添加默认 Initiator 人员
在 Actor 选项卡的列表中添加默认 Initiator 人员

BookRoom 活动还需要用户交互表格,该表格要求酒店前台职员输入用户信息。您将会在第 2 部分中设计工作流所需表格。也请注意,BookRoom 暂时是一个用户活动。在第 2 部分中,您将会配置该活动的自动部分。

添加迁移的条件

现在您在 gate 和 BookRoom 活动之间的迁移上添加一个房间可入住的条件。您需要在 BookRoom 活动只在所需类型房间可入住的情况下发生的条件下配置工作流。

单击 gate 与 BookRoom 活动之间的迁移元素。迁移元素的详细信息显示在详细窗口,如图 16 所示:

图 16. 显示迁移属性的详细窗口
显示迁移属性的详细窗口

迁移元素的详细信息只包含一个名为 General 的选项卡,如 图 16 所示。General 选项卡包含一个名为 Condition 的字段,指定了在何种条件下发生迁移。在 Condition 文本字段输入 isRequiredRoomTypeAvailable。请从 添加房间可用标志到工作流 回忆一下,您声明了 isRequiredRoomTypeAvailable 标志作为一个工作流级变量。如果房间可入住,CheckRoomAvailability 活动设置 isRequiredRoomTypeAvailable 标志为真。如果 isRequiredRoomTypeAvailable 活动为真(意味着标志被设置),这个条件就能使迁移转到 BookRoom 活动。

当您输入迁移的条件时,请注意一个小菱形出现在迁移元素的 gate 边。菱形表示迁移是有条件的。

正如您所猜想的,您还必须设置其他迁移的条件。在流程白板中单击 gate 元素激活它的上下文选项板。从上下文选项板底部拖出箭头(迁移图标)到 EnterRoomInformation 活动。这就描画了从 gate 到 EnterRoomInformation 活动的迁移元素,如图 17 所示:

图 17. 所需类型房间不可入住时,从 gate 到 EnterRoomInformation 活动的迁移
 所需类型房间不可入住时,从 gate 到 EnterRoomInformation 活动的迁移

现在,如 图 17 所示,简单地设置 isRequiredRoomTypeAvailable 作为该迁移的条件。工作会返回到 EnterRoomInformation 活动,如果所需类型的房间不可入住。

配置工作流的结束

工作流配置的最后一步是从 BookRoom 的上下文选项板中拖拽一个环形到右边,添加一个结束元素到工作流。事件选择选项板如图 18 所示:

图 18. 事件选择选项卡
事件选择选项卡,当您从上下文选项板中拖出环形图标时它会进行显示

事件选择选项板包含许多由 BPMN 定义的事件类型的符号。您只需要结束 元素(一个红色 circle,环绕在 图 18 中),您可以在事件选择选项板的右上角找到它。从事件选项板中选择结束元素。现在您的工作流中包含了一个结束元素,如图 19:

图 19. 有结束元素的订房工作流
有结束元素的订房工作流

您已经配置了订房工作流,除了它没有表格和数据库。单击 Bonita 主菜单的 Save 保存当前的工作。这将您的工作流信息保存在 RoomBookingDiagram.proc 文件中。RoomBookingDiagram.proc 文件也可用于 下载

结束语

类似预配置工作流和常用工作流类型的 ERP 功能是很有用的,但是也有一定的代价:这些功能都是特定于产品的。我发现教授 IT 专业人员如何使用特定于产品的功能来解决日常工作流问题是任何 ERP 项目中最难的部分。

因此,我认为 BPM 是未来的潮流。虽然标准化尚不完全,但也正在不断进行。我相信在几年之内,BPM 将会覆盖所有工作流的功能,通用或者非通用的,因此标准化的 BPM 培训将会成为 IT 课程的一部分,而特定于产品的 ERP 培训将逐渐消失。

本文中,您了解了一些 BPMN 的知识,以及如何使用它在 Bonita 中配置一个简单的工作流。在第 2 部分中,我将会讲到第 1 部分中未完成的部分 — 设计表格、使用变量、连接到 PostgreSQL 数据库、以及生成带 JasperReports 的报告 — 用于在实际中加载您的订房工作流。

转:https://www.ibm.com/developerworks/cn/java/j-bpm1/

第2部分:配置表单和变量

这个两部分文章的 第 1 部分 向您介绍了 Business Process Modeling Notation (BPMN) 和 Bonita Open Solution,一个基于 Java 的、开源的工作流工具。您已经使用 Bonita 设计了一个酒店预订的工作流。现在,在第 2 部分,您将配置变量来保存工作流数据,在客房预订(room-booking)工作流设计用户交互表单。然后,将您的工作流与 PostgreSQL 数据库和 JasperReports 报告引擎连接起来,这样,就可以从数据库阅读预订信息并生成报告。最后,您可以执行工作流来查看客房预订流程的运行状况。

使用 Bonita 设计一个简单表单

在第 1 部分结尾,您已经保存了 Launch Bonita 和开源的 RoomBookingDiagram_1.0.proc 文件。(该文件在本文源代码 下载 部分也有。)工作流包含 EnterRoomInformationCheckRoomAvailability 和 BookRoom 活动,如图 1 所示:

图 1. Bonita 中的客房预订工作流
Bonita 客房预订工作流屏幕截图

下一步是为 EnterRoomInformation 活动设计一个简单表单,如图 2 所示:

图 2. 一个简单数据输入表单
Bonita 中的一个简单数据输入表单的屏幕截图

图 2 中的表单包含一个标题(EnterRoomInformation)、一个带有标签(Type of room required)的下拉列表、以及一个按钮 Check Room Availability,也包含一些其他的元素,比如,Bonita 徽标,这也是标准 Bonita 模板的一部分。(Bonita 允许使用定制模板,但为了简单起见,本文使用标准模本。)

创建一个新模板

要开始为 EnterRoomInformation 活动创建一个新模板,单击活动在细节窗口显示其属性。在细节窗口单击 Forms 选项卡然后单击 Add 按钮,一个 Create a new Form 对话框打开。如图 3 所示:

图 3. 创建一个新表单的对话框
创建一个新数据输入表单的 Bonita 对话框的屏幕截图

注意,在 图 3 中,Bonita 已经在 Name 字段输入 EnterRoomInformation 作为新对话框的名称。在对话框中您可以看到一个 Description 文本框,可以在其中输入表单描述,比如 A form showing a drop-down list so that the receptionist can choose the type of room required by the customer

在 Description 文本框下方,您可以看到 Add widgets based on… 和两个标签为 Select All 和 Unselect All 的按钮。按钮下方是一个标签为 isRequiredRoomTypeAvailable 的复选框。这个复选框是默认选中的,表示您在第 1 部分的 添加房间可入住标志到您的工作流 部分选中的 isRequiredRoomTypeAvailable 变量。

Bonita 如何在表单设计中使用变量

回顾 第 1 部分isRequiredRoomTypeAvailable 变量实际上是 CheckRoomAvailability 活动设置的一个标志。使用该标志的工作流后面将决定 BookRoom 活动是否可以进行,或者控制是否必须被传送回 EnterRoomInformation 活动。

因为您正在设计的 EnterRoomInformation 表单只有一个字段(Type of room required,是一个下拉列表),那么就可以推断出,设计该表单 isRequiredRoomTypeAvailable 变量(或标记)不是必需的。您可能会觉得奇怪,为什么 EnterRoomInformation 表单的 Create a new Form 对话框以一个复选框显示该变量。

通常情况下,当您使用 Java 语言设计和实现表单时,表单中的每个字段(比如文本框下拉列表)是与一个保存应用程序数据的 Java 对象联系在一起的。通常称为 model beans,这类对象常用在大多数 Java 程序员都很熟悉的 Model-View-Controller (MVC) 基础架构中(见 参考资料)。Bonita 使用同一概念将字段和流程变量联系起来,允许您直接从流程变量快速构建表单。只需要制作一个默认表单,包含您所选择的每个变量相对应的所有字段。这就是快速构建一个可以根据您的需求编辑和调整的表单的方法。

由于 isRequiredRoomTypeAvailable 是一个全局变量,所以它在整个客房预订工作流以及工作流的所有单个活动中都是有效的。迄今为止,您不能为工作流声明任何其他变量。这就是为什么这是 Bonita 用于构建 EnterRoomInformation 表单的惟一一个变量。在您用来设计表单的变量列表中只包括 isRequiredRoomTypeAvailable 全局变量。

现在,如果您在 Create a new Form 对话框底部单击 Finish 按钮,Bonita 将创建一个表单,包含 isRequiredRoomTypeAvailable 变量相对应的一个字段。但是,正如您从您的客房预订工作流的业务逻辑所知道的那样,在设计 EnterRoomInformation 表单时您不需要 isRequiredRoomTypeAvailable 变量。因此,在 Create a new Form 对话框,现在应该取消选中 isRequiredRoomTypeAvailable 旁边的复选框,然后单击 Finish。Bonita 将自动配置一个空 EnterRoomInformation 表单,如图 4 所示:

图 4. 为 EnterRoomInformation 活动最新配置的空表单
屏幕截图,显示为 EnterRoomInformation 活动最新配置的空表单

现在,您必须为 Type of room required 字段配置一个变量。这个变量将保存所有房间类型,以便于前台可以选择客人需要的类型。我将调用变量 TypesOfRoomsAvailable。EnterRoomInformation 表单中的 Type of room required 字段将使用 TypesOfRoomsAvailable 变量来获取不同的可用房间类型。

配置一个变量来保存选项列表

TypesOfRoomsAvailable 变量是 EnterRoomInformation 表单中惟一需要的。这使得它成为了一个局部变量。

要开始创建 TypesOfRoomsAvailable 变量,在 Bonita 白板(设计视图)上单击 EnterRoomInformation 活动。在细节窗口单击 Data 选项卡,然后单击 Add 按钮。出现一个 Add a new variable 对话框,类似于 第 1 部分图 9(您需要配置 isRequiredRoomTypeAvailable 全局变量) 中的那个。它包括 Name (必须的)、Description、Data type 和 Default value 字段。在 Name 字段输入 TypesOfRoomsAvailable,在 Description 文本框输入 A variable to hold the different types of rooms available in the hotel,如图 5 所示:

图 5. 添加一个新变量的对话框
添加一个新变量的 Bonita 对话框的屏幕截图

注意看 图 5 中的 Data type 字段。如果您在 配置 第一部分图 9 中配置了 isRequiredRoomTypeAvailable 变量, 您可以选择 Boolean 作为 Data type 的值,因为 isRequiredRoomTypeAvailable 变量是一个 ture 标志,或者是 false 标志。TypesOfRoomsAvailable 变量应该是一系列选项 — 可用房间类型 — 所以,从 Data type 字段旁边的下拉列表中选择 List of options

一旦您选择 List of options 作为数据类型,在 Add a new variable 对话框的下部将出现 3 个字段(Name、Description 和 List)和 4 个按钮(AddUpDownRemove)组成的一个新组,如图 6 所示:

图 6. 添加一个新变量的对话框,其中含有 List of options 数据类型的附加字段
Bonita 添加新变量的对话框的屏幕截图,其中含有 List of options 数据类型的附加字段

Bonita 显示附加字段,因为它需要知道可用房间的具体类型,以便于它能将类型列表和您的 TypesOfRoomsAvailable 变量联系起来。

正如您在 图 6 中所看到的,Name 和 List 字段用星号做标记,表示它们是强制的。这是 Bonita 一个可重用性功能,允许您为一个变量列表给出一个名称。稍后您可能会重用这个列表和其他变量。

在 Name 字段输入 ListOfRoomTypes,输入 These are the types of rooms available 作为描述。然后,要将真实值输入列表,单击 Add 按钮。出现一个 Add an item 对话框,如图 7 所示,允许您逐个输入不同类型的房间:

图 7. 向 List of options 数据类型添加值的对话框
向 List of options 数据类型添加值的 Bonita 对话框的屏幕截图

在列表中,您只能输入 2 个值。首先,在 Add an item 对话框的 Item name 字段输入 Single,然后单击 OK。现在,这个值将在 图 6 所示的 Add a new variable 对话框中的 List 文本框中出现。再一次单击 Add 按钮,这次在 Item name 字段出现的类型是 Double,然后单击 OK。您完成了 Add a new variable 对话框。现在单击 OK 按钮,我在图 8 中圈起来的那个:

图 8. TypesOfRoomsAvailable 变量的完整的配置
Bonita 中 TypesOfRoomsAvailable 变量的完整配置的屏幕截图

在已完成的 Add a new variable 对话框单击 Finish 按钮,对话框消失,TypesOfRoomsAvailable 变量出现在 EnterRoomInformation 活动的 Data 选项卡中,如图 9 所示:

图 9. 添加到 EnterRoomInformation 活动的 TypesOfRoomsAvailable 变量
被添加到 EnterRoomInformation 活动的 TypesOfRoomsAvailable 变量的屏幕截图

您已经成功地配置了 TypesOfRoomsAvailable 变量,现在您可以使用该变量向您的 EnterRoomInformation 表单添加 Type of room required 下拉列表了。

向一个表单中添加一个新字段

如果,在白板中 EnterRoomInformation 活动仍然被选中,在细节窗口单击 Forms 选项卡。在表单列表单击 EnterRoomInformation,然后单击 Edit 按钮,已在图 10 中圈起来了:

图 10. 编辑一个 Bonita 表单
编辑一个 Bonita 表单的屏幕截图

您在 创建一个新表单 部分开发的空 EnterRoomInformation 表单在表单编辑器窗口出现,这个窗口左边有一个调色板控件,在右边是一个表单的设计视图。表单的设计视图显示矩形网格。在组件调色板单击 Select 组件,并将它拉到表单的最上层网格,如图 11 所示:

图 11. 从调色板拖拉一个组件到您的表单
将一个组件从调色板拖拉到您表单的屏幕截图

一个以 Select1 作为标签的新字段被放入表单,如图 12 所示:

图 12. 一个放入表单设计视图的 Select 组件
在 Bonita 中,一个 Select 组件放入表单设计视图的屏幕截图

现在,单击 Select1 字段。细节窗口显示其属性,如图 13 所示:

图 13. 显示一个字段的属性的细节窗口
显示一个字段属性的细节窗口的屏幕截图

在 Name 和 Show label 字段分别输入 RequiredRoomType 和 Type of room required。新字段现在显示 Type of room required 作为其标签,如图 14 所示:

图 14. Type of room required 字段的更新标签
Type of room required 字段更新标签的屏幕截图

Type of room required 字段的下拉列表显示可用房间的类型,便于前台选择。因而,下一步是将可用房间类型填入到下拉列表,使用您在 配置一个变量来保存选项列表 部分配置的 TypesOfRoomsAvailable 变量。

将 Bonita 变量与表单中的一个字段联系起来

如果 Type of room required 在表单设计者视图中是选中的,在细节窗口单击 Data 选项卡。注意该选项卡包含四个字段:Available Values、Initial value、Expression 和 save to,如图 15 所示。这些表单字段允许您将变量和字段联系起来。

图 15. Data 选项卡显示与字段关联的变量
显示与一个字段关联的变量的 Data 选项卡的屏幕截图

单击 Available Values 旁边的下拉列表,并选择 typesOfRoomsAvailable 作为其值。这就在 EnterRoomInformation 表单中的 Type of room required 字段旁边填入了房间类型。

现在,单击 Initial value 字段旁边的下拉列表,然后选择 Single。当 EnterRoomInformation 表单被呈现给用户时,这就将 Single 设置为 Type of room required 字段默认选中的初始值。现在 Data 选项卡看起来像图 16 所示:

图 16. 默认初始值选中后,RequiredRoomType 的 Data 选项卡
Bonita 中 Type of room required 字段的 Data 选项卡的屏幕截图,显示 typesOfRoomsAvailable 变量和 Initial value 字段的默认值

Data 选项卡的 Expression 字段允许您编写一个表达式,Bonita 使用它来估计 save to 字段指定的变量值。如果您想要在将用户输入保存为一个变量之前,就对其进行处理,这一特性非常有用。但是,如果您不需要处理用户输入,那么让 Expression 字段保留默认值。

工作流的下一个活动,CheckRoomAvailability,需要了解所需房间的类型,以便于查询客房预订数据库,查询房间是否可用。您需要定义一个工作流级别的文本类型变量来存储用户输入。因此,使用 配置一个变量来保存选项列表 小节描述的步骤,创建一个名为 requiredRoomType 的变量,数据类型设置为 Text。requiredRoomType 变量现在在 save to 旁边的下拉列表中列出,save to 字段左面的复选框也被选中,如图 17 所示。这是因为 Bonita 知道,现在 save to 字段有一个存储用户输入变量名。

图 17. 用于 RequiredRoomType 字段的 Data 选项卡的表达式和 save to 字段
用于 RequiredRoomType 字段的 Data 选项卡的表达式和 save to 字段的屏幕截图

您已经完成了 EnterRoomInformation 表单的字段和变量配置。现在您需要配置一个表单按钮,前台接待员可以单击它来选择所需的房间类型。

在 Bonita 表单中使用按钮

next 按钮和 previous 按钮

在 图 18 中,Field Type 字段有一个下拉列表,其中 Submit Button 被选中。其他可能值是 Next Button 和 Previous Button。当您需要从用户没有填写的表单中收集数据时,可使用 next 和 previous 这类按钮。既然那样,您可以将您的数据分离成一系列表单,并在每个表单中配置 next 和 previous 按钮。Bonita 在内部管理从一个表单到下一个或上一个表单的导航。

Bonita 提供 3 个类型的按钮:submit、next 和 previous。submit 按钮提交处理的数据表单:当用户单击按钮时,表单数据被提交,且工作流中的下一个活动发生。在 EnterRoomInformation 表单的设计视图,您在表单底部可以看到一个 Submit 按钮。当您创建新表单时,Bonita 自动为您放置此按钮。您只需要将按钮的标签从 Submit 修改到 Check Room Availability。其余的 Bonita 都已经为您配置好了。

在设计视图单击 Submit 按钮。细节窗口显示按钮属性,如图 18 所示:

图 18. 细节窗口显示 Submit 按钮属性
显示 Submit 属性的细节窗口屏幕截图

在细节窗口的 Show label 标签字段输入 Check Room Availability。这改变了按钮标签 — 完成了您的 EnterRooomInformation 表单配置。

连接 Bonita 到 PostgreSQL

使用 PostgreSQL

本文源代码 下载 部分的 Readme.txt 文件,提供了建立 PostgreSQL 安装的操作指南,将样例数据输入数据库来使用客房预订工作流。

CheckRoomAvailability 活动将查阅酒店预订数据库,查看所需类型的房间的状态。我将使用 PostgreSQL,一个流行的开源数据库,来保存客房预订数据。Bonita 提供许多连接器,您通过配置它们可以将 Bonita 和外部应用程序连接起来。您将配置 Bonita 的 PostgreSQL 连接器来将您的 CheckRoomAvailability 活动和酒店预订数据库连接起来。

要配置 Bonita 的 PostgreSQL 连接器,您需要:

  1. 添加一个 PostgreSQL 连接器到 CheckRoomAvailability 活动。
  2. 使用 requiredRoomType 变量,编写一个 SQL 查询。
  3. 在 isRequiredRoomTypeAvailable 工作流级别变量中存储 SQL 查询输出,稍后其他 BPM 元素制定决策时使用。

配置 Bonita 的 PostgreSQL 连接器

在白板上选择 CheckRoomAvailability 活动,在细节窗口显示其属性。在细节窗口单击 Connectors 选项卡,如图 19 所示:

图 19. CheckRoomAvailability 活动的连接器选项卡
CheckRoomAvailability 活动的连接器选项卡的屏幕视图

Connectors 选项卡目前还没有用于 CheckRoomAvailability 活动的连接器,要为 PostgreSQL 添加一个连接器,单击 Add 按钮来打开 Select a connector 对话框,如图 20 所示:

图 20. 向一个活动添加 PostgreSQL 连接器
向活动添加 PostgreSQL 连接器的屏幕截图

您将在连接器列表中的 Database 项之下找到 PostgreSQL 连接器。双击 Database 项,然后选择 PostgreSQL – Execute a query on a PostgreSQL DB 选项并单击 Next,如图 21 所示:

图 21. 从 Bonita 的数据库连接器中选中的 PostgreSQL 数据库连接器
显示从 Bonita 的数据库连接器中选中的 PostgreSQL 数据库连接器的屏幕截图

接下里,您将看到一个 Name the connector 对话框,如图 22 所示,要求您输入一个名称、描述和连接器将要激活的事件:

图 22. 酒店数据库的 PostgreSQL 连接器属性
显示酒店数据库的 PostgreSQL 连接器属性的屏幕截图

在 Name 和 Description 分别输入 HotelDB 和 PostgreSQL connector for the CheckRoomAvailability activity

Select 字段允许您选择是在 CheckRoomAvailability 活动的开始时激活连接器还是在末尾激活。因为您客房预订工作流中的 CheckRoomAvailability 活动只是一个数据库查询,连接器在活动开始还是结尾激活都没关系。因此保留 Select event 字段的默认值。

对话框的最后一个字段是 If connector fails…。如果在同数据库连接过程中出现问题,从它旁边的下拉列表中,选择两个选项中的一个:报告错误或忽略错误。为了简单起见,也让 If connector fails…字段保留默认值,如果和数据库连接的连接器不能运行,这就将报告一个错误。

单击 Next 按钮,下一个对话框将要求您输入数据库连接信息,包括数据库名称、用户名、密码和运行数据库的服务器名称和端口。这些值根据您构建的数据库而定。图 23 显示了我所使用的值:

图 23. PostgreSQL database connection 对话框
Bonita 中 PostgreSQL database connection 对话框屏幕截图

输入数据库连接信息之后,单击 Next 按钮。

提供一个 SQL 查询来从数据库读取数据

现在您已经有一个查询对话框了,如图 24 所示,您可以在其中输入一个 SQL 查询语句来检查房间使用情况:

图 24. 输入一个 SQL 查询
输入一个 SQL 查询的屏幕截图

您知道 requiredRoomType 变量存储用户的选择。因此,SQL 查询必须检查那类房间是否可用,使用 requiredRoomType 变量。在 Query 文本框输入以下查询:

12Select "Availability" from "RoomInfo" WHERE "RoomType" = '${requiredRoomType}' AND "Availability" = TRUE

这个查询语句从 PostgreSQL 的 RoomInfo 表中挑选出了可用性字段为 true 的所有记录。

在执行这个查询之前,Bonita 将使用 requiredRoomType 变量的值替换 ${requiredRoomType}。因此,如果前台接待员在表单中选择 Single 作为所需房间类型,那么实际被执行的 SQL 查询语句是:

12Select "Availability" from "RoomInfo" where "RoomType" = 'Single' AND "Availability" = TRUE

这就是为什么 Bonita 允许您编写在运行时声明的动态 SQL 查询。

在工作流级变量中捕获 SQL 查询的输出

您需要在 isRequiredRoomTypeAvailable 变量中存储 SQL 查询输出,这是您在 第 1 部分 中配置的一个全局变量。单击 Next 按钮,您将看到 Execute a query on a PostgreSQL DB 对话框,它允许您将 SQL 查询输出映射到一个 Bonita 变量。在 Connector output combo 对话框输入 rowSet.getValues().asBoolean(),然后从 Destination 变量下拉列表中选择 isRequiredRoomTypeAvailable,如图 25 所示:

图 25. 将 SQL 查询映射到一个 Bonita 变量
显示将 SQL 查询映射到一个 Bonita 变量的屏幕截图

如果有预订类型的房间,rowSet.getValues().asBoolean() 方法将插入 true 作为 isRequiredRoomTypeAvailable 变量的值。

您已经将您的工作流连接到数据库了。现在,您可以执行最后一个工作流配置步骤:设计客房预订表单,收集客户信息和预订信息。在这一步,定义 CustomerNamePhoneNumber 和 BookingDate 局部变量来保存客户信息。然后使用 Create a new form 界面(见 图 3) 来设计新表单。最后,配置连接器,编写一个 SQL 查询语句来将客房预订信息提交给数据库。我已经讲解了所有步骤,那么我将这个表单留给您做一个练习。本文 源代码中的 RoomBookingDiagram_2.0.proc 文件包含客房预订工作流的最终交互。

集成 JasperReports 和 Bonita

现在,您已经配置了完整的客房预订工作流。在我说明如何执行工作流之前,我将向您展示如何集成 JasperReports 和 EnterRoomInformation 活动。Bonita-JasperReports 集成在 BPM 应用程序中非常有用,因为报告功能在真实场景中是经常需要的,比如酒店预订流程。另外 JasperReports 也是最流行的开源报告引擎。

您需要先安装 JasperReports,然后再使用它和 Bonita。跳转到 JasperReports 网站,获取下载和安装操作说明(见 参考资料)。

使用 EnterRoomInformation 活动配置 JasperReports 的过程类似于您在 连接 Bonita 到 PostgreSQL 小节中执行的步骤。在白板中选择 EnterRoomInformation 活动,然后单击它的 Connectors 选项卡,并单击 Add。您将看到 Name the connector 对话框。然后在 Select a connector 对话框中从 Jasper 项选择 Create report – Create a Jasper Report from a database 选项。在 Name the connector 对话框,输入 BookingSummaryReport 作为连接器的名称。

之后,您将看到 Database access information 对话框,如图 26 所示,要求您输入连接您的数据库所需的信息:

图 26. 输入 JasperReports 的数据库访问信息
输入 JasperReports 数据库访问信息屏幕截图

在 Database driver 字段输入 org.postgresql.Driverorg.postgresql.Driver 是 JDBC 驱动器,您使用 PostgreSQL 数据库时需要它。图 26 中其他字段值是我输入的配置:JDBC URL 字段的 jdbc:postgresql://localhost:5432/hotelDB, User name 和 Password 字段的 postgres

关于连接 JasperReports 和关系数据库(比如,PostgreSQL)的详细信息,见 参考资料

单击 Next 按钮,Report Settings 对话框打开,如图 27 所示:

图 27. JasperReports 的报告设置
Bonita for JasperReports 中的报告设置对话框的屏幕截图

这个对话框要求您输入 JasperReports XML (JRXML) 文件的路径。JasperReports 报告被设计为 JRXML 文件。本文的源代码 下载 部分提供了一个简单客房预订汇总报告的 CurrentBookingSummaryReport.jrxml 文件。将这个文件复制到您所选择的位置,然后在 JRXML 文件路径字段中提供文件路径。

在 Output 文件路径字段,指定您想要 Bonita 保存客房预订汇总报告 PDF 版本的位置。在 Output 格式字段,选择 PDF。单击 Finish,您的客房预订汇总报告现在完全集成到 Bonita 了。

执行客房预订工作流

Bonita 与 Jetty 捆绑在一起,一个流行的开源 web 服务器。这使得用户在 Bonita 中较为容易地测试 BPM 应用程序。

在您尝试客房预订工作流之前,您需要建立 PostgreSQL 数据库,然后填充样例数据,如果还没有这样做。在源代码 下载 部分,参考 Readme.txt 文件,获取构建和填充样例代码(我过去试验的应用程序)的操作指南。

下载部分也包含 RoomBookingDiagram_2.0.proc,其中包含拥有所有表单和变量的完整客房预订工作流。从 Bonita 文件菜单打开该文件,然后在 Bonita 工具栏单击 Run 来执行工作流,如图 28 所示:

图 28. Bonita 工具栏
Bonita 工具栏屏幕截图

单击 Run 按钮时,Bonita 自动将客房预订工作流绑定到一个 web 归档文件(WAR),WAR 部署和运行在 Jetty 上。Bonita 然后在 web 浏览器打开 EnterRoomInformation 表单,如图 29 所示:

图 29. EnterRoomInformation 表单
在 web 浏览器中打开的 EnterRoomInformation 表单的屏幕截图

您可以看到,在 Type of room required 下拉列表中 Single 是默认选中的。选择 Double 然后单击 Check Room Availability 按钮。您再一次得到相同的 EnterRoomInformation 表单,因为在样例数据中没有双人间可以预订。

现在重新选择 Single,然后单击 Check Room Availability 按钮。由于客房预订数据库中的样例数据表明只有单人间可以预订,现在 BookRoom 表单出现,如图 3 所示:

图 30. BookRoom 表单
BookRoom 表单屏幕截图

您也可以观察到,EnterRoomInformation 活动已经在您之前指定的位置保存了客房预订汇总 JasperReports 报告的一个 PDF 版本。

结束语

在这个 两部分系列 文章中,您使用 Bonita 配置和执行了一个简单的酒店客房预订工作流作为一个 BPM 应用程序,也将您的工作流和两个外部应用程序连接起来。在这个配置中您所要做的就是使用 Bonita 的图形化工作流和表单编辑器,而不用编写任何 Java 代码。

与外部应用程序连接几乎在所有 BPM 应用程序中都是必须的。大多数实际 BPM 应用程序需要超过多个 BPM 引擎和许多其他非 BPM 外部应用程序共同工作。目前,没有标准 Java API 可用来描述一个 BPM 工具如何连接外部应用程序,以及不同 BPM 工具如何彼此相互连接。为此,每个 BPM 工具必须设计某种接口机制,比如 Bonita 的连接器机制。如果开发一个标准 Java BPM API — 定义一个 BPM 工具或其他应用程序如何公开其功能来集成到工作流 — 此接口机制可以实现无缝连接。

转:https://www.ibm.com/developerworks/cn/java/j-bpm2/index.html