在 WebSphere Process Server 中为新的查询要求设置自定义属性
2010-08-05 00:00:00 来源:WEB开发网简介
在您开发一个业务流程客户端程序时,您经常需要在一个流程实例内,通过某些业务数据标准来查询流程实例、活动和任务。例如,您可能想要在流程实例中寻找与某个 ID 的客户相关的所有任务。
当您在 WebSphere Integration Developer(以下简称为 Integration Developer)设计流程时,可以通过为人工任务设置自定义属性来实现这个需求。然而,当流程投入使用后,如果新查询要求需要新的自定义属性,那么这招就不灵了。您当然可以使用 WebSphere Process Server(以下简称为 Process Server)提供的流程版本控制方法,在新版业务流程中增加新的自定义属性。然而,使用新的自定义属性不能对已有的旧版业务流程进行查询。
本文对熟悉业务流程开发的业务流程设计师和程序员有一定的帮助。本文假设您熟悉 Process Server 和用 Integration Developer 开发业务流程应用程序。
在本文中,我们假设 Integration Developer V6.1.2 已得到合理安装。
本文介绍一种动态的方法,该方法使用 Business Process Choreographer(BPC) EJB API 来为正在运行的业务流程实例设置自定义属性,从而解决此类问题。
我们将利用一个简单的命令审计流程来说明这个解决方案。样例流程工作流包括以下典型步骤:
客户提交一个订单请求,其中含有用户和审计人员的信息。
审计人员批准或拒绝请求。
最后,当审计人员批准或拒绝请求后,系统给客户一个响应。
样例和模块将在以下几节描述。
准备样例流程项目
使用准备好的业务流程按如下方式导入项目交换文件:
下载提供的 OrderDemo.zip 文件,并将其保存到一个临时目录中。
在 WebSphere Integration Developer 中,单击 File -> Import。Import 对话框打开。
选择 Project Interchange。
单击 Next。Import Project Interchange Contents 窗口打开(如图 1 所示)。
图 1. Import 对话框
单击 “From zip file” 旁边的 Browse。
浏览临时目录,选择第 1 步中下载的压缩文件。
单击 Open。
选择您的工作空间目录作为您的 Project location root。
单击 Select All。
单击 Finish。
您需要使用与上面相似的步骤,将提供的包含流程数据类型的 OrderDemoLib.zip 导入工作空间。您将得到如图 2 所示的项目结构。以下部分将对此做详细解释。
图 2. 流程项目结构
业务对象和 BPEL 流程
订单审计流程有两个必需的业务对象(BO):OrderRequest 和 PersonInfo(见图 3)。OrderRequest 保存订单信息,包括客户、审计人员、状态和商品编号。PersonInfo 包含个人信息,比如 ID、姓名和地址。
图 3. 业务对象
图 4 展示了 Integration Developer BPEL 中设计的流程:
Receive 活动是流程的起始点。流程从客户端收到一个消息(OrderRequest),接着开始流程。消息中的数据存储在一个流程变量(请求)中。
Assign 活动执行该流程所需的数据映射。
Order Info 片段打印订单信息。
ApproveOrderRequest 是审计人员批准或拒绝请求的一个人工任务。
Approve 选项根据审计人员的决议决定下一步。系统将使用 Approve Response 和 Reject Response 片段打印相应的回复。
图 4. 流程
使用 BPC Explorer 运行样例
在嵌入 Integration Developer 的测试服务器上部署了 OrderDemoApp 之后,使用 Business Process Choreographer (BPC) Explorer 运行样例,步骤如下:
在 “My Process Templates” 页面(见图 5)上选择 OrderProcess,然后单击 Start Instance。
图 5. 流程模板
查看原图(大图)
填写 Process Input Message 部分并单击 Submit (见图 6)。
图 6. Process Input Message
在 My To-dos 页面(见图 7)上处理 ApproveOrderRequest 人工任务工作。
图 7. My To-dos
输入 Task Output Message(true 表示批准,false 表示拒绝)。单击 Complete(见图 8)。
图 8. 处理 Task Message
在控制台上(见图 9),您可以看到测试结果(日志以 Java™ 片段打印)。
图 9. 控制台
为何需要设置自定义属性
一般来说,您需要开发一个客户端应用程序来启动和完成流程实例,而不是使用 BPC Explorer。WebSphere Process Server V6 提供 BPC EJB API 来访问和处理业务流程和人工任务。事实上,有两个独立的 API 集合:Business Flow Manager API 和 Human Task Manager API。
当我们建立流程客户端应用程序时,常常希望定位一个特定的流程实例或人工任务,其业务数据满足某个标准。例如,可能需要通过特定的订单号寻找流程实例。
这部分说明了为什么您需要为查询要求设置自定义属性。查询出任务之前,您需要启动流程实例。
您可以使用与导入流程项目的类似的步骤,将提供的 OrderProcessExport.zip 导入您的工作空间。该项目的所有代码片段在本项目后面部分都能找到。
清单 1 显示了这些使用 Business Flow Manager API 来启动一个带有输入消息的 “OrderProcess” 实例的代码片段。
清单 1. 使用 BPC EJB API 启动流程
// Create the input ClientObjectWrapper
com.ibm.bpe.api.ClientObjectWrapper cow = flows.createMessage(
processTemplate.getID(), processTemplate.getInputMessageTypeName());
// Get the Input DataObject from the ClientObjectWrapper
DataObject dataObject = (DataObject) cow.getObject();
dataObject.setDataObject("request", OrderRequest);
//Initiate process instance
com.ibm.bpe.api.PIID piid = flows.initiate("OrderProcess", cow);
流程实例启动后,名为 “ApproveOrderRequest” 的人工任务将被启动,等待审计人员完成。完成任务之前,您需要通过订单号查询出任务。清单 2 显示了使用 Human Task Manager 通过订单号过滤任务的代码片段 。
清单 2. 通过订单号获取特定待处理任务
QueryResultSet instances = htms.query("DISTINCT TASK.TKIID",
"TASK.NAME='OrderProcess$ApproveOrderRequestTask' AND
TASK.STATE=TASK.STATE.STATE_READY", null, null, null, null);
while (instances != null && instances.next()) {
TKIID tkiid = (TKIID) instances.getOID(1);
ClientObjectWrapper cow = htms.getInputMessage(tkiid.toString());
DataObject input = (DataObject) cow.getObject();
if (orderNo.equals(input.getString("orderNo"))) {
System.out.println("find!!!");
}
}
您可以在预定义的 BPC 数据库视图上执行 SQL 查询。然而,像在输入消息(业务对象)中定义的订单号这类业务数据,在数据库视图中不能查询。您不得不通过流程的输入消息从所有待处理任务中过滤。如果审计人员有很多待处理任务,这个方法将可能导致性能问题。您也需要改进查询方法和自定义属性来满足您的需求。您可以指定业务流程自定义属性及其所有的基本活动。一个自定义属性有一个名称和一个可选值(字符串)。BPC 数 据 库 提 供一个 PROCESS_ATTRIBUTE 视图,您可以使用该视图查询流程人工任务,方法是将订单号定义为流程自定义属性。
除了性能问题之外,还有另一个重要的原因:如果在流程的输入消息中不包含查询标准,您就不能用输入消息过滤实例。然而您可以用 BPC EJB API 设置标准作为自定义属性来满足这类需求 。
根据自定义属性执行查询之前,您需要为流程实例设置自定义属性。
如何设置自定义属性
当启动流程实例时,您可以使用 BPEL 流程中的一个 Java 片段或 BPC EJB API 来设置自定义属性。下面将分别介绍这两种方法。
在 Integration Developer 中使用 Java 片 段设置自定义属性
您可以在流程的开始增加一个 Java 片段。输入以下设置语句,如图 10 所示:
setProcessCustomProperty(“orderNo”, orderNo);
图 10. 使用 Java 片段设置流程自定义属性
查看原图(大图)
使用 BPC EJB API 设置自定义属性
流程实例启动之后,您也可以使用 BPC EJB API 将订单号设置为自定义属性,如清单 3 所示。
清单 3. 使用 BPC EJB API 设置自定义属性
String orderNo = request.getString("orderNo");
if (orderNo != null && !"".equals(orderNo)) {
bfms.setCustomProperty(piid, "orderNo", orderNo);
}
流程启动之后,您可以在 BPC Explorer 中查看自定义属性,如图 11所示。
图 11. 检查现有流程实例属性
通过预定义的自定义属性查询待处理任务
您可以使用预定义的数据库视图 PROCESS_ATTRIBUTE 查询自定义属性,如表 1 所示。
表 1. PROCESS_ATTRIBUT 视图
列名 | 类型 | 注释 |
PIID | ID | 含有一个自定义属性的流程实例的 ID。 |
NAME | String | 自定义属性的名称。 |
VALUE | String | 自定义属性值。 |
清单 4 显示了如何通过自定义属性查询待处理任务。
清单 4. 通过自定义属性查询待处理任务
QueryResultSet instances = htms.query("DISTINCT TASK.TKIID",
"WORK_ITEM.OBJECT_ID = TASK.TKIID AND WORK_ITEM.ASSOC_OID = PROCESS_ATTRIBUTE.PIID AND
PROCESS_ATTRIBUTE.NAME= 'orderNo' AND PROCESS_ATTRIBUTE.VALUE ='" + orderNo + "' AND
(TASK.STATE = TASK.STATE.STATE_READY OR TASK.STATE = TASK.STATE.STATE_CLAIMED ) AND
TASK.SUSPENDED = FALSE AND WORK_ITEM.REASON=1 AND WORK_ITEM.OBJECT_TYPE=5 ",
null, null, null, null);
if (instances.size() > 0) {
instances.first();
TKIID tkiid = (TKIID) instances.getOID(1);
ClientObjectWrapper cow = htms.getInputMessage(tkiid.toString());
DataObject input = (DataObject) cow.getObject();
}
您可以使用查询、通过自定义属性直接获取订单号的任务 ID。这将会产生较好的性能。
如何满足新的查询要求
如果在业务流程运行之后,出现一个新的查询要求,此时,您该做什么?例如,您想要根据 customerId 而非 orderNo 查询流程实例。您需要添加一个新的名为 “customerId” 的自定义属性来支持新的查询要求。如您所知,样例流程是一个长期流程,就是说,可能有多个实例运行在生产服务器上。这意味着您需要添加新的自定义属性, 不仅要为新启动的流程实例添加,也要为服务器上已存的实例添加。
为新启动的流程实例设置新自定义属性
有两种方法来实现这个要求。您可以实现一个新版业务流程,在 Java 片段中添加新的自定义属性。对于版本控制方法,参见 Versioning business processes and human tasks in WebSphere Process Server。另一种方法是,为新启动的流程实例添加新的自定义属性 customerId。对于第二种方法,您不需要进行流程版本控制。
从这个角度来看,使用 BPC EBJ API 比在 BPEL 流程中设置自定义属性要好一些。有了 API,您可以根据需求变化动态地添加新的客户属性,而不需要对 BPEL 流程进行版本控制。清单 5 显示了如何使用 BPC EJB API 设置一个新的自定义属性。
清单 5. 为新启动的实例设置自定义属性
//Initiate the process instance as usual
com.ibm.bpe.api.PIID piid = flows.initiate("orderProcess", cow);
//Set custom property after process instance is initiated.
flows.setCustomProperty(piid, "orderNo",“000001”);
flows.setCustomProperty(piid, "customerId",“C00001”);
现在,您可以根据新的自定义属性 customerId 来查询待处理任务,从而满足新的需求。
为运行中的流程实例设置新自定义属性
通过使用 BPC EJB API,您可以搜索运行中的流程实例,并为其添加一个新自定义属性。清单 6 显示了如何为运行中的实例添加一个新自定义属性。
清单 6. 为运行中的实例设置自定义属性
QueryResultSet instances = flows.query("DISTINCT PROCESS_INSTANCE.PIID",
"PROCESS_INSTANCE.STATE = 2 AND PROCESS_INSTANCE.TEMPLATE_NAME
='OrderProcess' ", "", null, null);
while (instances .next())
{
PIID piid = (PIID) result.getOID(1);
flows.setCustomProperty(piid, "customerId", customerIdValue);
}
根据自定义属性查询待处理任务
就像根据 orderNo 查询待处理任务那样,现在,您可以根据 customerId (见清单 7)执行查询。
清单 7. 根据新的自定义属性查询待处理任务
QueryResultSet instances = htms.query("DISTINCT TASK.TKIID", "WORK_ITEM.OBJECT_ID
= TASK.TKIID AND WORK_ITEM.ASSOC_OID = PROCESS_ATTRIBUTE.PIID AND
PROCESS_ATTRIBUTE.NAME= 'customerId' AND PROCESS_ATTRIBUTE.VALUE ='" + customerId
+ "' AND (TASK.STATE = TASK.STATE.STATE_READY OR TASK.STATE = TASK.STATE.STATE_CLAIMED )
AND TASK.SUSPENDED = FALSE AND WORK_ITEM.REASON=1 AND WORK_ITEM.OBJECT_TYPE=5 ", null,
null, null, null);
if (instances.size() > 0) {
instances.first();
TKIID tkiid = (TKIID) instances.getOID(1);
ClientObjectWrapper cow = htms.getInputMessage(tkiid.toString());
DataObject input = (DataObject) cow.getObject();
System.out.println("find customerId:" + customerId + " orderNo:
" + input.getString("orderNo"));
}
在 Integration Developer 中测试客户端应用程序
您可以测试 OrderProcessExport 项目,这是一个实现了流程实例的启动和查询的 Java 客户端应用程序。将两个模块 OrderDemo 和 OrderProcessExport 部署到 Integration Developer 中的测试服务器之后,您可以在 Integration Developer中使用测试模块测试该项功能。
图 12. 在 Integration Developer 中测试客户端应用程序
您可以参考函数描述(表 2)来执行测试。
表 2. PROCESS_ATTRIBUTE 视图
方法名 | 功能 |
initProcess | 启动一个新的流程实例。 |
initProcessWithOrderNo | 启动一个新的流程实例并为该实例设置自定义属性 orderNo。 |
initProcessWithCustomerId | 启动一个新流程实例,并为该实例设置自定义属性 customerId。 |
queryTodoTaskByOrderNo | 根据请求的 orderNo 查询特定待处理任务。 |
queryTodoTaskByCustom PropertyWithOrderNo | 根据自定义属性 orderNo 查询特定待处理任务。 |
queryTodoTaskByCustom PropertyWithCustomerId | 根据自定义属性 cusomerId 查询特定待处理任务。 |
addCustomPropertyFor RunningProcess | 为运行中的流程实例添加新的自定义属性。 |
结束语
基于业务流程的应用程序包括长期实例,这种实例可以运行几周、几月、甚至几年。业务需求随时间而变化。WebSphere Process Server V6.1 提供一个称为 “流程版本控制” 的技术,来帮助升级基于业务流程的应用程序,以满足新环境和业务需求。然而,您还需要修改已有的实例来满足新的查询要求。本文介绍了一种动态方法,它使用 Business Process Choreographer EJB API 来为新流程实例和运行中的实例设置自定义属性,从而满足新的查询要求。使用这种方法,您不需要更新流程来添加一个新的自定义属性。
下载
描述 | 名字 | 大小 | 下载方法 |
样例脚本 | OrderDemo.zip | 11KB | HTTP |
样例脚本 | OrderDemoLib.zip | 5KB | HTTP |
样例脚本 | OrderProcessExport.zip | 2,012KB | HTTP |
- ››WebSphere Application Server 7.0 XML Feature P...
- ››WebSphere 反向投资者: 解决 WebSphere Applicati...
- ››WebSphere sMash 的创新应用,第 2 部分: 借助包装...
- ››Websphere MQ v6集群的负载均衡新功能
- ››WebSphere Process Server V6.0.2 集群,第 2 部分...
- ››WebSphere Process Server V6.0.2 集群,第 1 部分...
- ››WebSphere MQ性能调优浅谈
- ››WebSphere配置资源库管理
- ››WebSphere中的SSL/TLS:用法、配置和性能
- ››websphere ejb远程/本地调用总结
- ››WebSphere Application Server对SIP的支持
- ››WebSphere Process Server V6 体系结构概述
更多精彩
赞助商链接