天天看点

Oracle BPM/SOA API 操作流程

对于国内的客户,Oracle提供的huaman task ui不能满足客户的需求。大部分的客户都需要重新来开发。个人认为这样的要求不算过分,企业内部的BPM规划本来就应该走向公共单一平台的设计模式,也就是,理想状态可是使用多种的语言开发,比如.NET,JAVA,C++,有需要内部流程管理,或者跨系统流程应用整合,都可以将流程部署至此平台,前段应用程序可以维持原先界面的操作,只是适当的通过API或者特定的界面与BPM进行审批等即可。

Oracle BPM/SOA API 操作流程

 因此,在BPM的架构中,个人觉得除了流程设计需要灵活性之外,前端也是另一个非常重要的主题。对于前段应用与后端系统整合的方式,又各有不同的方式,前段着重与用户交互,后端着重使用SOA架构下,来整合现有的系统。 假设我们需要这样一个简单的审核流程,BPMN如下:

Oracle BPM/SOA API 操作流程

如图所示,我们设计一个流程,其中包含了两个泳道,分别是为发起InitTask,审核所使用的ConfirmTask;个人交给两个角色,分别为InitRole,ComfirmRole来负责。在流程中只有一个对象,其XML Schema如下:

<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 你可以使用任何IDE来开发。

2. 初始化BPM  server 连接:

//初始化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. 认证使用者 准备好了远端连接,在使用时需要对当前用户进行认证。

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来启动一个新的流程实例:

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查询当前分配的人。

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)。

//创建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。 整个流程就这样结束了。

转自: http://www.fmw007.com/archives/305