对于国内的客户,Oracle提供的huaman task ui不能满足客户的需求。大部分的客户都需要重新来开发。个人认为这样的要求不算过分,企业内部的BPM规划本来就应该走向公共单一平台的设计模式,也就是,理想状态可是使用多种的语言开发,比如.NET,JAVA,C++,有需要内部流程管理,或者跨系统流程应用整合,都可以将流程部署至此平台,前段应用程序可以维持原先界面的操作,只是适当的通过API或者特定的界面与BPM进行审批等即可。
因此,在BPM的架构中,个人觉得除了流程设计需要灵活性之外,前端也是另一个非常重要的主题。对于前段应用与后端系统整合的方式,又各有不同的方式,前段着重与用户交互,后端着重使用SOA架构下,来整合现有的系统。
假设我们需要这样一个简单的审核流程,BPMN如下:
![Image](http://www.fmw007.com/wp-content/uploads/2012/04/Image1.png)
如图所示,我们设计一个流程,其中包含了两个泳道,分别是为发起InitTask,审核所使用的ConfirmTask;个人交给两个角色,分别为InitRole,ComfirmRole来负责。在流程中只有一个对象,其XML Schema如下:
1
2 3 4 5 6 7 8 9 10 11 12 |
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:customhumantask="http://blogdemo/customhumantask" targetNamespace="http://blogdemo/customhumantask" elementFormDefault="qualified"> <xsd:element name="hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="helloString" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> |
简单的说:有个数对象hello,其中内容为名字helloString的字符串。
Oracle BPM提供了Human Workflow Service模式用以处理人机交互。它有两种方式来使用:
其一是使用JAVA开发,建议直接使用Java API来操作human task,jaava API底层会通过Local/Remote EJB或者SOAP的方式连接BPM Server.也就是说我们开发的应用程序并不需要BPM Server绑定到同一个容器。
第二个是如果你不是使用JAVA语言,只能通过Web Service以SOAP的方式连接BPM Server,也是因为是SOAP,你可是使用不同的语言来开发。
本次我们先介绍使用JAVA来开发的方式:
开始之前我们可以先看一下这样的流程到底与前端程序的交互点:
1. initRole发起流程。
2. InitRole查询提交单,填入相关信息,提交流程。
3. ConfirmRole查询流程到自己的自身的task,取出详细信息,更改审核结果,完成流程。
上面的交互会用到Oracle BPM 的API中的
createProcessInstance(),queryTasks().getTaskDetailsByID(),updateTaskOutcome()等函数。
1. 开发前需要准备的library:
首先,你需要如下JAR file 在你的project之中,
- <MW_HOME>/wlserver_10.3/server/lib/wlfullclient.jar
- <MW_HOME>/oracle_common/webservices/wsclient_extended.jar
- <MW_HOME>/oracle_common/modules/oracle.xdk_11.1.0/xml.jar
- <MW_HOME>/oracle_common/modules/oracle.xdk_11.1.0/xmlparserv2.jar
- <MW_HOME>/Oracle_SOA/soa/modules/oracle.soa.fabric_11.1.1/bpm-infra.jar
- <MW_HOME>/Oracle_SOA/soa/modules/oracle.soa.fabric_11.1.1/fabric-runtime.jar
- <MW_HOME>/Oracle_SOA/soa/modules/oracle.soa.workflow_11.1.1/bpm-services.jar
- <MW_HOME>/Oracle_SOA/soa/modules/oracle.bpm.client_11.1.1/oracle.bpm.bpm-services.client.jar
wlfullclient.jar需要自己生成,可以使用以下命令:
> cd <MW_HOME>/wlserver_10.3/server/lib
> java -jar ../../../modules/com.bea.core.jarbuilder_1.3.0.0.jar
> java -jar ../../../modules/com.bea.core.jarbuilder_1.3.0.0.jar
你可以使用任何IDE来开发。
2. 初始化BPM server 连接:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//初始化context
Map properties = new HashMap ( ) ; properties. put (IWorkflowServiceClientConstants. CONNECTION_PROPERTY. CLIENT_TYPE, WorkflowServiceClientFactory. REMOTE_CLIENT ) ; properties. put (IWorkflowServiceClientConstants. CONNECTION_PROPERTY. EJB_INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" ) ; properties. put (IWorkflowServiceClientConstants. CONNECTION_PROPERTY. EJB_PROVIDER_URL, "t3://:" ) ; properties. put (IWorkflowServiceClientConstants. CONNECTION_PROPERTY. EJB_SECURITY_CREDENTIALS, "" ) ; properties. put (IWorkflowServiceClientConstants. CONNECTION_PROPERTY. EJB_SECURITY_PRINCIPAL, "" ) ; //实例出BPM Service Client 和 Work Service Client BPMServiceClientFactory bpmServiceClientFactory = BPMServiceClientFactory. getInstance (properties, null, null ) ; IBPMServiceClient bpmSc = bpmServiceClientFactory. getBPMServiceClient ( ) ; IWorkflowServiceClient wfSc = bpmServiceClientFactory. getWorkflowServiceClient ( ) ; 接下来当你需要获得远端连接时,对于BPM Server的使用者认证、task 查询,task 内容变更所需的Service。 IBPMUserAuthenticationService authSvc = bpmServiceClientFactory. getBPMUserAuthenticationService ( ) ; ITaskQueryService querySvc = wfSc. getTaskQueryService ( ) ; ITaskService taskSvc = wfSc. getTaskService ( ) ; |
3. 认证使用者
准备好了远端连接,在使用时需要对当前用户进行认证。
1
|
IBPMContext bpmCtx
= authSvc.
authenticate
(
"tim",
"welcome1".
toCharArray
(
),
null
)
;
|
4. 启动流程
在启动流程之前,你必须确认该流程已经被部署到BPM server上,并且能够在EM中查询到相关信息:
blogdemo/CustomHumanTask!1.0*soa_87c431bf-7757-46de-8c52-55f4f2aabc11
假设你的流程名字为CustomHumanTaskProcess,则产生新实例时需要传入的ID是:
blogdemo/CustomHumanTask!1.0*soa_87c431bf-7757-46de-8c52-55f4f2aabc11/CustomHumanTaskProcess
你可以通过以下API来启动一个新的流程实例:
1
|
String instanceID
= bpmSc.
getInstanceManagementService
(
).
createProcessInstance
(bpmCtx,
"blogdemo/CustomHumanTask!1.0*soa_87c431bf-7757-46de-8c52-55f4f2aabc11/CustomHumanTaskProcess"
)
;
|
API返回的ID即为流程实例.
5.查询task,填写相关信息,完成task
现在流程已经启动,并且执行到第一个task,等待InitRole角色的人处理。
首先,可以使用之前产生的querySvc查询当前分配的人。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
List queryColumns
=
new
ArrayList
(
)
;
queryColumns. add ( "TASKID" ) ; queryColumns. add ( "TASKNUMBER" ) ; queryColumns. add ( "TITLE" ) ; queryColumns. add ( "PRIORITY" ) ; //获取可用的action List optionalInfo = new ArrayList ( ) ; optionalInfo. add (ITaskQueryService. OptionalInfo. ALL_ACTIONS ) ; //指定查询条件 ,这里只查询出已经被分配的task。 Predicate pred = new Predicate (TableConstants. WFTASK_STATE_COLUMN, Predicate. OP_EQ, "ASSIGNED" ) ; //执行查询 result = querySvc. queryTasks (bpmCtx, queryColumns, optionalInfo, ITaskQueryService. AssignmentFilter. MY_AND_GROUP, //本人或其其所属的组 null, // 不使用keywords pred, null, // 不指定查询排序 0, // 不paging查询結果 0 ) ; //接下来回取得Task的负载,特别需要注意的是,Task 的负载一定要通过以下的API来操作,之前的queryTask获得的信息并不包含task的负载。 //使用查询出的task.getSystemAttributes().getTaskId()去取出taskId字串 Task task = querySvc. getTaskDetailsById (bpmCtx, taskId ) ; |
接下来我们需要将负载中的字段赋值,因为所有的负载都是xml文件,所以我们需要解析xml,并修改。一般情况下我们使用标准的W3C DOM的API来操作。(底层是Oracle XML Parser V2)。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//创建XML文件
Document document = XMLUtil. createDocument ( ) ; Element payload = document. createElementNS ( "http://xmlns.oracle.com/bpel/workflow/task", "payload" ) ; Element hello = document. createElementNS ( "http://blogdemo/customhumantask", "hello" ) ; Element helloString = document. createElementNS ( "http://blogdemo/customhumantask", "helloString" ) ; helloString. appendChild (document. createTextNode ( "HELLO TIM!!" ) ) ; hello. appendChild (helloString ) ; payload. appendChild (hello ) ; document. appendChild (payload ) ; //将XML资料指定给task作为其payload task. setPayloadAsElement (payload ) ; //接下来 就将这个已经完成的task,推送出去。 // "SUBMIT"字串是该HumanTask设计之时所指定的Outcome taskSvc. updateTaskOutcome (bpmCtx, task, "SUBMIT" ) ; |
6 第二个节点
和上面类似的,这时候主管通过authenticase()认证,连入BPM server,通过queryTasks()查询待办事项,通过
getTaskDetailsByID取出详细的payload资料,接下来根据设计时所设置的Outcome,调用updateTaskOutcome()将其review的结果指定为APPROVE或者REJECT。
整个流程就这样结束了。
您好,我正在学习Oracle的BPM产品,遇到一些问题,所以想得到您的一些指导。冒昧的地方,还请您原谅。
欢迎交流~,联系我邮箱或者在博客上直接提问都可以啦。我的邮箱:guoliang1114@gmail.com
版主你好,关于BPM 的东西想向您请教一下
目前我在开发过程中想做这样一个事情,1、我使用Jdevelopr创建流程模版后发布到BPM;2、然后我在自己的java应用里通过API为各个变量(节点)赋值(执行人、角色等);3、流程启动之后,我通过API动态获取待办任务等,然后与完成我的java应用集成。
现在问题是第2步的时候的API不知道怎么用,所以也就不知道赋值的规范是什么(角色、人员、组织等怎么赋到变量上);第3步的API应该能够做到。
因为我看到您的demo中有提到对象的XML Schema,并且对对象也有编辑,所以我不确定这个对象和之前的变量是不是一个东西,并且对象的XML Schema是如何获取的,还是说是自己定义的?
希望版主能指点迷津,不胜感激!!
您好,我想问您,如何获取到所有流程;比如我发起一个流程实例,您的博客里介绍,需要传入一个ID–“blogdemo/CustomHumanTask!1.0*soa_87c431bf-7757-46de-8c52-55f4f2aabc11/CustomHumanTaskProcess”
这些信息是否可以通过API获取而不用到EM里查看得到?假如我想给用户展现一个流程列表,显示都有哪些流程(不是流程实例),那应该怎么通过API来实现。
查询流程列表属于SOA的范畴,需要使用SOA的API才能实现,如果您需要的话,我可以写次贴出来。
您好,我使用Jdeveloper创建了一个人工启动的流程A(Manual Process方式的流程),我先让我所有的用户都具有发起该流程,生成待办任务的权限,这在流程中该怎么进行配置,希望您给予指导,谢谢。
貌似不对 ,当流程启动的时候,就过了第一个节点,就是说 启动流程之后 任务就到了ComfirmRole这个节点了,然后我还有一个问题要问下, 把xml推送出去后,再次使用getTaskDetailsByID 怎么获取里面的信息了,我没看到task里面有 hello这个对象啊。
如何 在 一个webservice里面调用 以上的BPM api 代码呢?