1. 程式人生 > 其它 >jbpm5.1介紹(7)

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]}]