2011年1月28日 星期五

[Oracle BPM/SOA 基礎] 第一個BPM流程

現在,我們來做一個簡單的BPM流程吧!

背景設定為一個很簡單的採購流程,使用者上網提出採購申請,之後經過主管同意後,流程會將此採購資料寫入檔案供採購系統抓取,夠簡單吧? 這個簡單流程可以提供各位在一個BPM平台上面的開發是如何進行。

開始之前,請先確定你的BPM開發環境已經完成安裝與設定,你可以參考小弟先前文章完成此步驟。

啟動你的JDeveloper,不管你喜歡與否,這個IDE是Oracle BPM產品流程設計現在唯一的工具,試著熟悉他吧!

新增應用程式專案

選擇 "New Application",會有一彈出的對話框讓你輸入包括Application Name、Directory、package prefix等資訊,特別注意的是JDeveloper是一個general purpose的IDE,所有Oracle產品應用都是透過這IDE開發,所以在BPM專案的開發上面,Application Template記得要選"BPM Applicaiton"。





下一步後建立一個Project,你只需要給定Project名即可


下一步請選擇 "Composite with BPMN Process"


接下來會有BPMN Process產生的選擇,你可以給定自己喜歡的Process名稱與描述,但下面的Type則會根據流程特性的不同產生不同的流程基本元件,這邊Oracle提供了四種類別:Asynchronous Service、Synchronous Service、Manual Process與Reusable Process。

基本上Asynchronous Service與Synchronous Service兩種的Process本身都會提供Web Service的介面給外部系統或程式呼叫啟動,唯一的差別只有流程本身是同步或非同步;至於Reusable Process,你可以把他想成是一個工具流程,或是一個常被不同流程中引用的子流程,讓你之後可以再利用。

Manual Process則是如同我們現在所預設的流程,由人工啟動,並在流程完成後自己結束。我們的範例就採用這種流程,選好之後直接按下"Finish"即可。


基本流程設計

產生完成的BPM流程就如下圖所示,Oracle BPM流程設計是採用BPMN標準notation,BPMN會將整個流程劃分為一到多個"水道(swim lane)",每一條水道代表的是不同角色的工作範圍,流程內包含了許多的Activity與Transition,原則上,每一個Activity你可以把它視為一個【動作】,這個動作有可能是人工處理的,也有可能是呼叫系統自動作業的,Transition就是協助串連起多個動作,以完成一個完整流程。當然BPMN本身還另外支援了Event與Gateway的概念,這些部份我們在第一個流程中不會用到,留待以後再提。

下圖所示,流程的開始點是"Start",結束點是"End",我們現在只有一個水道 -- "Role"、一個Activity -- "UserTask",這樣代表"UserTask"這個工作是由叫做"Role"的角色負責執行。


根據我們採購流程的劇本,基本上我們需要兩種角色出現,一種是一般使用者,一種是管理階層,使用者負責提出申請,管理人員負責審核。也因此我們會需要兩個水道,分別指定為User與Manager兩種角色。

同時,我們會需要兩個User Activity -- "Request Procurement" 以及 "Approve Procurement",這兩個Activity分別會被放置到User與Manager的水道之中;我們還需要一個Service Activity -- "Save Procurement",這個Activity是一個系統的自動作業,負責的是我們劇本之中最後一個步驟,將採購資料寫入檔案之中。

來看看怎麼樣做出這樣的流程吧!

首先你可以double-click "Role"的位置,會有一對話視窗出現讓你指定角色,請按下"New"按鈕並給定我們的需要的第一個角色 -- "User"。


接下來,請在"User"水道下方空白處按右鍵選擇"Add Role",並重複上面的步驟以產生說們所需要的第二個角色 -- "Manager"。

Double-click "UserTask",將他的名稱改為劇本之中的第一個Activity -- "Request Procurement"。



試試看,你可以在水道之間任意托放現有的Activity,我們可以先把"End"托放到"Manager"水道之上。接下來,找一下在你右手方的Component Palette,將User元件托放至 "Request Procurement" 與 "End" 之間的Transition上(記得要放在線中間,看到線變成藍色之後放下),你又會看到對話視窗,把名稱改為劇本之中的第二個Activity -- "Approve Procurement"吧。

調整一下流程的layout,你應該會看到如下面所示的畫面:


同樣的做法,請再把Component Palette中的Service Activity托放到 "Approve Procurement" 和 "End" 之間的Transition上,給他個名稱"Save Procurement",這就是最基本我們流程的長相了!


各位不難發現,到目前為止的流程充其量只是個"皮",基本定義了流程中間有那些關卡與角色,欠缺了詳細每個Activity內容的定義,也沒有設計流程中所夾帶的變數資料。接下來的步驟我們就先來定義流程的詳細內容吧!

指定流程變數

在BPM平台中,設計並部署好的流程(Process)可以同時會有許多的流程實例(Process Instance)在平台上執行,每一個instance都會夾帶著各自的資料,以我們的例子來說,採購申請流程的每一個instance應該夾帶著採購申請的內容,這個內容在設計時需要被定義為一個流程的變數,每一個流程實例都會有一個變數資料。以Java的概念來說,這就像是class中的property,每一個class instance都會保有一份自己的instance variable一樣。

而Oracle BPM平台是基於SOA架構所設計的,SOA又是基於XML相關的一些標準所堆疊,因此,Oracle BPM變數設計的第一步驟,就是要定義變數的"長相",而在XML世界裡,變數的長相就是定義在XML Schema之中了。接下來我們就來使用JDeveloper定義出我們所要的procurement變數。

首先,在你的Project之中,會有一個資料夾叫做 "SOA Content",裡面有一個資料夾叫 "xsd" 的,這是我們Project中預設XML Schema存放的位置,在此資料夾上右鍵選擇 "New" ,在New Gallery的搜尋列中打上 "XML Schema",你可以看到一個XML Schema的item供你選擇。


接下來給這個schema檔案名稱、Target Name Space以及Prefix,我們分別使用procurement.xsd、http://blogdemo/procurement與procurement。


你可以看到GUI介面的XML Schema編輯器,當然如果你很熟悉XML Schema的撰寫,你也可以切換到source view自己編輯,或者是使用現成的XML Schema檔做為變數的長相。


在XML Schema編輯器中,你可以點選任何一個element,為每個element加上sequence與子element,並且可以定義每個element的型別(字串、數字或日期...等)。我們需要的是一個procurement element,裡面有四個子element分別為:user_id (字串 xsd:string)、procurement_date (日期 xsd:date)、item (字串 xsd:string)與item_count (整數 xsd:integer)。
  • 做法是點選一個現在的"exampleElement",在畫面右下角的Property Inspector中將name改為procurement。
  • 右鍵此element,選擇"Insert inside element - procurement" --> "sequence",產生一個sequence。
  • 再右鍵剛才所產生的sequence,選擇 "Insert inside sequence" --> "element",產生新的element。
  • 點選此element並將其name改為user_id,type改為xsd:string。
  • 重複上面兩個步驟,產生procurement_date、item與item_count三個element
完成之後你的XML Schema應該看起來像是這樣:


接下來,我們來把這個XML Schema當作BPM變數的"型別"吧! 首先先把開發介面左上角的切換到BPM Project Navigator頁簽之上(看得出差別嗎? 左上角長得不太一樣了!)。


接下來右鍵"Business Catalog" --> "New" --> "Business Object",給定 "Procurement" 為名稱、"Data"為Destination Module。


選取 "Based on External Schema" Checkbox,並按下旁邊的放大鏡,你可以從Type explorer中一路選取到procurement.xsd裡面的procurement element。


一路OK到底,你將可以在Business Catalog下面看到一個新的Module叫"Data",裡面有一個Business Object是"Procurement"。現在你就可以開始在流程之中加入Procurement資料物件了!

切回流程(ProcurementProcess)的頁面,你可以看到左下角的Structure Panel裡面有個叫做 "Process Data Objects"的地方,右鍵他,選"New",在彈出的對話框中給定如下圖所示的資料。



現在,流程中所要攜帶的資料已經有變數可以儲存了,我們只要在流程細部設計中指定這變數何時被使用還有如何使用了。

定義人工作業

在定義人工作業內容之前,有一個問題需要先被解決,到底剛才所定義的User與Manager兩個角色各自有那些人呢? 要完成這一步驟,首先你至紹需要有兩個使用者存在於你的BPM server之中,你可以參考我這篇文章預先加入所需的使用者。

在你的BPM Navigator中,double-click Organization:


選擇 "User" 角色,並在下面Role Members中選擇Type為User,並按下綠色的加號按鍵,產生一行User,你可以在Name的地方直接改為你所設定的使用者名稱,這邊我指定為"tim"。


重複上述步驟,選擇"Manager" 角色,指定使用者為"kenneth"。完成之後,儲存內容。

ps. 你也可以不要自行輸入,你可以按下放大鏡圖示,接下來會有對話框讓你連接進入BPM Server之中,查詢並選擇你所指定的使用者。

接下來我們來定義詳細的人工作業內容,先double-click "Request Procurement"這個Activity,在對話框中切換到"Implementation"頁簽。給定Title為"申請採購"。


按下中間的綠色加號圖案,會跳產生人工作業的對話框,給定下來資訊:
  • Name:Request
  • Pattern:選擇Initiator
  • Title:申請採購


這一個對話框中包含許多重要的資訊,我們需特別說明一下每個部分:
  • Pattern
    Pattern會指定此人工作業的執行模式,通常我們都會使用Simple,Simple會將工作指派給該水道角色的人員。但是若我們希望流程的啟動是由人工啟動,則在此流程的第一個User Task我們需要選擇Initiator Pattern,這樣的話,負責此人工作業腳色的人員將可以手動透過網頁啟動這個流程。針對採購流程,我們希望一般使用者可以自行提出申請,因此在 "Request Procurement" 中選定Initiator Pattern。在接下來系列中我會額外再針對其他不同的Pattern進行說明。
  • Outcome
    代表此人工作業完成後使用者可以選擇的結果,你可以透過旁邊的放大鏡來選擇(可複選),常用的有幾種Outcome,像是送出(SUBMIT)、核准(ACCEPT)、拒絕(REJECT)...等等,你可以針對不同的情境去指定每一個人工作業完成之時,使用者可以選擇的結果選項。以採購流程來說,"Request Procurement"本身是提出採購申請,當使用者填完成購申請之後只應該有一種選項 -- SUBMIT;但是在管理階層所使用的 "Approve Procurement ",其Outcome就有可能是ACCEPT或是REJECT了! 記得,這些結果系統有給幾個預設值供你使用,但是你也可以根據需求自行增加不同的Outcome值在流程中使用。
  • Parameters
    流程中的每一個人工作業關卡會根據其工作內容,使用到流程中的某些變數。此處便是提供你指定哪些流程變數會被傳給此人工作業使用,並且指定傳入的變數內容是否在此作業中可以被修改。"Request Procurement" 此作業需提供使用者輸入採購的項目與資訊,因此需要將procurement變數傳入,並且允許被編輯。做法是按下綠色的加號圖形,將右手邊"Browse Data Objects"中的procurement托放至Parameter之中,並且將Editable選項勾選。


一路OK到關閉所有對話框,你會發現,現在 "Request Procurement" Activity上面已經不再出現黃色驚嘆號警告了,代表他的詳細定義已經完成。

重複上述步驟完成 "Approve Procurement" Activity的詳細0定義,特別注意,"Approve Procurement" 與 "Request Procurement" 有一些的不同:
  1. "Approve Procurement" 並不是起始流程實例的步驟,所以他應該選擇Simple Pattern而非Initiator Pattern。
  2. "Approve Procurement" 的Outcome可能有兩種,分別是APPROVE與REJECT,代表管理人員可以同意或拒絕此採購。
  3. "Approve Procurement" 同樣使用procurement變數,但是他們不應該可以編輯變數內容,記得不需要勾選Editable。


恭喜你! 你已經將流程的人工作業部分完成了! 好像還差了甚麼東西? 對了,最重要的使用者介面還沒設計哩!

定義使用者介面

雖然Oracle BPM提供了一套自動產生UI的功能,但是先天上的設計似乎有些... "功能龐大"。簡單來說,他會幫你流程中的每一個HumanTask單獨產生一個UI Project,此UI Project是採用了Oracle ADF的架構,最後整個流程在部署的時候,JDeveloper再將你的每一個UI Project包裝成WAR,然後統整所有的WAR打包成一個EAR。想想看,要是你有個流程內部有十幾個人工作業步驟,每個都會包了所有ADF的library變成一個WAR,最後再打包成一大包的EAR,這樣的做法會對你的server與部署時間造成 "小小的負擔"。

因此,我這邊直接跳過預設的做法,提供各位平時我會使用的UI產生方式。

首先,產生一個新的專案,"New Project" --> "Generic Project",給定專案名稱叫 "FirstBPMUI"。

右鍵此FirstBPMUI專案,選擇 "New",在New Gallery的搜尋列之中打上human,你可以在Items內部看到一個選項叫做 "ADF Task Flow Based on Human Task (JSF)",按下OK。


接下來會有對話框彈出,請你選擇你現在需要製作的UI是針對哪一個Task,選取在FirstBPM裡面的Request.task。


接受所有Create Task Flow的預設值


你會看到像是這樣的畫面


現在你所看到的 "taskDetails1_jspx" 就是等一下會產生的UI JSF,你可以點選此icon並在右下角的view中給他一個你喜歡的Activity ID與Page,這裡我把他們分別設定為"request"以及"/request.jspx" (Page就是待會產生的JSF檔案名,因此你最好給他一個有意義且不要和其他網頁重複的名稱)。


現在可以做網頁了,double-click圖上面的request,你會看到一個Create JSF的對話窗,接受所有的預設值,直接OK即可,你會看到自動產生了一個空白的JSF檔案。


接下來就要展現ADF Data Control的功能了,在JDevelop介面左邊中間,你會看到一個Data Control的地方,點一下它把它展開,你會看到一個剛才ADF幫你自動產生的Data Control,點選 "FirstBPMUI_Request" --> "getTaskDetails (String, String, String) --> Return,你會看到Task的icon出現。


這時候將"Task"從左手邊托拉至你的空白JSF網頁之中,此時JDeveloper會自動彈跳出一個選單,請選擇 "Human Task" --> "Complete Human Task with Payload",接下來會連續出現兩個對話框,暫時不要理他,都接受預設值按下OK。

噹噹,你的UI JSF網頁已經自動被產生出來了!


趕快Save All一下吧!

接下來你會需要再做出"Approve Procurement"的使用者介面,請重複上面的步驟 (記得,不用重新產生一個Project,你可以從"右鍵FirstBPMUI" 這個步驟開始做),要特別注意的是,你之後會產生一個新的TaskFlow以及Data Control,在選取的時候不要選到之前做過的了,並且在網頁命名上不要重複即可。

用這樣的做法可以讓你即使有多個人工作業存在於流程中,你始終還是只有一個UI Project,這會保持你的部署EAR檔案不要太過龐大。
ps. 這個版本的JDeveloper有個小問題需要手動修正,各位請在FirstBPMUI Project之中,找到位於"Web Content" --> "WEB-INF" --> "adfc-config.xml",double-click此檔案後,你會在畫面中央的Unbounded Task Flow中看到有一個紅色叉叉在Empty1_jspx上面,請double-click此元件以自動產生對應的JSF檔案。

定義非人工系統自動作業

記得嗎? 我們在採購流程的最後一步驟是要將採購資料寫入檔案,此步驟應該是一自動作業,由BPM平台將採購procurement變數資料寫入指定的目錄與檔案。此部分就是BPM架構在SOA整合平台的好處,我們將使用SOA平台所提供的File Adapter功能,讓開發人員不需要寫code即可完成這件事情。

首先,double-click "FirstBPM" --> "SOA Content" --> "composite.xml" 檔案,你可以看到一SCA (Service Component Architecture) 的composite圖,這張圖代表了整包專案之中,各種不同元件之間的關聯,現在可以看到的是我們專案之中有一個 "ProcurementProcess" BPMN流程,這流程之中有到兩個人工作業 -- "Request" 與 "Approve"。


接下來我們還需要產生一個External Reference,讓我們可以將資料寫到檔案之中,請從右手邊的Component Palette中托放一個File Adapter至External References區域之中。JDeveloper接著會自動啟動File Adapter Wizard,第一步驟是指定此服務名稱,我們姑且叫他 "ProcureService"。


連按兩個Next,來到Operation步驟,此步驟是指定此File Adapter是做讀檔、寫檔還是等待檔案的動作,根據我們的需求,選擇Write File,並按下Next。


指定你所希望檔案被寫出的目錄,以及檔案名稱,在這我是指定檔案輸出到"f:\tmp"目錄之下,並指定檔案名稱為"procure_%SEQ%.xml" (注意:這裡的%SEQ%代表的系統會自動產生序號,你也可以指定檔名根據時間來產生,如:procure_%yyMMddHHmmss%.xml),按下Next。


此步驟可指定檔案寫出的格式,我們希望直接寫出XML格式的檔案,因此請直接按下旁邊的放大鏡按鍵,並在Type explorer中選出 "procurement.xsd" --> "procurement"。


Next之後就可以Finish了! 完成之後,你在Composite中可以看到這樣的圖形,多了一個ProcureService的File Adapter在External References之中。


Double-click Composite中的ProcurementProcess,進入ProcurementProcess的BPMN流程圖,double-click "Save Procurement" 這個Service Activity,選擇Implementation頁簽,在Service Task的Implementation下拉選單中,選擇Service Call。


按下放大鏡,並選擇剛才所產生的ProcureService,並按下OK。


選取Data Association中Use Associations旁邊的鉛筆按鍵,這步驟會定義流程變數如何被傳遞至ProcureService中,如下圖,你只需要將右手邊ProcurementProcess裡面的procurement變數托放到左手邊的Input欄位即可。接著就是一路OK到看到BPMN流程,這時,你會發現"Save Procurement" Activity上面的黃色驚嘆號也不見了。


恭喜你! 你的流程已經開發完成了!

部署流程

右鍵FirstBPM目錄 --> Deploy --> FirstBPM,選擇Deploy to Application Server。


此處,你可以於Revision ID處指定部署的流程版本資訊,並記得,如果你不是第一次部署此版本的流程(此版本的流程已經被部署過,現在需要覆蓋過去)的情形,請勾選 "Overwrite any existing composites with the same revision ID",按下Next。


選好所有之前所產生的FirstBPMUI Project,指定Application Name為 "FirstBPMUI ",並勾選 "Overwrite existing application" (同樣的,這是為了覆蓋過之前產生過的UI Application),按下Next。



接下來會選擇你所欲部署的BPM server位置,按下綠色加號按鍵,給定連接名稱、帳號密碼、WebLogic hostname、port與domain名稱之後你就完成了BPM server的連線 (懶得貼畫面了,相信大家能夠搞定這部分,哈哈),這步驟只需要做一次,下一次的部署或其他專案的開發都可以再利用這個BPM server連線。選擇你剛才所建立的連線,並按下Next。


選擇default partition,按下Finish,此時JDeveloper會開始部署流程以及他相關的UI Project,請耐心等候。


流程測試

這一個範例我們是使用Oracle BPM Workspace做為使用者介面,先連上你的BPM Workspace來看看吧! BPM Workspace的URL是: http://<your_hostname>:<your_port>/bpm/workspace

首先,使用你的User角色的使用者登入,你可以看到像是這樣的畫面


有注意到嗎? 在左上角應用程式的部分,你可以看到你剛才所部署的ProcurementProcess v.10版,只要是屬於這個User角色的人登入都會可以看到這個Link,按下去之後會跳出剛才我們透過JDeveloper所自動產生的UI介面供使用者輸入資料:


輸入完畢之後按下SUBMIT就完成了這一關卡的動作了,請特別注意,上面所列出來的SUBMIT按鈕就是之前我們在定義此人工作業所指定的Outcome。

趁這個機會我們也看一下管理介面吧,Oracle BPM提供管理人頭透過管理介面看到每一個Process Instance的執行狀況與歷程。管理介面登入的URL是:http://<your_hostname>:<your_port>/em

開啟一個新的browser連接此URL,並以管理人員登入 (e.g. weblogic),依序點開在左手邊的 "Farm_bpm_domain" --> "SOA" --> "soa-infra" --> "default" --> "FirstBPM",你應該可以看到系列的畫面,正中央就會有顯示你剛才執行的Process Instance,標示為執行中。


選取該執行中Process Instance的執行處理ID,你可以看到Process Instance的內容component,要細看流程的話,請選取 "ProcurementProcess"。


管理人員可以依照表單式的與圖形式的歷程紀錄看到流程執行的情形,注意,你會發現流程現在停在 "Approve Procurement" 的步驟。



接下來,你可以用Manager角色再登入BPM Workspace,完成流程!



再次恭喜你! 你已經完成流程的設計了!


1 則留言:

匿名 提到...

請問在UI Project新增human再指定哪個task這部份,曾經看過只要新增一個human後,其他task就可以在hwtaskflow.xml裡定義共用就好了,但詳細不知如何實作,不知這部份你有經驗嗎?