天天看點

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