About using Activiti BPM in business process development

Hello everyone! We mentioned earlier that the Unidata platform is actively working with business processes and supports BPMN notation at the heart of their design. For BP development, we use the open source Activiti BPMN engine based on java. Among the available open source products for business process design, we chose Activiti for 2 reasons:





  • We already had experience with this product





  • There is a convenient Apache license for commercial development





In this article, we will share our own experience of using Activiti in the development of real business processes for a customer.





The first step in developing a business process is to form a business process diagram. For example, the Activiti plug-in for Eclipse allows you to visually design a business process in BPMN 2.0 notation. The visual editor has all the necessary components for this: tasks of various types, subprocesses, gateways, triggers, scripts, and others. It is enough to drag a BPM element from the list onto the diagram, and then connect all the elements with “arrows”, as in BPMN notation it is denoted “Sequence Flow”. The diagram of the business process by means of Activiti is written into a special configuration xml-file, which can be further edited. Below is an example of a simple business process.





, BPMN, :





  • UserTask – , . -





  • ServiceTask , .





  • MailTask





  • (Sequence Flow) . (“”)









  • . , , SLA .





, , , .  Activiti, - Unidata. , java-, WorkflowProcessSupport, . WorkflowProcessSupport Activiti Unidata.  .





@Override
public WorkflowProcessStartState processStart(StartProcessRequestContext ctx) {
    WorkflowProcessStartState state = new WorkflowProcessStartState();
    state.setAllow(true);
 
    Map<String, Object> processVariables = state.getAdditionalProcessVariables();
    if (processVariables == null) {
        processVariables = new HashMap<>();
    }
 
    processVariables.put("validFrom", ctx.getValidFrom());
    processVariables.put("validTo", ctx.getValidTo());
 
 
    state.setAdditionalProcessVariables(processVariables);
    return state;
}
      
      



processStart (userTask) . task_id, .





@Override
public WorkflowProcessAfterStartState afterProcessStart(String processInstanceId, String
        processDefinitionId, Map<String, Object> variables) {
 
    WorkflowProcessAfterStartState state = new WorkflowProcessAfterStartState();
    Map<String, Object> processVariables = state.getAdditionalProcessVariables();
    if (processVariables == null) {
        processVariables = new HashMap<>();
    }
 
    processVariables.put("processId", processInstanceId);
 
 
    String initiatorEmail = (String) variables.get("initiatorEmail");
    if (initiatorEmail == null || !initiatorEmail.contains("@"))
        processVariables.put("initiatorEmail", "testmail@testmail.com");
 
    state.setAdditionalProcessVariables(processVariables);
 
    return state;
}
      
      



afterProcessStart . processStart tasl_id, .





@Override
public WorkflowTaskCompleteState complete(String taskDefinitionId, Map<String, Object> variables,
                                          String actionCode) {
    WorkflowTaskCompleteState state = new WorkflowTaskCompleteState(true, "FINISHED".equals(actionCode) ? "Approve task." : "Decline task.");
    Map<String, Object> additionalProcessVariables = state.getAdditionalProcessVariables();
    if (additionalProcessVariables == null) {
        additionalProcessVariables = new HashMap<>();
    }
    Map<String, Object> additionalTaskVariables = state.getAdditionalProcessVariables();
 
     if (taskDefinitionId.equals("expertTask")) {
        if (!WorkflowUtils.curatorsIsAvailable("role_name")) {
            throw new WorkflowException(USER_NOT_AVALIBLE, ExceptionId.EX_WF_CANNOT_COMPLETE_TASK_COMPLETION_ERROR);
        }
    }
 
    state.setAdditionalProcessVariables(additionalProcessVariables);
    state.setAdditionalTaskVariables(additionalTaskVariables);
    return state;
}
      
      



complete , .





@Override
public WorkflowProcessEndState processEnd(String processDefinitionId, Map<String, Object> variables) {
 
    String selectorValue = (String) variables.get("finishTaskSelector");
    WorkflowProcessEndState state = new WorkflowProcessEndState();
    if (selectorValue != null && selectorValue.equals("complete")) {
        state.setComplete(true);
    } else {
        state.setComplete(false);
    }
    LOGGER.info(String.format("End process %s with action %s", processDefinitionId, selectorValue));
    return state;
}
      
      



processEnd -. - , , , .





, , . Activiti, Activiti. , Form properties UserTask.





descriptionCode, , taskSelector, . . - , . , .





, – . UserTask, Main config Assignee Candidate group. Assignee, . Candidate group, , , .





, - . . -. , , . , Activiti , . Activiti Listener’, Java , .





- , Activiti , – . , -, .  Activiti , . . - , Activiti Activiti SQL .   , , Activiti elasticsearch. .





, Activiti BPM - , ,   .








All Articles