jbpm5.1介紹(7)
Junit測試評估流程
評估流程的介面如下:
這個示例裡邊用到了Script Task,Service Task和User Task
Log執行記錄日誌的功能,打印出一段資訊
RegisterRequest呼叫外部預定義的程式或者其它引擎的程式
Two呼叫人工任務
看一下呼叫的測試程式
public void testEvaluationProcess() throws Exception { KnowledgeBase kbase = createKnowledgeBase("BPMN2-EvaluationProcess.bpmn2"); StatefulKnowledgeSession ksession = createKnowledgeSession(kbase); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("RegisterRequest", new SystemOutWorkItemHandler()); Map<String, Object> params = new HashMap<String, Object>(); params.put("employee", "UserId-12345"); ProcessInstance processInstance = ksession.startProcess("Evaluation", params); assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED); }
在程式中註冊工作處理程式
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler()); ksession.getWorkItemManager().registerWorkItemHandler("RegisterRequest", new SystemOutWorkItemHandler());
看一下SystemOutWorkItemHandler中的內容
public class SystemOutWorkItemHandler implements WorkItemHandler { public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { System.out.println("Executing work item " + workItem); manager.completeWorkItem(workItem.getId(), null); } public void abortWorkItem(WorkItem workItem, WorkItemManager manager) { System.out.println("Aborting work item " + workItem); manager.abortWorkItem(workItem.getId()); } }
看一下WorkItemHandler,這個介面
Method Summary | |
---|---|
void |
abortWorkItem(WorkItem workItem, WorkItemManager manager) The given work item should be aborted. |
void |
executeWorkItem(WorkItem workItem, WorkItemManager manager) The given work item should be executed. |
有兩個方法,一個是要執行的工作任務,一個是忽略的工作任務
執行junit測試,會發現輸出了
Loading process BPMN2-EvaluationProcess.bpmn2 Processing evaluation for employee UserId-12345 Executing work item WorkItem 1 [name=RegisterRequest, state=0, processInstanceId=1, parameters{employeeId=UserId-12345}] Executing work item WorkItem 2 [name=Human Task, state=0, processInstanceId=1, parameters{}] 先是執行RegisterRequest這個裡邊的executeWorkItem方法
然後執行了Human Task裡的executeWorkItem方法
最後使用
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
判斷狀態完成,執行成功
Junit測試評估流程2
評估流程的介面如下,同樣的流程,開啟BPMN2-EvaluationProcess2.bpmn2檔案
同前邊的示例一下,看一下測試2的示例程式
public void testEvaluationProcess2() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-EvaluationProcess2.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
params.put("employee", "UserId-12345");
ProcessInstance processInstance = ksession.startProcess("com.sample.evaluation", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
執行完成後的結果如下:
Loading process BPMN2-EvaluationProcess2.bpmn2 Executing work item WorkItem 1 [name=Human Task, state=0, processInstanceId=1, parameters{ActorId=UserId-12345, Comment=You need to perform a self evaluation, Skippable=false, Content=, TaskName=Performance Evaluation, Priority=1}] Executing work item WorkItem 2 [name=Human Task, state=0, processInstanceId=1, parameters{ActorId=john, Comment=You need to perform an evaluation for employee UserId-12345, Skippable=false, Content=, TaskName=Performance Evaluation, Priority=1}] Executing work item WorkItem 3 [name=Human Task, state=0, processInstanceId=1, parameters{ActorId=mary, Comment=You need to perform an evaluation for employee UserId-12345, Skippable=false, Content=, TaskName=Performance Evaluation, Priority=1}] 每個人的工作任務自動向下執行。
Junit測試評估流程3
評估流程的介面如下,同第一個是一樣的
看一下示例程式
public void testEvaluationProcess3() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-EvaluationProcess3.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler());
ksession.getWorkItemManager().registerWorkItemHandler("RegisterRequest", new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
params.put("employee", "john2");
ProcessInstance processInstance = ksession.startProcess("Evaluation", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
執行之後看結果
Loading process BPMN2-EvaluationProcess3.bpmn2 Processing evaluation for employee john2 Executing work item WorkItem 1 [name=Human Task, state=0, processInstanceId=1, parameters{}]
可以看到只執行了Human Task,預設情況下注冊進來的多個Handler如果不指定的話會預設執行Human Task,如果指定了就先指定執行的,如第一個示例再執行Human Task
Junit測試使用者任務
接下來的示例是測試使用者任務的示例,開啟BPMN2-UserTask.bpmn2檔案,流程定義檔案如下
指定了ActorId為john
看測試用例程式
public void testUserTask() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-UserTask.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler);
ProcessInstance processInstance = ksession.startProcess("UserTask");
assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE);
ksession = restoreSession(ksession, true);
WorkItem workItem = workItemHandler.getWorkItem();
assertNotNull(workItem);
assertEquals("john", workItem.getParameter("ActorId"));
ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null);
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
先定義了一個TestWorkItemHandler,然後將這個handler定義為人工任務
然後判斷節點狀態是否是啟用狀態
然後判斷流程中執行的是john在執行這個任務並且完成,最後判斷流程完成
TestWorkItemHandler中的內容如下:
public static class TestWorkItemHandler implements WorkItemHandler {
private List<WorkItem> workItems = new ArrayList<WorkItem>();
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
workItems.add(workItem);
}
public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
}
public WorkItem getWorkItem() {
System.out.println("執行test workitem");
if (workItems.size() == 0) {
return null;
}
if (workItems.size() == 1) {
WorkItem result = workItems.get(0);
this.workItems.clear();
return result;
} else {
throw new IllegalArgumentException("More than one work item active");
}
}
public List<WorkItem> getWorkItems() {
List<WorkItem> result = new ArrayList<WorkItem>(workItems);
workItems.clear();
return result;
}
}
執行結果如下顯示
Loading process BPMN2-UserTask.bpmn2 執行test workitem
Junit測試泳道
接下來的示例是一個測試泳道的例子,泳道的概念可以理解成一個角色或者一個組,就是相當於一組人
看流程圖
定義了泳道“MyLane”
在hello上指定了ActorId是john,在Goodbye上沒有指定人
看流程示例
public void testLane() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-Lane.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
ksession.getWorkItemManager().registerWorkItemHandler("Human Task",
workItemHandler);
ProcessInstance processInstance = ksession.startProcess("UserTask");
assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE);
ksession = restoreSession(ksession, true);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task",
workItemHandler);
WorkItem workItem = workItemHandler.getWorkItem();
assertNotNull(workItem);
assertEquals("john", workItem.getParameter("ActorId"));
Map<String, Object> results = new HashMap<String, Object>();
results.put("ActorId", "mary");
ksession.getWorkItemManager().completeWorkItem(workItem.getId(),
results);
ksession = restoreSession(ksession, true);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task",
workItemHandler);
workItem = workItemHandler.getWorkItem();
assertNotNull(workItem);
assertEquals("mary", workItem.getParameter("ActorId"));
ksession.getWorkItemManager().completeWorkItem(workItem.getId(), null);
assertProcessInstanceCompleted(processInstance.getId(), ksession);
}
定義任務並且執行,並且可以看到第一個使用者任務的執行人是john,然後向裡傳入了第二個使用者,mary
這個使用者將被賦到泳道MyLane上
然後在看執行使用者變成了mary,最後流程結束
看輸出結果
Loading process BPMN2-Lane.bpmn2 執行test workitemWorkItem 1 [name=Human Task, state=0, processInstanceId=1, parameters{ActorId=john}] 執行test workitemWorkItem 2 [name=Human Task, state=0, processInstanceId=1, parameters{ActorId=mary}]
Junit測試異或流程
接下來的示例是測試gateway的異或流程,看一下示例
流程圖如下
就是說只需要執行其中的一個流程,就可以讓流程繼續向下執行,這個示例是根據傳入的變數X來看向哪執行
看測試程式碼
public void testExclusiveSplit() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplit.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Email",
new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
params.put("x", "First");
params.put("y", "Second");
ProcessInstance processInstance = ksession.startProcess(
"com.sample.test", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
執行測試流程結果如下
Loading process BPMN2-ExclusiveSplit.bpmn2 x=First Executing work item WorkItem 1 [name=Email, state=0, processInstanceId=1, parameters{Body=This is an urgent email First, Subject=Urgent email !, [email protected], [email protected]}] 即當流程執行到其中有一個後則流程自動向下執行
Junit測試異或流程高階1
接下來的示例是測試,看如下流程定義
這個是根據動態傳入的看結點的值是不是a如果是a則走上邊的流程,如果不是則走下邊的流程
public void testExclusiveSplitXPathAdvanced() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath-advanced.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Email",
new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element hi = doc.createElement("hi");
Element ho = doc.createElement("ho");
hi.appendChild(ho);
Attr attr = doc.createAttribute("value");
ho.setAttributeNode(attr);
attr.setValue("a");
params.put("x", hi);
params.put("y", "Second");
ProcessInstance processInstance = ksession.startProcess(
"com.sample.test", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
根據傳入的結點執行流程
執行結果如下
Loading process BPMN2-ExclusiveSplitXPath-advanced.bpmn2 x=[hi: null] Executing work item WorkItem 1 [name=Email, state=0, processInstanceId=1, parameters{[email protected], Subject=Urgent email !, [email protected], [email protected]}]
Junit測試異或流程高階2
接下來的示例是測試,如下流程圖
流程結點定義
還是根據值來判斷流向,這次只指定x
看測試程式
public void testExclusiveSplitXPathAdvanced2() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath-advanced-vars-not-signaled.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Email",
new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element hi = doc.createElement("hi");
Element ho = doc.createElement("ho");
hi.appendChild(ho);
Attr attr = doc.createAttribute("value");
ho.setAttributeNode(attr);
attr.setValue("a");
params.put("x", hi);
params.put("y", "Second");
ProcessInstance processInstance = ksession.startProcess(
"com.sample.test", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
執行的流程結果
Loading process BPMN2-ExclusiveSplitXPath-advanced-vars-not-signaled.bpmn2 y=Second Executing work item WorkItem 1 [name=Email, state=0, processInstanceId=1, parameters{[email protected], Subject=Urgent email !, [email protected], [email protected]}]
Junit測試異或流程帶引數
與上邊幾個程式基本一致,直接上程式碼吧
public void testExclusiveSplitXPathAdvancedWithVars() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitXPath-advanced-with-vars.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Email",
new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element hi = doc.createElement("hi");
Element ho = doc.createElement("ho");
hi.appendChild(ho);
Attr attr = doc.createAttribute("value");
ho.setAttributeNode(attr);
attr.setValue("a");
params.put("x", hi);
params.put("y", "Second");
ProcessInstance processInstance = ksession.startProcess(
"com.sample.test", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
執行結果
Loading process BPMN2-ExclusiveSplitXPath-advanced-with-vars.bpmn2 x=[hi: null] Executing work item WorkItem 1 [name=Email, state=0, processInstanceId=1, parameters{[email protected], Subject=Urgent email !, [email protected], [email protected]}]
Junit測試異或流程優先和預設
下面的兩個流程和上邊基本一致只是細節上有些不同,一個是根據優先順序流向一個是根據預設值流向
優先
public void testExclusiveSplitPriority() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitPriority.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Email",
new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
params.put("x", "First");
params.put("y", "Second");
ProcessInstance processInstance = ksession.startProcess(
"com.sample.test", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
預設
public void testExclusiveSplitDefault() throws Exception {
KnowledgeBase kbase = createKnowledgeBase("BPMN2-ExclusiveSplitDefault.bpmn2");
StatefulKnowledgeSession ksession = createKnowledgeSession(kbase);
ksession.getWorkItemManager().registerWorkItemHandler("Email",
new SystemOutWorkItemHandler());
Map<String, Object> params = new HashMap<String, Object>();
params.put("x", "NotFirst");
params.put("y", "Second");
ProcessInstance processInstance = ksession.startProcess(
"com.sample.test", params);
assertTrue(processInstance.getState() == ProcessInstance.STATE_COMPLETED);
}
分別的執行結果如下:
優先
Loading process BPMN2-ExclusiveSplitPriority.bpmn2 y=Second Executing work item WorkItem 1 [name=Email, state=0, processInstanceId=1, parameters{Body=This is an urgent email First, Subject=Urgent email !, [email protected], [email protected]}]
預設
Loading process BPMN2-ExclusiveSplitDefault.bpmn2 y=Second Executing work item WorkItem 1 [name=Email, state=0, processInstanceId=1, parameters{Body=This is an urgent email NotFirst, Subject=Urgent email !, [email protected], [email protected]}]