在 WebSphere Process Server 中為新的查詢要求設定自定義屬性
簡介: 在您開發一個業務流程客戶端程式時,您經常需要在一個流程例項內,通過某些業務資料標準來查詢流程例項、活動和任務。本文向您展示了在 WebSphere Process Server 中,如何通過一個動態方法為流程例項設定自定義屬性來滿足新查詢要求。
在您開發一個業務流程客戶端程式時,您經常需要在一個流程例項內,通過某些業務資料標準來查詢流程例項、活動和任務。例如,您可能想要在流程例項中尋找與某個 ID 的客戶相關的所有任務。
當您在 WebSphere Integration Developer(以下簡稱為 Integration Developer)設計流程時,可以通過為人工任務設定自定義屬性來實現這個需求。然而,當流程投入使用後,如果新查詢要求需要新的自定義屬性,那麼這招就不靈了。您當然可以使用 WebSphere Process Server(以下簡稱為 Process Server)提供的流程版本控制方法,在新版業務流程中增加新的自定義屬性。然而,使用新的自定義屬性不能對已有的舊版業務流程進行查詢。
本文對熟悉業務流程開發的業務流程設計師和程式設計師有一定的幫助。本文假設您熟悉 Process Server 和用 Integration Developer 開發業務流程應用程式。如果您沒有經驗,我們建議您仔細閱讀 Business Process Management 樣例 & 教程 — 版本 6.1。
在本文中,我們假設 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. 流程專案結構
訂單審計流程有兩個必需的業務物件(BO):OrderRequest 和 PersonInfo(見圖 3)。OrderRequest 儲存訂單資訊,包括客戶、審計人員、狀態和商品編號。PersonInfo 包含個人資訊,比如 ID、姓名和地址。
圖 3. 業務物件
圖 4 展示了 Integration Developer BPEL 中設計的流程:
- Receive 活動是流程的起始點。流程從客戶端收到一個訊息(OrderRequest),接著開始流程。訊息中的資料儲存在一個流程變數(請求)中。
- Assign 活動執行該流程所需的資料對映。
- Order Info 片段列印訂單資訊。
- ApproveOrderRequest 是審計人員批准或拒絕請求的一個人工任務。
- Approve 選項根據審計人員的決議決定下一步。系統將使用 Approve Response 和 Reject Response 片段列印相應的回覆。
圖 4. 流程
在嵌入 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 將訂單號設定為自定義屬性,如清單 3 所示。
清單 3. 使用 BPC EJB API 設定自定義屬性
String rderNo = 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")); } |
您可以測試 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 來為新流程例項和執行中的例項設定自定義屬性,從而滿足新的查詢要求。使用這種方法,您不需要更新流程來新增一個新的自定義屬性。
原文連結:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1006_cheng/1006_cheng.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14789789/viewspace-671385/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 自定義滑鼠設定-中鍵設定為後退
- 為什麼阿里巴巴強制要求使用包裝型別定義屬性?阿里型別
- CSS 自定義屬性指北CSS
- data-* 自定義屬性
- 自定義RadiusBackgroundSpan在textview設定tagTextView
- 帶你深入理解Android中的自定義屬性!!!Android
- 給Product新增自定義屬性
- 初識css自定義屬性CSS
- ReactNative自定義元件及屬性React元件
- CSS 自定義屬性(變數)CSS變數
- Echarts中Option屬性設定Echarts
- SQL Server 中的 ACID 屬性SQLServer
- Android 自定義View:深入理解自定義屬性(七)AndroidView
- 4. 自定義控制元件(4) --- 自定義屬性控制元件
- 【譯】CSS 自定義屬性的策略指南CSS
- python中__setattr__的屬性設定Python
- [譯] 為函式自定義屬性的八種實現方法函式
- ts類中屬性定義的另一種方式
- 自定義元件-資料、方法、屬性元件
- spring 自定義屬性解析器Spring
- 使用 CSS 自定義屬性(變數)CSS變數
- ubuntu下OpenLDAP新增自定義屬性UbuntuLDA
- React Native 自定義元件及屬性React Native元件
- MySQL8 根據某屬性查詢欄位排名由自定義變數到rank()的變動MySql變數
- [譯]Kotlin中是應該定義函式還是定義屬性?Kotlin函式
- 二分查詢的定義
- Qt編寫自定義控制元件屬性設計器QT控制元件
- 【Web Components】關於自定義元件屬性在 Vue 和 React 中不同表現的探討Web元件VueReact
- Spring Cloud自定義引導屬性源SpringCloud
- Spring Boot讀取自定義外部屬性Spring Boot
- Android 自定義View:屬性動畫(六)AndroidView動畫
- Linux 中 FQDN 查詢及設定Linux
- 表屬性設定
- DbForge Studio for SQL Server入門教程:在查詢生成器中建立查詢SQLServer
- android -- EditText 設定 imeOptions 屬性為何失效?Android
- android — EditText 設定 imeOptions 屬性為何失效?Android
- Xcode設定自己的個性屬性XCode
- 關於CSS中設定overflow屬性的值為hidden的相關理解CSS
- Spring JPA 定義查詢方法Spring