王鈞召,江學(xué)武,何云峰,于俊清*
(1.廣東粵電信息科技有限公司,廣東 廣州510630;2.華中科技大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,湖北 武漢430074)
工作流技術(shù)越來(lái)越廣泛地應(yīng)用在企業(yè)信息系統(tǒng)中,大部分企業(yè)信息系統(tǒng)都選擇采用成熟的商業(yè)或開(kāi)源的工作流產(chǎn)品,也有不少企業(yè)在原有信息系統(tǒng)基礎(chǔ)上進(jìn)行二次開(kāi)發(fā),實(shí)現(xiàn)符合自身需求的工作流管理系統(tǒng)(WfMS,Workflow Management System)[1-3]。商業(yè)工作流產(chǎn)品,國(guó)外主要有IBM 公司的Lotus Domino Workflow 和WebSphere MQ Workflow,以及Oracle 公司的Oracle Workflow 等工作流產(chǎn)品[4]。國(guó)內(nèi)目前比較流行的WfMS,主要有西安協(xié)同的SynchroFlow,上海東蘭的DLFlo 和杭州信雅達(dá)的SunFlow 等[5]。國(guó)外的工作流產(chǎn)品并不適合用于管理具有中國(guó)特點(diǎn)的業(yè)務(wù)流程,因此大部分企業(yè)都采用國(guó)內(nèi)廠商生產(chǎn)的工作流產(chǎn)品,維護(hù)和升級(jí)比較方便。目前使用較多的開(kāi)源工作流產(chǎn)品,主要有jBPM(Java Business Process Management,jBPM)和Activiti。jBPM[6-7]提供了工作流引擎和應(yīng)用擴(kuò)展接口,可以根據(jù)不同需求進(jìn)行功能擴(kuò)展,能夠方便地集成到已有的系統(tǒng)中。Activiti[8-9]的發(fā)起人是原jBPM 創(chuàng) 始 人Tom Baeyens,Activiti 是 在jBPM3 和jBPM4 的基礎(chǔ)上發(fā)展而來(lái)的,其內(nèi)部接口與核心API與原jBPM 有很多的相似之處。Activiti 與jBPM 相比較,增加了流程可視化與管理能力,并加強(qiáng)了與外部系統(tǒng)的集成能力。
功能完備的工作流產(chǎn)品除了支持基本的業(yè)務(wù)操作之外,還支持“撤銷(xiāo)”,“委派”,“會(huì)簽”以及“自由流”等復(fù)雜業(yè)務(wù)場(chǎng)景,實(shí)現(xiàn)比較復(fù)雜,如果要集成到原有的信息系統(tǒng)中,需要修改相關(guān)代碼和配置相關(guān)文件,才能方便對(duì)接。但是,發(fā)電企業(yè)燃料管理中的很多業(yè)務(wù)流程只需要基本的“通過(guò)”和“退回”功能,如果采用成熟的商業(yè)或開(kāi)源工作流產(chǎn)品,將造成成本較高、集成復(fù)雜和系統(tǒng)兼容性差等問(wèn)題。
為了能夠方便地集成到已有的信息系統(tǒng)解決簡(jiǎn)單的業(yè)務(wù)流程定制,設(shè)計(jì)了輕量級(jí)的工作流管理系統(tǒng)[10],并將系統(tǒng)應(yīng)用到火力發(fā)電企業(yè)燃料信息系統(tǒng)的審批流程中,實(shí)際應(yīng)用結(jié)果表明,該系統(tǒng)可以滿足信息系統(tǒng)中對(duì)審批流程自動(dòng)化流轉(zhuǎn)的要求,能夠保證審批流程的正確運(yùn)行。
根據(jù)WfMC 給出的工作流管理系統(tǒng)參考模型[11],輕量級(jí)工作流管理系統(tǒng)的總體架構(gòu)如圖1所示。

圖1 工作流管理系統(tǒng)總體架構(gòu)圖Fig.1 System architecture of WfMC
工作流管理系統(tǒng)主要由工作流定義工具和工作流引擎組成。其中,工作流定義工具以圖形化的方式為用戶提供抽象實(shí)際業(yè)務(wù)流程及描述流程的手段,同時(shí)生成工作流模型,這里的工作流模型是指可被計(jì)算機(jī)處理的形式化定義,是由組成工作流的各個(gè)活動(dòng)以及活動(dòng)之間的關(guān)聯(lián)關(guān)系等信息組成的一個(gè)完整的數(shù)據(jù)結(jié)構(gòu),通常被保存在數(shù)據(jù)庫(kù)中。工作流引擎將數(shù)據(jù)庫(kù)中保存的工作流模型作為依據(jù),驅(qū)動(dòng)工作流實(shí)例的自動(dòng)流轉(zhuǎn)[12]。
根據(jù)WfMC 規(guī)范,工作流定義工具由3 部分組成:模型設(shè)計(jì)器、工作流模型和模型控制器。
模型設(shè)計(jì)器用于定義工作流模型,通過(guò)拖拽相關(guān)組件進(jìn)行流程圖的繪制,鼠標(biāo)點(diǎn)擊和鍵盤(pán)輸入操作可以設(shè)置各個(gè)活動(dòng)的可操作角色,用戶做出的各種請(qǐng)求動(dòng)作將由模型控制器響應(yīng)。用戶定義工作流模型之前,流程設(shè)計(jì)器先查詢(xún)?cè)摴ぷ髁髂P褪欠褚汛嬖?,如存在則在原有模型的基礎(chǔ)上進(jìn)行更改。
工作流模型既可以保存為XML文件,也可以保存在數(shù)據(jù)庫(kù)中,作為工作流實(shí)例自動(dòng)流轉(zhuǎn)的依據(jù)。輕量級(jí)工作流系統(tǒng)通過(guò)工作流表、節(jié)點(diǎn)表、節(jié)點(diǎn)間連線表、工作流實(shí)例執(zhí)行情況表4個(gè)數(shù)據(jù)表保存每一個(gè)工作流模型各個(gè)節(jié)點(diǎn)的信息和節(jié)點(diǎn)間連線信息,以及工作流實(shí)例的運(yùn)行情況。
模型控制器負(fù)責(zé)響應(yīng)模型設(shè)計(jì)器的請(qǐng)求動(dòng)作,主要功能包括:圖形化界面中各個(gè)組件的增刪改查,工作流模型與XML 文件的相互轉(zhuǎn)換,數(shù)據(jù)庫(kù)的存取,以及一些其他操作如清空、撤銷(xiāo)等。模型控制器中還提供一個(gè)重要功能,就是工作流模型的合理性驗(yàn)證。對(duì)工作流模型的合理性驗(yàn)證分為語(yǔ)法驗(yàn)證、語(yǔ)義驗(yàn)證和結(jié)構(gòu)驗(yàn)證[13]。由于語(yǔ)義驗(yàn)證由工作流模型設(shè)計(jì)人員負(fù)責(zé)驗(yàn)證,所以驗(yàn)證功能只提供語(yǔ)法驗(yàn)證和結(jié)構(gòu)驗(yàn)證。
工作流引擎需要對(duì)定義的工作流模型進(jìn)行解析,讓計(jì)算機(jī)能理解該模型的具體含義,驅(qū)動(dòng)工作流實(shí)例按照該模型進(jìn)行正確流轉(zhuǎn),它是工作流管理系統(tǒng)的核心組成部分[14]。對(duì)于每個(gè)工作流實(shí)例來(lái)說(shuō),各項(xiàng)任務(wù)能夠按照工作流模型進(jìn)行自動(dòng)流轉(zhuǎn)并且互不干擾,都是因?yàn)楣ぷ髁饕嬖诤笈_(tái)進(jìn)行控制。工作流引擎的工作流程如下:
1)用戶啟動(dòng)某個(gè)工作流實(shí)例,該實(shí)例開(kāi)始執(zhí)行;
2)工作流引擎從數(shù)據(jù)庫(kù)中讀取對(duì)應(yīng)的工作流模型;
3)當(dāng)用戶對(duì)某個(gè)節(jié)點(diǎn)操作完成,工作流引擎決定該實(shí)例的流轉(zhuǎn)方向,即決定下一個(gè)操作節(jié)點(diǎn)以及該節(jié)點(diǎn)可操作的角色,一直持續(xù)到該實(shí)例流轉(zhuǎn)結(jié)束。
工作流引擎以工作流模型作為依據(jù),根據(jù)控制參與者的操作權(quán)限和工作流實(shí)例的執(zhí)行情況控制實(shí)例的正確流轉(zhuǎn)。
定義的工作流模型是否合理直接決定了工作流實(shí)例能否正常執(zhí)行,因此工作流模型的合理性驗(yàn)證至關(guān)重要。工作流模型的合理性驗(yàn)證分為語(yǔ)法驗(yàn)證、語(yǔ)義驗(yàn)證和結(jié)構(gòu)驗(yàn)證[15]。語(yǔ)法驗(yàn)證提供初級(jí)的錯(cuò)誤驗(yàn)證,主要驗(yàn)證是否有重名的節(jié)點(diǎn),是否有孤立的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)是否都存在輸入狀態(tài)和輸出狀態(tài)等。語(yǔ)義驗(yàn)證用于驗(yàn)證工作流的定義是否與實(shí)際業(yè)務(wù)流程的目標(biāo)相同,由工作流模型設(shè)計(jì)人員負(fù)責(zé)。結(jié)構(gòu)驗(yàn)證檢查是否存在非法并發(fā)、死循環(huán)等錯(cuò)誤,這里重點(diǎn)說(shuō)明結(jié)構(gòu)驗(yàn)證。
工作流模型存在唯一的開(kāi)始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)。工作流模型可以看作有向圖,該有向圖必須是連通圖,不能存在多個(gè)連通子圖。因此從開(kāi)始節(jié)點(diǎn)進(jìn)行遍歷必須能遍歷到所有的節(jié)點(diǎn),否則存在節(jié)點(diǎn)不可達(dá)的錯(cuò)誤。工作流模型中可能存在非法并發(fā)單元,主要表現(xiàn)為非法入口,非法出口和并發(fā)跳轉(zhuǎn)等。工作流模型組成元素包含:開(kāi)始節(jié)點(diǎn)、結(jié)束節(jié)點(diǎn)、流程節(jié)點(diǎn)以及節(jié)點(diǎn)間連線。各個(gè)元素的圖形化表示如圖2所示。

圖2 工作流模型組成元素表示圖Fig.2 The legend of Workflow engine
常見(jiàn)的結(jié)構(gòu)性問(wèn)題主要有以下幾個(gè)方面:
1)節(jié)點(diǎn)不可達(dá);指對(duì)于某一個(gè)節(jié)點(diǎn),無(wú)法從開(kāi)始節(jié)點(diǎn)找到一條路徑到達(dá)該節(jié)點(diǎn),如圖3(a)所示。如果存在不可達(dá)的節(jié)點(diǎn),那么該節(jié)點(diǎn)的存在是無(wú)意義的,因?yàn)樵诠ぷ髁鲗?shí)例的執(zhí)行過(guò)程中,該節(jié)點(diǎn)永遠(yuǎn)不會(huì)得到執(zhí)行。
2)非法并發(fā)單元:非法并發(fā)單元是指存在錯(cuò)誤的并發(fā)單元,錯(cuò)誤原因包括非法出口、非法入口和分支跳轉(zhuǎn)。
非法出口,是指存在某條路徑,可以從并發(fā)單元內(nèi)的某個(gè)節(jié)點(diǎn)直接到達(dá)并發(fā)單元外的某個(gè)節(jié)點(diǎn)。如圖3(b)所示,一個(gè)有非法出口的并發(fā)單元由并發(fā)單元內(nèi)的流程節(jié)點(diǎn)B可以直接到達(dá)并發(fā)單元外的流程節(jié)點(diǎn)E。
非法入口,是指存在某條路徑,可以從并發(fā)單元外的某個(gè)節(jié)點(diǎn)直接到達(dá)并發(fā)單元內(nèi)的某個(gè)節(jié)點(diǎn)。如圖3(c)所示,一個(gè)有非法入口的并發(fā)單元由并發(fā)單元外的流程節(jié)點(diǎn)A可以直接到達(dá)并發(fā)單元內(nèi)的流程節(jié)點(diǎn)C。
分支跳轉(zhuǎn),是指存在某條路徑,可以從某個(gè)分支直接到達(dá)同一個(gè)并發(fā)單元中的另一個(gè)分支。如圖3(d)所示,一個(gè)分支間存在跳轉(zhuǎn)的并發(fā)單元由并發(fā)開(kāi)始節(jié)點(diǎn)A有兩條完全不重合的路徑可以到達(dá)并發(fā)單元內(nèi)的流程節(jié)點(diǎn)C。
3)其他錯(cuò)誤:其他可能出現(xiàn)的結(jié)構(gòu)錯(cuò)誤如圖3(e)所示,一個(gè)并發(fā)單元的并發(fā)開(kāi)始節(jié)點(diǎn)A 可以直接到達(dá)并發(fā)結(jié)束節(jié)點(diǎn)D;又如圖3(f)所示,由流程節(jié)點(diǎn)A,B,C,D組成了一個(gè)環(huán),工作流實(shí)例一旦進(jìn)入該環(huán)中,將一直在流程節(jié)點(diǎn)A,B,C,D之間循環(huán)執(zhí)行,系統(tǒng)產(chǎn)生死循環(huán),導(dǎo)致工作流實(shí)例不能正常結(jié)束。
工作流模型可以看做是一個(gè)有向圖,利用深度優(yōu)先搜索的思想,對(duì)該有向圖進(jìn)行遍歷,能夠檢測(cè)出存在的結(jié)構(gòu)性錯(cuò)誤。結(jié)構(gòu)驗(yàn)證算法基于矩陣模型和深度優(yōu)先搜索,能夠檢測(cè)出典型的結(jié)構(gòu)性錯(cuò)誤。該算法的流程圖如圖4所示。
1)初始化變量。
初始化節(jié)點(diǎn)總數(shù)n,并規(guī)定開(kāi)始節(jié)點(diǎn)的編號(hào)為0,結(jié)束節(jié)點(diǎn)的編號(hào)是n-1,其他節(jié)點(diǎn)編號(hào)按照層次遍歷的順序從1 開(kāi)始逐一遞增。初始化矩陣變量matrix[n,n],visit[n,max]和info[n,3]。其中:

matrix[n,n]表示工作流模型中的節(jié)點(diǎn)間關(guān)系。visit[i,j]表示節(jié)點(diǎn)i到j(luò)之間的邊執(zhí)行情況,0表示未執(zhí)行,1表示已執(zhí)行,工作流實(shí)例執(zhí)行之前所有的邊都是未執(zhí)行的。info[i,0]表示節(jié)點(diǎn)i是否已遍歷,0表示未遍歷,1 表示已遍歷;info[i,1]表示節(jié)點(diǎn)i 入邊個(gè)數(shù),info[i,2]表示節(jié)點(diǎn)i的出邊個(gè)數(shù)。
2)驗(yàn)證節(jié)點(diǎn)可達(dá)性。
通過(guò)遞歸算法遍歷節(jié)點(diǎn),驗(yàn)證info[0...n-1,0]是否都是1,如果存在0的情況,假如info[i,0]為0,那么說(shuō)明無(wú)法找到一條路徑從開(kāi)始節(jié)點(diǎn)到達(dá)節(jié)點(diǎn)i,即存在不可達(dá)節(jié)點(diǎn);如果info[0...n-1,0]都是1,則驗(yàn)證通過(guò)。接下來(lái)驗(yàn)證第二部分,采用相同的算法,但是傳入?yún)?shù)matrix 時(shí),選擇傳入他的變形矩陣antiMatrix[n,n],其中:

驗(yàn)證從結(jié)束節(jié)點(diǎn)能否逆向到達(dá)所有節(jié)點(diǎn),即驗(yàn)證對(duì)于每一個(gè)節(jié)點(diǎn)都能至少找到一條路徑能到達(dá)結(jié)束節(jié)點(diǎn)。

圖3 結(jié)構(gòu)性錯(cuò)誤實(shí)例Fig.3 Examples of structural errors

圖4 結(jié)構(gòu)驗(yàn)證算法流程圖Fig.4 Flow chart of structure verification algorithm
3)驗(yàn)證是否存在非法的并發(fā)單元、死循環(huán)等錯(cuò)誤。
并發(fā)單元的驗(yàn)證主要依據(jù)并發(fā)單元的并發(fā)入口和并發(fā)出口的一對(duì)一的關(guān)系,且并發(fā)入口先于并發(fā)出口出現(xiàn)。因此,如果發(fā)生以下情況,則說(shuō)明存在非法并發(fā)單元:并發(fā)出口先于并發(fā)入口出現(xiàn);并發(fā)入口對(duì)應(yīng)多個(gè)并發(fā)出口,或并發(fā)出口存在多個(gè)并發(fā)入口;并發(fā)入口與并發(fā)出口直連。
為了達(dá)到上述驗(yàn)證目的,定義了一個(gè)遞歸函數(shù),其偽代碼如下:
Algorithm 1:結(jié)構(gòu)性驗(yàn)證算法
Input:
id:當(dāng)前遍歷節(jié)點(diǎn)的編號(hào),初始為0
matrix[n,n]:該有向圖的鄰接矩陣
info[n,3]:info[i,1]表示節(jié)點(diǎn)i 入邊個(gè)數(shù),info[i,2]表示節(jié)點(diǎn)i的出邊個(gè)數(shù)
dict[key,val]:dict中保存了所有的并發(fā)單元入口,并發(fā)單元出口的鍵值對(duì)[key,val]
stack:保存并發(fā)單元入口
Output:
errorInfo:記錄可能發(fā)生錯(cuò)誤的節(jié)點(diǎn)編號(hào)
1:if(info[i][2]>1)then
2:curKey ←id//curKey表示當(dāng)前并發(fā)單元入口
3:if(dict中不存在curKey)then
4:dict ←[curKey,-1]
5:curKey入棧stack
6:endif
7:endif
8:if(info[id][1]>1)then
9:curVal ←id//curVal表示當(dāng)前并發(fā)單元出口
10:if(dict中存在curKey)then
11:if(dict[curKey]不存在對(duì)應(yīng)的val)then
12:dict[curKey]←curVal
13:if(并發(fā)入口與并發(fā)出口直連)then
14:errorInfo ←curVal//出現(xiàn)錯(cuò)誤
15:endif
16:curKey 從stack 出棧//表示當(dāng)前并發(fā)單元入口已找到出口,配對(duì)完成
17:else if(dict[curKey]!=curVal)then
18:errorInfo ←curVal//當(dāng)前并發(fā)單元入口,存在多個(gè)出口,出現(xiàn)錯(cuò)誤
19:endif
20:else then
21:errorInfo ←curVal//當(dāng)前并發(fā)單元出口,不存在入口,出現(xiàn)錯(cuò)誤
22:endif
23:endif
24:for(與節(jié)點(diǎn)id存在聯(lián)系的所有節(jié)點(diǎn)i)
25:if(節(jié)點(diǎn)id到節(jié)點(diǎn)i之間的邊未遍歷過(guò))then
26:遞歸調(diào)用本算法,其中參數(shù)id傳入i
27:endif
28:endfor
根據(jù)文獻(xiàn)[16]中的相關(guān)表述,表1 中對(duì)常見(jiàn)的工作流結(jié)構(gòu)驗(yàn)證算法進(jìn)行了比較。其中N/A表示無(wú)法從文獻(xiàn)中獲知。

表1 結(jié)構(gòu)驗(yàn)證算法比較表Table1 Structure verification algorithm comparison table
由表1可知,相比其他算法,本算法可以驗(yàn)證節(jié)點(diǎn)不可達(dá)、非法并發(fā)以及死循環(huán)等常見(jiàn)的結(jié)構(gòu)性錯(cuò)誤,算法的時(shí)間復(fù)雜度不高,并且實(shí)現(xiàn)相對(duì)簡(jiǎn)單。
火力發(fā)電企業(yè)燃料信息系統(tǒng)中,存在很多審批流程,審批流程中存在多個(gè)環(huán)節(jié),這些環(huán)節(jié)的操作都是類(lèi)似的,只是操作順序或者操作角色不同。隨著需求的變動(dòng),審批流程需要經(jīng)常變更,系統(tǒng)開(kāi)發(fā)人員需要針對(duì)流程的變更,更改原先的審批流程代碼,給系統(tǒng)帶來(lái)了不穩(wěn)定性,也增加了開(kāi)發(fā)人員的負(fù)擔(dān)。因此針對(duì)這種情況,設(shè)計(jì)了工作流管理系統(tǒng),該系統(tǒng)可以自動(dòng)控制審批流程的自動(dòng)流轉(zhuǎn),即使更改審批流程,也不需要系統(tǒng)開(kāi)發(fā)人員更改代碼,從而保證了系統(tǒng)的穩(wěn)定性。
管理員設(shè)計(jì)工作流的具體執(zhí)行步驟,即定義工作流模型,定義結(jié)果將保存在數(shù)據(jù)庫(kù)中,作為工作流實(shí)例自動(dòng)流轉(zhuǎn)的依據(jù)。模型設(shè)計(jì)器的工具欄中,提供了組件繪制功能,通過(guò)鼠標(biāo)的點(diǎn)擊和拖拽動(dòng)作便可完成設(shè)計(jì),工具欄中還提供了清空,撤銷(xiāo)和與XML 文件相互轉(zhuǎn)換等輔助功能。模型設(shè)計(jì)器界面如圖5所示。

圖5 模型設(shè)計(jì)器界面示意圖Fig.5 Workflow engine designer interface
工作模型在保存之前,將進(jìn)行合理性驗(yàn)證,如果通過(guò)驗(yàn)證則保存到數(shù)據(jù)庫(kù)中,否則不予保存。如果審批流程需要變更,只需更改在模型設(shè)計(jì)器中做簡(jiǎn)單調(diào)整即可,不需要對(duì)系統(tǒng)代碼進(jìn)行更改,但是之前正在執(zhí)行的工作流實(shí)例必須重新開(kāi)始執(zhí)行。
由具有指定權(quán)限的用戶“提交”審批,之后便啟動(dòng)了一個(gè)合同審批流程的實(shí)例,該實(shí)例按照已定義的工作流模型開(kāi)始執(zhí)行。對(duì)于系統(tǒng)中所有相關(guān)用戶,都存在一個(gè)待處理審批流程頁(yè)面,當(dāng)某個(gè)工作流實(shí)例流轉(zhuǎn)到該用戶可處理的節(jié)點(diǎn)時(shí),頁(yè)面就會(huì)顯示這個(gè)工作流實(shí)例,該用戶就能對(duì)這個(gè)實(shí)例進(jìn)行審批操作。在審批過(guò)程中,可以看到工作流的詳細(xì)執(zhí)行情況,如圖6 所示,在已執(zhí)行節(jié)點(diǎn)上可以顯示該節(jié)點(diǎn)歷史執(zhí)行記錄,頁(yè)面右側(cè)顯示了該工作流實(shí)例的歷史執(zhí)行情況。

圖6 某工作流實(shí)例執(zhí)行情況界面Fig.6 Workflow instance execution interface
企業(yè)中某些業(yè)務(wù)流程只需要基本的“通過(guò)”和“退回”功能,如果采用成熟的商業(yè)或開(kāi)源工作流產(chǎn)品,將造成成本較高,集成復(fù)雜以及系統(tǒng)不兼容等問(wèn)題,本文針對(duì)這類(lèi)簡(jiǎn)單的業(yè)務(wù)流程設(shè)計(jì)和實(shí)現(xiàn)了輕量級(jí)的工作流管理系統(tǒng)可以有效解決該問(wèn)題。由于設(shè)計(jì)的工作流管理系統(tǒng)在工作流模型定義,模型結(jié)構(gòu)性驗(yàn)證方面存在一定的局限性,未來(lái)可以在模型設(shè)計(jì)器中,增加“或分支”功能,用于指示工作流中的并發(fā)單元是條件選擇關(guān)系,還是并發(fā)執(zhí)行關(guān)系。