一、 引言
在developerWorks中,有许多文章介绍了WPS和WID在流程整合中的应用,比如BPEL开发、CEI监控和selector等等,那么,在实际的应用中,通常会有这样的场景:流程调用的一些第三方系统都是需要人工去审批,流程引擎发出调用第三方系统的请求后,是一个需要人审批的长流程(Long-runing process)。因此,这个调用是一个异步调用,只有第三方系统把审批结果传回给主流程,流程才能继续往下运行。这和直接在BPEL中直接实现的human task节点是不同的,因为用到了SCA组件的装配技术。
本文将详细介绍如何在WPS中利用SCA的编程模型实现human task manager对第三方系统的调用,并通过实际的例子加以说明,使读者能够掌握使用SCA和human task manager来实现对第三方系统的异步调用。
二、产品及其基本技术框架简介
1 WebSphere Process Server及其开发工具Integration Developer
WebSphere Process Server V 6.0(WebSphere流程服务器V 6.0)基于SOA体系架构并提供了统一的、简化的编程模型,是新一代的业务流程服务器,能够帮助我们基于SOA架构模型实现企业的业务流程转型。WebSphere流程服务器采用基于开放标准的技术来整合业务流程,实现自动化的流程服务器。采用WebSphere流程服务器可以通过统一的编程模型将企业的人员、工作流程、应用、系统、平台和基础设施整合在一起。
基于Eclipse技术的WPS专用开发工具WebSphere Integration Developer V6.0则为快速组装、开发业务解决方案提供了新一代的开发工具。采用这一工具可以基于统一的编程模型通过BPEL(Business Process Execution Language, 业务流程执行语言)来描述各类流程。它易于使用,仅需要少量的相关技能即可使用,并且提供了开发、测试和将应用部署到流程服务器的功能。
2 基本技术实现框架
2.1 SCA(服务组件编程架构模型)
为了使客户能够更加简单的实现向这种面向服务架构的转变,IBM在推出一系列WebSphere新产品的同时,提出了一种新的服务组件模型。这是一种全新的、跟语言无关的编程模型,它提供了一种统一的调用方式,从而使得客户可以把不同的组件类型,比如POJO, EJB, 流程组件,人工交互组件等都可以通过一种标准的接口来封装和调用。结合SDO的数据模型,这种服务组件的编程模型可以大大的简化客户的编程,提高应用的灵活性,这就是面向服务组件的架构(Service Component Architecture,SCA)。
2.2 human task
WPS V6中的人工任务管理器(Human Task Manager)模块实现了与人工任务相关的下列功能:
- 让用户启动业务流程或者其他Service 组件
- 实现业务流程中的Staff活动
- 流程管理(Administration)
- 动态创建含有与人工或者Service交互的任务
人工任务管理器针对三种基本场景:机器-人(Machine-to-Human),人-机器(Human-to-Machine),和人-人(Human-to-Human)。相应的,人工任务有四种不同类型,见下图。
图: 人工任务管理器
其中,机器-人场景中的人工任务(participants)是我们这篇文章要主要介绍的,它使流程调用的service的执行中能融入人工交互,典型的例子是一个业务流程为参与业务执行的人创建任务。pTask是一个标准的SCA 组件,可以被用在任何希望引入人工交互的应用中而不仅仅是业务流程。
与其他工作流类的流程整合解决方案不同,WPS中引入了基于SCA service的人工任务,用户可以灵活地替换系统中基于SCA service的自动service和真正的人工实现。
2.3 Interface开发
在下面的实例中,我们是根据需求来确定出出第三方系统与主流程调用的接口(硬连接的方式),而在企业级应用中,也可以通过实施IBM WebSphere Message Broker来作为连接的应用接口,帮助WPS来连接企业应用。
三、样例背景及解决方案概述
3.1 方案背景
许多公司在不同时期都开发了企业内部的审批系统,某个部门内部的业务都各自有独立的系统来进行审批,而有的业务需要不同部门合作,那就只有通过人工来审批,手续相当繁琐,效率也不高。而为某项业务重新开发新的工作流引擎,又舍不得以前的IT投资,因此,企业就有了这样的需求:能否有这样的流程控制器可以将不同部门的独立系统统一的利用起来,实现跨系统的易更改工作流呢?
在我们这篇文章所举的范例中,是一个基于BPEL的审批流程,其中涉及到财务系统,项目管理系统2个独立的系统。其中财务系统是由Deiphi + OCX控件实现的,由SQL server存储数据;项目管理系统是一个J2EE系统,用DB2 数据库存储数据。
在需求中,项目管理系统必须依赖于财务系统才能进行审核等操作,需要把财务系统的数据传给项目管理系统,适当的时候,项目管理系统也要把相关数据传给财务系统。在此基础上,客户还可能有更高的需求,他们不但想要有流程的整合,还要有门户的整合,信息的整合。
3.2 IBM的解决方案
用WebSphere Process Server来做流程的整合,需要在不同的节点上完成与Deiphi和J2EE系统的异步调用,同时用Portal来做门户和信息的整合,并配置SSO, 用户只需要在Portal进行一次登陆,就可以相应的访问WPS系统、财务系统(DEiphi)、项目管理系统(J2EE)。相应用户登陆后可以看到自己的任务列表,如预算编制,项目建立,项目审批等。用户点击相应的任务,通过human task接口直接可以访问到第三方的系统,由第三方的系统得到与任务有关的数据,并直接组织数据发送给WPS.他们之间的通信方式是在SOAP协议上传输XML数据。
3.3 可行性分析
在WPS的装配图里可以实现的是,第三方的系统只需要提供一个接口,WPS就可以以异步或同步方式来访问组件。此需求里,客户要在系统里首先能看到自己的任务列表,点击不同的任务来决定到那个系统去。如客户任务列表里有一项的任务是"预算编制",用户一点击"预算编制",在Portal的另一个iframe就应把财务系统的相应界面调出来。Deiphi根据TaskID到WPS上把相应的数据取到本地并进行处理,用户进行适当的操作以后,Deiphi再把相应的数据发送给WPS,此过程可如下图所示:
图:HumantaskManager调用第三方系统流程
四、解决方案开发
这一章将论述实现这个解决方案的每一个大的步骤,但并不详细论述如何step by step的实现,比如怎样定义BO,定义接口等,他们已超出了本次主题。因此,本文的读者必须对WID和WPS有一定的了解。
4.1 定义BO
BO是工作流平台与外界进行数据交互的数据格式,第一步我们首先明确工作流平台与第三方系统进行数据交互的定义,根据业务流程的需要,在每一个流程节点,第三方系统需要向WPS工作流平台放入哪些数据项,想要从工作流平台得到什么数据,都要定义出来。 如下图所示:
在BPEL每次调用第三方系统时,必须前期将输入输出的参数确定。主流程传出业务数据对象(BO),第三方系统接受后,进入自己的子流程,通过人工处理,将主流程需要的参数也以BO的方式传递给主流程,使流程能够继续运行。
在我们的例子中,主流程与2个子系统每次交互中,我们都定义了两个BO作为数据输入输出的数据格式,分别是OperationNameIN和OperationNameOut。在下图中,对应"编制预算"这个操作,我们分别定义2个BO,即BudgetBuildIn和BudgetBuildOut.
图:定义BO
4.2 定义接口
这一步需要定义接口,如操作名称,输入数据及输出数据的定义,在WPS的开发流程里,每一个组件如果能在装配图里能被其他的组件所调用,就必须定义接口, Human Task 也不例外。
每个操作的输入和输出数据(input和output)的数据类型可以用默认的数据类型,如int、boolean等,也可以用我们定义好的BO。在我们的例子中,由于每次与财务系统或者项目管理系统交互时,都是组合数据,因此都用定义好的BO作为数据类型。如下图所示,在BudgetBuild接口中,定义了编制预算的操作:其输入输出的数据类型分别为budgetBuildIn和budgetBuildOut。
图:接口的定义
4.3 流程的具体定义
在Process里我们根据用户的具体业务需求,实现每一个节点,明确每一个节点是与那个系统进行交互的。整个Process有几次invoke,就表明与财务系统和项目管理系统有几次交互,即humantask实现的接口。
图:设计流程(BPEL)
4.4 定义装配图
完成了所有的接口定义以后,我们需要在装配图里把他们都明确的用线连接起来,可以清楚地明确他们之间的调用关系及数据流向。如下图所示,把每个接口都拖入到装配图中,再分别用humantask来实现。最后,再把主流程Process拖到装配图中,通过"Wire to Existing"连接所有组件。
图:组件装配SCA
4.5 对外export 一个调用接口
所有的第三方系统通过这个component 来访问到WPS工作流平台。我们同样在装配图中建起连接。
图:暴露调用接口(SCA)
4.6 实现一个统一的调用接口
如图所示,财务系统需要从WPS工作流平台得到与这个任务相关的数据,有人工处理以后,要传回到WPS工作流平台,并complete 这个任务。这里我们实现一个web service, 并对外提供两个接口供所有第三方系统进行调用,如Deilhpi, MQ WorkFlow, J2EE等。
该webservice的WSDL描述如下:
<wsdl:operation name="getHTInput">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getHTInputRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ForMIS.ibm.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getHTInputResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ForMIS.ibm.com" use="encoded"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="setHTOutput">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="setHTOutputRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ForMIS.ibm.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="setHTOutputResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ForMIS.ibm.com" use="encoded"/>
</wsdl:output>
</wsdl:operation>
|
实现操作如下所述:
实现getHTInput operation
1) 得到HumanTaskManager实例
RelationshipService relService = (RelationshipService) ServiceManager.INSTANCE
.locateService("com/ibm/wbiserver/rel/RelationshipService");
InitialContext ctx = new InitialContext();
Object myObj = ctx.lookup(HTM_MANAGER_NAME);
HumanTaskManagerHome myHome = (HumanTaskManagerHome) PortableRemoteObject.narrow
(myObj, com.ibm.task.api.HumanTaskManagerHome.class);
HumanTaskManager humanTaskManager = myHome.create();
|
2) 根据taskID得到第三方系统的需要得到的数据
ClientObjectWrapper input = null;
input = humanTaskManager.getInputMessage(id);
|
实现setOutput operation
1) 得到HumanTaskManager实例
RelationshipService relService = (RelationshipService) ServiceManager.INSTANCE
.locateService("com/ibm/wbiserver/rel/RelationshipService");
InitialContext ctx = new InitialContext();
Object myObj = ctx.lookup(HTM_MANAGER_NAME);
HumanTaskManagerHome myHome = (HumanTaskManagerHome) PortableRemoteObject.narrow(myObj,
com.ibm.task.api.HumanTaskManagerHome.class);
HumanTaskManager humanTaskManager = myHome.create();
|
2) 根据taskID,把第三方上传的数据赋给WPS相应的Human Task
ClientObjectWrapper outputWrapper = humanTaskManager.createOutputMessage(id);
BusObjImpl busObjImpl = (BusObjImpl) outputWrapper
.getObject();
busObjImpl.set(0, output);
|
3) 完成这个任务complete
humanTaskManager.complete(id,outputWrapper);
|
4. 7 试与部署
首先访问Http://localhost:9080/bpc 用bpc explorer进行测试,证明所有的节点都可以走通,就可以部署到WPS服务器上,与Portal及第三方系统(Deilphi, MQ WorkFlow, J2EE)进行互联测试。运行实例演示如下:
4.7.1 下图是获取任务列表的演示效果:
登陆系统后,用户将在系统中看到自己的任务列表,点中任务,就可以在下方的portlet中进行信息输入和审批。
图:任务列表和任务的人工处理
4.7.2. 与Deiphi进行交互的页面
图:调用财务系统处理界面
流程进入财务系统后,将调用财务系统,在OCX控件中进行相应的操作和处理,然后再把流程往下运行所需要的数据再传回给process。
4.7.3. 与MQ WorkFlow 的交互页面
图:调用项目管理操作界面
与财务系统一样,当流程调用到项目管理系统时,也出现了项目管理所采用的MQ workflow的界面,进行相应处理和审批后,将数据传回给WPS,于是流程就可以继续往下运行。
五. 结束语
本篇文章主要讲述了一个解决方案,即如何利用Human Task把第三方系统连接到WPS 里,并实现人工参与及异步通信。这里着重介绍了解决方案的大致步骤,而没有关注于细节的描述。