天天看點

OSWorkflow的基本概念[原]

rel=File-List href="./OSWorkflow的基本概念.files/filelist.xml" target="_blank" rel="external nofollow" > 一、工作流的概念

一、工作流的概念

1. 步驟、狀态和動作

工作流要描述步驟(step)、步驟的狀态(status)、各個步驟之間的關系以及執行各個步驟的條件和權限,每個步驟中可以含有一個或多個動作(action),動作将會使一個步驟的狀态發生改變。

對于一個執行的工作流來講,步驟的切換是不可避免的。一個工作流在某一時刻會有一個或多個目前步驟,每個目前步驟都有一個狀态值,目前步驟的狀态值組成了工作流執行個體的狀态值。一旦完成了一個步驟,那麼這個步驟将不再是目前步驟(而是切換到一個新的步驟),通常一個新的目前步驟将随之建立起來,以保證工作流繼續執行。完成了的步驟的最終狀态值是用old-status屬性指定的,這個狀态值的設定将發生在切換到其他步驟之前。old-status的值可以是任意的,但在一般情況下,我們設定為Finished。

切換本身是一個動作(action)的執行結果。每個步驟可以含有多個動作,究竟要載入哪個動作是由最終使用者、外部事件或者triggerd的自動調用決定的。随着動作的完成,一個特定的步驟切換也将發生。動作可以被限制在使用者、使用者組或目前狀态。每一個動作都必須包含一個unconditional result和0個或多個conditional results。

是以,總體來說,一個工作流由多個步驟組成。每個步驟有一個目前狀态(例如:Queued, Underway, or Finished),一個步驟包含多個動作。每個步驟含有多個可以執行的動作。每個動作都有執行的條件,也有要執行的函數。動作包含有可以改變狀态和目前工作流步驟的results。

2. Results, Joins, and Splits

(1) Unconditional Result

對于每一個動作來講,必須存在一個Unconditional Result。一個result是一系列指令,這些指令将告訴OSWorkFlow下一個任務要做什麼。這包括使工作流從一個狀态切換到另一個狀态。

(2) conditional Result

conditional Result是unconditional Result的一個擴充。它需要一個或多個condition子标簽。第一個為true的conditional(使用AND或OR類型),會指明發生切換的步驟,這個切換步驟的發生是由于某個使用者執行了某個動作的結果導緻的。

(3) 三種不同的Results (conditional or unconditional

 --一個新的、單一的步驟和狀态的組合。

 --一個分裂成兩個或多個步驟和狀态的組合。

 --将這個和其他的切換組合成一個新的單一的步驟和狀态的組合。

 每種不同的result對應了不同的xml描述,你可以閱讀http://www.opensymphony.com/osworkflow/workflow_2_6.dtd,擷取更多的資訊。

 注意:通常,一個split或一個join不會再導緻一個split 或 join的發生。

① 單一步驟和狀态的結果可以這樣描述:

<unconditional-result old-status="Finished" step="2" status="Underway" owner="${someOwner}"/>

如果狀态不是Queued的話,那麼第三個必要條件就是新步驟的所有者(owner)。除了可以指明下一個狀态的資訊之外,result也可以指定validators和 post-functions,這将在下面讨論。

② 從一個狀态分裂成多個狀态可以這樣描述:

<unconditional-result split="1"/>

...

<splits>

  <split id="1">

    <unconditional-result old-status="Finished" step="2"

                          status="Underway" owner="${someOwner}"/>

    <unconditional-result old-status="Finished" step="2"

                          status="Underway" owner="${someOtherOwner}"/>

  </split>

</splits>

③ 将多個狀态合并為一個狀态可以這樣描述:

<!-- for step id 6 ->

<unconditional-result join="1"/>

...

<!- for step id 8 ->

<unconditional-result join="1"/>

...

<joins>

  <join id="1">

    <conditions type="AND">

      <condition type="beanshell">

        <arg name="script">

          "Finished".equals(jn.getStep(6).getStatus()

          && "Finished".equals(jn.getStep(8).getStatus())

        </arg>

      </condition>

    </conditions>

  <unconditional-result old-status="Finished" status="Underway" owner="test" step="2"/>

  </join>

</joins>

上面的描述也許有點含糊,但是你最應該關注的是condition标簽,它使用一個"jn"的變量,利用這個變量,你可以組成表達式來決定合并動作發生的條件。這個表達式的意思是說:“當id=6和id=8的步驟的狀态都變成Finished的狀态并且他們要發生的切換都是join="1"時,這個合并動作才發生”。

3. 外部函數

OSWorkFlow為要定義和執行的外部業務邏輯定義了一個标準的解決方法。這是通過使用"functions"來實作的。OSWorkFlow有兩種function,pre和post step functions。

Pre functions是在流程的步驟發生切換之前執行的。一個例子是取得調用者名字的函數,将取得的調用者的名字作為要發生狀态切換的result使用。另外一個例子是pre-function用來更新大多數的動作的最近調用者。這兩個函數是做為标準的工具函數提供的,在實際的工作流中非常實用。

Post functions與Pre functions有着同樣的适用範圍,不同點在于Post functions是在狀态發生變化之後執行的。一個典型的Post functions的例子是:在某個動作執行完畢後,給某些人發送電子郵件。例如:當一個文檔處于'research'步驟,并且執行了'markReadyForReview'動作的時候,要發送郵件給所有的reviewers。

使用Post functions與Pre functions可能有很多原因。一個是如果使用者點選完成按鈕兩次而且發送了兩次執行動作的指令,而且這個動作的Pre function會執行很長時間,那麼這個長時間執行的函數可能會被執行多次,因為切換動作還沒有發生,這時OSWorkflow會認為第二次執行動作是合理的。是以要将這個函數改變成Post function。一般情況下,Pre function應該是簡單的、能快速執行的函數。

函數可以定義在兩個獨立的位置:步驟(step)和動作(action)。

通常情況下,Post functions與Pre functions被定義在action中。在action中定義的Pre-functions是指在該動作發生之前要執行的函數。當工作流發生切換的時候,函數用來做某些事情,不管是發送E_mail也好,還是為以後的使用設定變量。

當Post functions與Pre functions被定義在step中的時候,用途就有點不同了。在step中定義的Pre-functions是指在切換到這個step之前要執行

的函數。注意:這些函數将被應用到這個步驟的所有的切換,即使是由于這個步驟本身發起的切換,例如:在同一個步驟内,由Queued狀态轉移到Underway狀态時,也将調用所有的 Pre functions。與此相同,在step中的Post functions将在流程離開這個步驟之前。

4. Trigger Functions

Trigger Functions與其他函數一樣,不同點在于他們不是與一個動作相聯系的。他們也是通過一個唯一的ID來辨別。這些函數通常是運作在系統級使用者或非正規使用者的環境中。Trigger functions是通過OSWorkflow的API來使用。

5. Validators

validator 是用來校驗一個動作的輸入的有效性的。如果輸入符合條件,那麼将執行這個動作。如果輸入不符合條件,那麼将抛出InvalidInputException異常。

6. Registers

A register 是一個輔助函數,這個函數可以傳回一個對象,這個對象可以用在函數中去通路其他的普通對象,特别是出現在workflow中的實體。被注冊的對象可以是任何類型,典型的注冊對象的例子是:Document, Metadata, Issue, 和Task。

下面是一個registers的例子:

<registers>

       <register name="doc" class="com.acme.DocumentRegister"/>

</registers>

...

<results>

       <result condition="doc.priority == 1" step="1" status="Underway"

                  owner="${someManager}"/>

       <unconditional-result step="1" status="Queued"/>

</results>

...

7. Conditions

Conditions就象validators,registers和functions一樣,可以用不同的語言和技術來實作。Conditions可以用AND或OR邏輯運算符來組織。Conditions通常是與conditional results聯系的,隻有當條件成立,result才會執行。

Conditions與函數很相似,唯一不同的是Conditions傳回的是boolean值,而不是void。

8. Variable Interpolation

在所有的functions、conditions、validators和registers中,可能要提供一系列的參數。這些參數将會被轉化為參數Map,這将在後面讨論。同樣,在workflow描述符中的status,old-status和owner标簽也将被動态的解析成變量。一個變量是這樣被識别的:${foo}。當OSWorkflow識别出這種格式的時候,它首先到transientVars中去找關鍵字為foo的對象,如果沒有找到,那麼就到propertySet中去找,如果也沒找到,那麼變量foo将被轉換為一個空字串。

One thing of particular importance is that in the case of args, if the variable is the only argument, the argument will not be of type String, but instead whatever the variable type is. However, if the arg is a mix of characters and variables, the entire argument is converted to String no matter what. That means the two arguments below are very different in that foo is a Date object and bar is a String:

<arg name="foo">${someDate}</arg>

<arg name="bar"> ${someDate} </arg> <!-- 注意多餘的空格 -->

9. Permissions and Restrictions

Permissions can be assigned to users and/or groups based on the state of the workflow instance. These permissions are unrelated to the functionality of the workflow engine, but they are useful to have for applications that implement OSWorkflow. For example, a document management system might have the permission name "file-write-permission" enabled for a particular group only during the "Document Edit" stage of the workflow. That way your application can use the API to determine if files can be modified or not. This is useful as there could be a number of states within the workflow where the "file-write-permission" is applicable, so instead of checking for specific steps or conditions, the check can simply be made for a particular permission.

10. Auto actions

有的時候,我們需要一些動作可以基于一些條件自動地執行。為了達到這個目的,你可以在action中加入auto="true"屬性。流程将考察這個動作的條件和限制,如果條件符合,那麼将執行這個動作。 Auto action是由目前的調用者執行的,是以将對該動作的調用者執行權限檢查。

11. Integrating with Abstract Entities

建議在你的核心實體中,例如"Document" 或 "Order",在内部建立一個新的屬性:workflowId。這樣,當新的"Document" 或 "Order"被建立的時候,它能夠和一個workflow執行個體關聯起來。那麼,你的代碼可以通過OSWorkflow API查找到這個workflow執行個體并且得到這個workflow的資訊和動作。

12. Workflow Instance State

有的時候,為整個workflow執行個體指定一個狀态是很有幫助的,它獨立于流程的執行步驟。OSWorkflow提供一些workflow執行個體中可以包含的"meta-states"。這些"meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。當一個工作流執行個體被建立的時候,它将處于CREATED狀态。然後,隻要一個動作被執行,它就會自動的變成ACTIVATED狀态。如果調用者沒有明确地改變執行個體的狀态,工作流将一直保持這個狀态直到工作流結束。當工作流不可能再執行任何其他的動作的時候,工作流将自動的變成COMPLETED狀态。

然而,當工作流處于ACTIVATED狀态的時候,調用者可以終止或挂起這個工作流(設定工作流的狀态為KILLED 或 SUSPENDED)。一個終止了的工作流将不能再執行任何動作,而且将永遠保持着終止狀态。一個被挂起了的工作流會被當機,他也不能執行任何的動作,除非它的狀态再變成ACTIVATED。

繼續閱讀