1. 程式人生 > >深入理解Activiti工作流

深入理解Activiti工作流

 

來源:https://www.jdon.com/soa/activiti.html

  Activiti作為一個流行的開源工作流引擎,正在不斷髮展,其6.0版本以API形式提供服務,而之前版本基本都是要求我們的應用以JDK方式與其互動,只能將其攜帶到我們的應用中,而API方式則可以伺服器獨立執行方式,能夠形成一個專網內工作流引擎資源共享的方式。

Activiti執行的BPMN2.0,這個規範中有幾個要素見下圖:

其實最經常使用的是開始結束事件和任務,本文就以這三個為例,說明通過UI畫圖和REST API方式如何實現呼叫,當然如果能夠了解BPMN的XML,就能更加精確地定製流程,否則只能是玩玩而已,當然如果你說掌握XML定義不如程式設計呢,至少程式設計工具還能提示錯誤,BPMN繪圖畫錯了很難發現,特別是攜帶很多資料,這些資料又有不同的邏輯關係時,隱藏在圖形化流程背後的邏輯關係被弱化了。

 

2.下載

我們可以從Activiti網站本身下載兩個webapps 的war檔案。

對於v6.0.0,我們可以下載activiti-6.0.0.zip,解壓縮,war檔案可以在activiti-6.0.0 / wars目錄中找到。

activiti-app提供了一個使用者介面,使用者可以通過該介面執行任何身份管理和任務管理相關的操作,建立使用者和組。同樣,activiti-rest是一個webapp,它提供REST API,用於對流程,任務等執行任何操

3. Activiti Kickstart App

我們需要一個可用的Java執行時和一個Apache Tomcat

安裝來部署該應用程式。任何Web容器都可以工作,但Activiti主要在Tomcat上進行測試。

現在,我們只需要在Tomcat上部署戰爭並使用http:// localhost:8080 / activiti-app訪問它。

使用者名稱和密碼:

activiti-admin: admin/admin
activiti-app: admin/test
activiti-rest: kermit/kermit

主頁應如下所示:

 

 

3.1 資料庫

預設情況下,它使用H2記憶體資料庫。如果我們想要更改資料庫配置,我們可以檢查程式碼並修改activiti-app.properties

檔案。執行此操作後,我們需要重新生成war檔案,這可以通過執行start.sh指令碼來完成。這將構建activiti-app以及所需的依賴項。

3.2。Kickstart App

當我們點選Kickstart App時,我們會獲得使用Process的選項我們可以建立/匯入流程並從這裡執行它們。

讓我們建立一個包含單個User Task的小流程,該任務接收來自使用者的訊息。進入Kickstart應用程式後,要建立流程,請選擇Processes選項卡,然後單擊Create Process

流程編輯器將開啟,我們可以拖放開始事件,各種型別的任務和結束事件的各種符號來定義流程。

當我們在我們的流程中新增使用者任務時,我們需要將其分配給某人。我們可以通過單擊此任務選項中的分配並選擇受理人來完成此操作

為簡單起見,讓我們將任務分配給流程啟動器:

我們還希望此使用者任務從使用者獲取輸入訊息。為此,我們需要將Form與單個文字欄位關聯到此任務。

選擇使用者任務,然後選擇參考表格 Referenced form。目前,沒有與任務關聯的表單,因此單擊“ 新建表單”,然後新增所需的詳細資訊:

在此之後,它將帶我們到表單部分,我們可以在表單中拖放我們想要的各種欄位,併為它們設定標籤:

請注意,我們已勾選Required,這意味著如果不輸入Message,則無法完成User任務

完成後,我們將儲存並轉到“app標籤。為了能夠執行我們建立的流程,我們需要建立一個Process App。

在Process App中,我們可以新增一個或多個Process Definitions。執行此操作後,我們需要釋出此應用程式,以便其他使用者可以使用流程,這個釋出很重要,如果你的流程有錯誤就釋出不了,當然Activiti也不會像IDE那樣告訴你精確的錯誤位置和原因或提示,你自己好好反省自查。

當然我們也可以將流程匯出BPMN.xml檔案,主要部分內容:

<startEvent id="startEvent1"></startEvent>
<userTask id="sid-9A9219F8-306C-4ED0-A243-88756537F7FA" activiti:assignee="$INITIATOR" activiti:formKey="userinputmessage">
<extensionElements>
<modeler:activiti-idm-initiator xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-initiator>
</extensionElements>
</userTask>
<sequenceFlow id="sid-4CB3BA7F-30A3-49F6-97CE-82D0BD2FD9F8" sourceRef="startEvent1" targetRef="sid-9A9219F8-306C-4ED0-A243-88756537F7FA"></sequenceFlow>
<endEvent id="sid-A6BA7A4E-D1AC-451D-A3D2-5FEC5408519C"></endEvent>
<sequenceFlow id="sid-B8CC1746-E80B-4185-AA6A-5E85031E4152" sourceRef="sid-9A9219F8-306C-4ED0-A243-88756537F7FA" targetRef="sid-A6BA7A4E-D1AC-451D-A3D2-5FEC5408519C"></sequenceFlow>
</process>

這些startEvent、userTask是文章開頭第一張圖裡面的對應含義。sequenceFLow是順序流,startEvent是流程事件,userTask是任務。

 

3.3 任務應用程式

在任務應用程式中,有兩個選項卡:任務 - 用於當前正在執行的任務,以及流程 - 用於當前正在執行的流程。

單擊“ 流程中的開始流程”選項卡後,我們將獲得可以執行的可用流程列表。從此列表中,我們將選擇我們的流程並單擊開始按鈕,只有你的流程釋出publish之後才能看到,也才能按開始按鈕。

我們的流程只包含一個任務,它是一個使用者任務。因此,該過程正在等待使用者完成此任務。當我們點選流程正在等待的任務時,我們可以看到我們建立的表單:

如果我們點選檢視圖,這將不僅向我們展示過程圖也強調,完成的任務和正在等待的人。在我們的示例中,使用者任務仍處於待處理狀態,會突出顯示:

要完成此任務,我們可以單擊Complete butto n。如前所述,我們需要輸入訊息,因為我們必須保留它。因此,在輸入訊息後,我們可以完成任務。

3.4。身份管理應用

除了管理流程外,我們還有一個身份管理應用程式,允許我們新增使用者和組。我們還可以為使用者定義角色。

4. Activiti REST

Activiti為Activiti Engine提供REST API,可以通過將activiti-rest.war檔案部署到像Apache Tomcat這樣的servlet容器來安裝。

預設情況下,Activiti Engine將連線到記憶體中的H2資料庫。就像我們在activiti-app中看到的一樣,在這裡我們可以更改WEB-INF / classes資料夾中db.properties檔案中的資料庫設定並重新建立war檔案。

啟動並執行應用程式後,我們可以將此基本URL用於所有請求:

http://localhost:8080/activiti-rest/service/

預設情況下,所有REST資源都需要對有效的Activiti使用者進行身份驗證。每次REST呼叫都應使用基本HTTP訪問身份驗證。

4.1。建立和執行流程

要建立流程,首先,我們需要BPMN檔案用於流程。我們可以按照之前基於Activiti with Java的文章中的描述建立檔案,也可以從Kickstart App的Process部分下載。

我們需要發一個POST請求,以及contentType:multipart / form-data,我們將為我們的新流程上傳BPMN檔案,在postman中設定:body中選擇form,key填入file;型別從text和file中選擇file,然後上傳我們之前匯出的BPMN.xml檔案,授權選擇basic auth,使用者名稱和密碼: kermit

POST http://127.0.0.1:8080/activiti-rest/service/repository/deployments

當我們通過傳遞我們建立的流程的BPMN檔案來進行此呼叫時,它將提供以下輸出:

{
"id": "40",
"name": "myprocess.bpmn20.xml",
"deploymentTime": "2018-08-21T15:20:11.056+08:00",
"category": null,
"url": "http://127.0.0.1:8080/activiti-rest/service/repository/deployments/40",
"tenantId": ""
}

現在,如果我們獲得所有流程定義,我們可以看到列出的流程定義:

 

GET http://127.0.0.1:8080/activiti-rest/service/repository/process-definitions

接下來,我們可以使用我們在BPMN檔案中提到的processKey來執行此過程:

POST http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances

有了這個請求正文:

{
"processDefinitionKey":"myprocess-Id"
}

響應將是:

{
"id": "48",
"url": "http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances/48",
"businessKey": null,
"suspended": false,
"ended": false,
"processDefinitionId": "myprocess-Id:2:47",
"processDefinitionUrl": "http://127.0.0.1:8080/activiti-rest/service/repository/process-definitions/myprocess-Id:2:47",
"processDefinitionKey": "myprocess-Id",
"activityId": null,
"variables": [],
"tenantId": "",
"name": null,
"completed": false
}

我們可以使用上一個響應返回的流程例項的id來檢視正在執行的流程圖:

 

GET http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances/48/diagram

如前所述,該過程正在等待使用者任務完成,因此它在圖中突出顯示:

 

4.2。完成任務

現在讓我們看看我們的待處理任務:

 

GET http://127.0.0.1:8080/activiti-rest/service/runtime/tasks

響應將包含待處理任務的列表。目前,只有一項任務 - 我們的使用者任務

{
      "data": [
      {
      "id": "53",
      "url": "http://127.0.0.1:8080/activiti-rest/service/runtime/tasks/53",
      "owner": null,
      "assignee": "$INITIATOR",
      "delegationState": null,
      "name": null,
      "description": null,
      "createTime": "2018-08-21T15:23:55.714+08:00",
      "dueDate": null,
      "priority": 50,
      "suspended": false,
      "taskDefinitionKey": "sid-9A9219F8-306C-4ED0-A243-88756537F7FA",
      "tenantId": "",
      "category": null,
      "formKey": "userinputmessage",
      "parentTaskId": null,
      "parentTaskUrl": null,
      "executionId": "50",
      "executionUrl": "http://127.0.0.1:8080/activiti-rest/service/runtime/executions/50",
      "processInstanceId": "48",
      "processInstanceUrl": "http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances/48",
      "processDefinitionId": "myprocess-Id:2:47",
      "processDefinitionUrl": "http://127.0.0.1:8080/activiti-rest/service/repository/process-definitions/myprocess-Id:2:47",
      "variables": []
      }
      ],
      "total": 1,
      "start": 0,
      "sort": "id",
      "order": "asc",
      "size": 1
}

最後,讓我們使用任務ID 49完成此任務:

 

POST http://127.0.0.1:8080/activiti-rest/service/runtime/tasks/53

這是一個POST請求,我們需要傳送操作欄位來指示我們要對該任務執行的操作。我們可以“解決”,“完成”或“刪除”任務。此外,我們可以傳遞任務所需的變數陣列來完成。

在我們的例子中,我們要傳遞一個欄位“message”,它就是使用者訊息文字欄位。所以我們的要求是:

{

    "action": "complete",

     "variables": [{

         "name": "message",

         "value": "This is a User Input Message"

     }]

}

 

5.結論

在本文中,我們討論瞭如何使用Activiti Kickstart應用程式和提供的REST API。

 

Github案例1 GitHub案例2

在Spring Boot中使用activiti

工作流引擎四重罪

無伺服器使用流程場景舉例