Activity-错误事件

设计一个流程:

提交一个新的 sales leader, 创建一个子流程, 在子流程中同时对 customer rating 以及 profitability 进行考察, 如果同时通过, 则结束子流程, 完成主流程的 Store lead in CRM system 任务以及结束节点

如果 profitability 任务没有提供足够的信息, 则会抛出错误事件, 错误事件被边界事件所捕获, 进入 Provide additional details 流程, 并重新进入开始子流程

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:activiti="http://activiti.org/bpmn" targetNamespace="Examples"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
             http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd">

  <error id="notEnoughInfoError" errorCode="not_enough_info" />
  <process id="reviewSaledLead" name="Review sales lead">
    <startEvent id="theStart" activiti:initiator="initiator" />
    <sequenceFlow id="flow1" sourceRef="theStart" targetRef="provideNewSalesLead"/>
    <userTask id="provideNewSalesLead" name="Provide new sales lead" activiti:assignee="${initiator}">
      <extensionElements>
        <activiti:formProperty id="customerName" name="Customer name" type="string" required="true"/>
        <activiti:formProperty id="potentialProfit" name="Potential profit" type="long" />
        <activiti:formProperty id="details" name="Details" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow2" sourceRef="provideNewSalesLead" targetRef="reviewSalesLeadSubProcess"/>
    <!-- 子流程 -->
    <subProcess id="reviewSalesLeadSubProcess" name="Review sales lead">
      <startEvent id="subProcessStart" />
      <sequenceFlow id="flow3" sourceRef="subProcessStart" targetRef="fork"/>
      <sequenceFlow id="flow4" sourceRef="fork" targetRef="reviewProfitability"/>
      <parallelGateway id="fork" />
      <sequenceFlow id="flow5" sourceRef="fork" targetRef="reviewCustomerRating"/>
      <userTask id="reviewCustomerRating" name="Review customer rating" activiti:candidateGroups="accountancy" />
      <sequenceFlow id="flow6" sourceRef="reviewCustomerRating" targetRef="subProcessEnd1"/>
      <endEvent id="subProcessEnd1" />
      <userTask id="reviewProfitability" name="Review profitability" activiti:candidateGroups="management">
        <documentation>
          ${initiator} has published a new sales lead: ${customerName}. Details: ${details}
        </documentation>
        <extensionElements>
          <activiti:formProperty id="notEnoughInformation" name="Do you believe this customer is profitable?" type="enum" required="true">
            <activiti:value id="false" name="Yes" />
            <activiti:value id="true" name="No (= request more info)" />
          </activiti:formProperty>
        </extensionElements>
      </userTask>
      <sequenceFlow id="flow7" sourceRef="reviewProfitability" targetRef="enoughInformationCheck"/>
      <exclusiveGateway id="enoughInformationCheck" name="Enough information?" />
      <sequenceFlow id="flow8" sourceRef="enoughInformationCheck" targetRef="notEnoughInformationEnd">
        <conditionExpression>${notEnoughInformation == 'true'}</conditionExpression>
      </sequenceFlow>
      <sequenceFlow id="flow9" sourceRef="enoughInformationCheck" targetRef="subProcessEnd2">
        <conditionExpression>${notEnoughInformation == 'false'}</conditionExpression>
      </sequenceFlow>
      <endEvent id="subProcessEnd2" />
      <endEvent id="notEnoughInformationEnd">
        <errorEventDefinition errorRef="notEnoughInfoError" />
      </endEvent>
    </subProcess>
    <sequenceFlow id="flow10" sourceRef="reviewSalesLeadSubProcess" targetRef="storeLeadInCrmSystem"/>
    <boundaryEvent attachedToRef="reviewSalesLeadSubProcess" cancelActivity="true" id="catchNotEnoughInformationError" >
      <errorEventDefinition errorRef="notEnoughInfoError" />
    </boundaryEvent>
    <sequenceFlow id="flow11" sourceRef="catchNotEnoughInformationError" targetRef="provideAdditionalDetails"/>
    <userTask id="provideAdditionalDetails" name="Provide additional details" activiti:assignee="${initiator}">
      <documentation>Provide additional details for ${customerName}.</documentation>
      <extensionElements>
        <activiti:formProperty id="details" name="Additional details" type="string" required="true"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow12" sourceRef="provideAdditionalDetails" targetRef="reviewSalesLeadSubProcess"/>
    <task id="storeLeadInCrmSystem" name="Store lead in CRM system" />
    <sequenceFlow id="flow13" sourceRef="storeLeadInCrmSystem" targetRef="processEnd"/>
    <endEvent id="processEnd" />
  </process>

</definitions>

代码:

package com.lala.boundaryerrorevent;

import common.ProcessEngineUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

public class BoundaryErrorEvent {
    public static void main(String[] args) {
        // 设置流程发起者
        Authentication.setAuthenticatedUserId("destiny");
        ProcessEngineUtil processEngineUtil = new ProcessEngineUtil("boundaryErrorEvent.bpmn20.xml");
        ProcessEngine processEngine = processEngineUtil.getProcessEngine();
        Map<String, Object> variables = new HashMap<>();
        variables.put("details", "interesting");
        variables.put("customerName", "Camery");
        ProcessInstance processInstance = processEngine.getRuntimeService().
            startProcessInstanceByKey("reviewSaledLead", variables);
        TaskService taskService = processEngine.getTaskService();

        // 流程启动,列出当前由destiny的创建所有流程,当前是在开始的第一个节点Provide new sales lead
        System.out.println("流程开始");
        Task task = taskService.createTaskQuery()
            .taskAssignee("destiny")
            .singleResult();
        System.out.println("task name: " + task.getName());
        // 提交节点
        taskService.complete(task.getId());

        // 进入并行网关, 会同时生成两个 task, 一个到eview customer rating,另外一个到Review profitability
        Task ratingTask = taskService.createTaskQuery().taskCandidateGroup("accountancy").singleResult();
        System.out.println("ratingTask name: " + ratingTask.getName());

        Task profitabilityTask = taskService.createTaskQuery().taskCandidateGroup("management").singleResult();
        System.out.println("profitabilityTask name: " + profitabilityTask.getName());

        // Review profitability 提交后就会触发 errorEvent
        variables = new HashMap<>();
        variables.put("notEnoughInformation", true);
        taskService.complete(profitabilityTask.getId(), variables);

        // 查找流程发起者 destiny 对应的 task
        // 此时 errorEvent 会被边界条件捕获, 整个事件会流转到 Provide additional details
        Task provideDetailsTask = taskService.createTaskQuery().taskAssignee("destiny").singleResult();
        System.out.println("provideDetailsTask: {}" + provideDetailsTask);
        System.out.println("provideDetailsTask name: " + provideDetailsTask.getName());


        // 完成 Provide additional details 节点后, 会重新进入子流程
        taskService.complete(provideDetailsTask.getId());
        List<Task> reviewTasks = taskService.createTaskQuery().orderByTaskName().asc().list();
        for (Task reviewTask : reviewTasks) {
            System.out.println("reviewTask name: " + reviewTask.getName());
        }
        // 完成子流程的两个节点
        taskService.complete(reviewTasks.get(0).getId());
        variables.put("notEnoughInformation", false);
        taskService.complete(reviewTasks.get(1).getId(), variables);
        // 画出整套流程图
        processEngineUtil.draw(processInstance);
    }
}

流程图:

Activity-错误事件

 

上一篇:Activiti 流程变量


下一篇:[NgRx] Optimistically Editing Entity Data