Flowable actual combat BPMN2 0 task

  tasks are the most important part of the process. Flowable provides a variety of task types to meet actual needs.

  common task types are:

  • User tasks
  • Java Service task
  • Script task
  • Business rule task
  • Execution listener
  • Task listener
  • Multiple instances

  the task types of integration extension include:

  • Manual task
  • Java receive task
  • Shell task
  • Compensation processor
  • Web Service task
  • Mail task
  • Http task
  • Camel mission
  • Mule mission

  the graphics of the task are based on a rounded rectangle, and specific types of icons are added in the upper left corner.

1, Common task types

1.1 user tasks

1.1.1 description

  "user task" refers to a task that needs to be executed manually. When the process execution reaches the user task, the process instance will stop waiting until the user triggers the completion of the task action.

1.1.2 diagram

  user tasks are represented by standard tasks (rounded rectangle) with a small user icon in the upper left corner.

1.1.3 XML representation

  user tasks are defined in XML as follows. Where id is a required attribute and name is an optional attribute.

    <userTask id="theTask" name="important mission" />

1.1.4 expiry date

  due date can be set for each task.

  you can specify a fixed time or relative time. For example, when dueDate is "PT30M", it means that the task expires 30 minutes after it arrives.

  expiration date must conform to Java util. Date or Java util. String (ISO8601 format).

  for practical application, we specify as variable value.

    <userTask id="theTask" name="Important task" flowable:dueDate="${dateVariable}"/>

  the expiration date of a task can be modified using TaskService or the passed DelegateTask in TaskListener.

1.1.5 task assignment

  • Appoint a determined handler
    <userTask id="theTask" name="important mission" flowable:assignee="jinyangjie"/>
  • Assign potential managers
    <userTask id="theTask" name="important mission" flowable:candidateUsers="jinyangjie, zhangsan" />
  • Assign potential processing group
    <userTask id="theTask" name="important mission" flowable:candidateGroups="leader, manager" />

  more task assignments have been introduced in the chapter "users and groups", which will not be repeated here.

1.2 Java Service tasks

1.2.1 description

  Java service task is used to call Java classes. Java Service does not belong to BPMN2 0 specification, but a custom extension of Flowable.

1.2.2 diagram

  the service task is represented by a rounded rectangle with a pinion icon in the upper left corner.

1.2.3 XML representation

   there are three methods to declare how to call Java logic, which are described below:

  • Call fixed class

    use the flowable:class attribute to provide a fully qualified class name to specify the class called during process execution. This class must implement the JavaDelegate or ActivityBehavior interface.

    <serviceTask id="javaService" flowable:class="com.example.service.MyJavaDelegate" />
  • Call dynamic class

  use the flowable:delegateExpression property to provide the expression of the delegation object. This function is similar to flowable:class. It also needs to implement the JavaDelegate or ActivityBehavior interface, but instead of specifying a specific implementation class, it queries the Bean object with the specified name.

    <serviceTask id="javaService" flowable:delegateExpression="${myDelegateExpressionBean}" />

  myDelegateExpressionBean is a bean that implements the JavaDelegate interface and is defined in the Spring container.

  • Calls the specified method or property value of the class

  use the flowable:expression property to specify the method or property value of the class. Similarly, this class needs to implement the JavaDelegate or ActivityBehavior interface.

    <serviceTask id="javaService" flowable:expression="#{printer.printMessage()}" />

  the printMessage method (without parameters) will be called on the object named printer. Of course, you can also pass variables for the methods used in expressions.

   example of attribute value:

    <serviceTask id="javaService" flowable:expression="#{printer.ready}" />

  the getter method of the ready parameter of the bean named printer will be called, getReady (without parameters). The value is resolved to the process variable being executed.

1.2.4 specific implementation examples

   the following is an example of a Java class used to change the process variable String to uppercase. This class implements org flowable. engine. delegate. Javadelegate interface, which can be called during process execution.

  at the same time, you need to rewrite the execute(DelegateExecution) method to implement the business logic. This method is the method that the engine will call. In addition, various information of the process instance can be accessed through the DelegateExecution parameter in this method.

    public class ToUppercase implements JavaDelegate {
      public void execute(DelegateExecution execution) {
        String var = (String) execution.getVariable("input");
        var = var.toUpperCase();
        execution.setVariable("input", var);
      }
    }

  if you implement org flowable. engine. impl. delegate. The activitybehavior interface can access more powerful engine functions, such as the control process that can affect the process. But note that this is not a good practice and needs to be avoided.

1.2.5 return value of task

  the return value of service execution (only for service tasks using expressions) can be set as a process variable through the 'flowable:resultVariable' attribute defined for the service task. It can be an existing or new process variable. If it is specified as an existing process variable, the value of the process variable will be overwritten by the return value of the service execution. If the result variable name is not specified, the return value of the service task will be ignored.

    <serviceTask id="aMethodExpressionServiceTask"
        flowable:expression="#{myService.doSomething()}"
        flowable:resultVariable="myVar" />

  in the above example, the result of service execution (the return value of calling 'doSomething()' method) will be set as a process variable named 'myVar' after service execution is completed.

1.2.6 exception handling

  when executing custom logic, you usually need to capture and handle specific business exceptions in the process. Flowable provides a variety of ways.

1.2.6.1 throw BPMN error

  BPMN errors can be thrown in the user code of service tasks or script tasks. You can throw a special FlowableException: BpmnError in Java delegates, scripts, expressions, and delegate expressions. The engine catches the exception and forwards it to the appropriate error handler, such as an error boundary event or an error event subprocess.

    public class ThrowBpmnErrorDelegate implements JavaDelegate {
      public void execute(DelegateExecution execution) throws Exception {
        try {
          executeBusinessLogic();
        } catch (BusinessException e) {
          throw new BpmnError("BusinessExceptionOccurred");
        }
      }
    }

   the argument to the constructor is the error code. The error code determines the error processor that handles this error.

  this mechanism should only be used for business errors, which need to be handled through the error boundary event or error event sub process defined in the process. Technical errors should be represented by other exception types and are usually not handled within the process.

1.2.6.2 exception mapping

  you can directly map Java exceptions to business exceptions (errors) using the mapException extension. Single mapping is the simplest form:

    <serviceTask id="servicetask1" flowable:class="...">
      <extensionElements>
        <flowable:mapException
              errorCode="myErrorCode1">com.example.SomeException</flowable:mapException>
      </extensionElements>
    </serviceTask>

  in the above code, if the service task throws org flowable. An instance of someexception, which is caught by the engine and converted into a BPMN error with a given errorCode. Then it can be handled exactly like a normal BPMN error. Other exceptions are not mapped and will still be thrown to API calls.

  you can also use the includechildexception attribute in a single line to map all child exceptions of a specific exception.

    <serviceTask id="servicetask1" flowable:class="...">
      <extensionElements>
        <flowable:mapException errorCode="myErrorCode1"
               includeChildExceptions="true">com.example.SomeException</flowable:mapException>
      </extensionElements>
    </serviceTask>

  in the above code, Flowable will convert any direct or indirect subclass of SomeException into a BPMN error with the specified error code. "false" is considered when includechildexception is not specified.

1.2.6.3 default mapping

  default mapping is the most commonly used. The default mapping is a mapping that does not specify a class and can match any Java exception:

    <serviceTask id="servicetask1" flowable:class="...">
      <extensionElements>
        <flowable:mapException errorCode="myErrorCode1"/>
      </extensionElements>
    </serviceTask>

    in addition to the default mapping, the mapping will be checked from top to bottom, and the first matching mapping will be used. Use the default mapping only if none of the mappings match successfully. Only the first mapping that does not specify a class will be the default mapping. The default mapping ignores includechildexception.

1.2.6.4 abnormal sequence flow

  there is also a recommended usage to route the process execution to another path when an exception occurs. Here is an example.

    <serviceTask id="servicetask1" flowable:class="com.example.ThrowsExceptionBehavior">
    </serviceTask>

    <sequenceFlow id="no-exception" sourceRef="javaService" targetRef="theEnd" />
    <sequenceFlow id="exception" sourceRef="javaService" targetRef="fixException" />

  the service task has two exit sequence flows named exception and no exception. When an exception occurs, use the sequence flow ID to control the flow direction of the process:

    public class ThrowsExceptionBehavior implements ActivityBehavior {

      public void execute(DelegateExecution execution) {
        String var = (String) execution.getVariable("var");

        String sequenceFlowToTake = null;
        try {
          executeLogic(var);
          sequenceFlowToTake = "no-exception";
        } catch (Exception e) {
          sequenceFlowToTake = "exception";
        }
        DelegateHelper.leaveDelegate(execution, sequenceFlowToTake);
      }

    }

1.3 script tasks

1.3.1 description

  script tasks are automatically executed activities. When the process execution reaches the script task, the corresponding script will be executed.

1.3.2 diagram

  script tasks are represented by standard BPMN 2.0 tasks (rounded rectangle) with a small "script" icon in the upper left corner.

1.3.3 XML representation

  script tasks are defined using script and scriptFormat elements.

    <scriptTask id="theScriptTask" scriptFormat="groovy">
      <script>
        sum = 0
        for ( i in inputArray ) {
          sum += i
        }
      </script>
    </scriptTask>

   by default, JavaScript is included in each JDK, so there is no need to add any jar files. If you want to use another scripting engine, you need to add the corresponding jar in the classpath and use the appropriate name. For example, Flowable unit tests often use Groovy. The Groovy script engine is bundled with the Groovy all jar. Add the following dependencies:

    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.x.x<version>
    </dependency>

1.3.4 variables in scripts

  during the execution of the script engine, all process variables can be used in the script. In this example, the script variable 'inputArray' is actually a process variable (an array of integer s).

    <script>
        sum = 0
        for ( i in inputArray ) {
          sum += i
        }
    </script>

  examples of setting variables in scripts:

    <script>
        def scriptVar = "test123"
        execution.setVariable("myVar", scriptVar)
    </script>

Note: the following names are reserved words and cannot be used for variable names: out, out:print, lang:import, context, elcontext.

1.3.5 results of script tasks

  the return value of the script task can be set as a process variable through the 'flowable:resultVariable' attribute defined for the script task. It can be an existing or new process variable. If it is specified as an existing process variable, the value of the process variable will be overwritten by the result value of script execution. If you do not specify a result variable name, the script result value is ignored.

    <scriptTask id="theScriptTask" scriptFormat="juel" flowable:resultVariable="myVar">
      <script>#{echo}</script>
    </scriptTask>

    in the above example, the result of script execution (parsing the value of expression '#{echo}') will be set as a process variable named 'myVar' after the script is completed.

1.4 business rule tasks

1.4.1 description

  in enterprise applications, it is recommended to use a maintainable rule base to manage complex and changeable business rules, and maintain business codes and rules separately. Once the rules are changed, you only need to modify the preset rules without affecting the business codes.

  business rule tasks can process preset business rules according to the value of process variables. Flowable supports Drools, the most popular rule engine at present. Just package and deploy the process file containing business rule tasks and the rule engine file ". drl" into the system, and add the jar package of Drools to realize the flowable driven rule engine.

1.4.2 diagram

  business rule tasks are displayed as rounded rectangles with table icons.

1.4.3 XML representation

  to execute business rules, you need to define input and result variables. Input variables can be defined in the list of process variables, separated by commas. The output variable can only have one variable name. If no result variable name is specified, the default value is org flowable. engine. rules. OUTPUT.

    <process id="simpleBusinessRuleProcess">
      <startEvent id="theStart" />
      <sequenceFlow sourceRef="theStart" targetRef="businessRuleTask" />

      <businessRuleTask id="businessRuleTask" flowable:ruleVariablesInput="${order}"
          flowable:resultVariable="rulesOutput" />

      <sequenceFlow sourceRef="businessRuleTask" targetRef="theEnd" />

      <endEvent id="theEnd" />
    </process>

  business rule tasks can also be configured to execute only deployed tasks A set of rules in a drl file. To do this, you need to specify a list of rule names, separated by commas.

    <businessRuleTask id="businessRuleTask" flowable:ruleVariablesInput="${order}"
          flowable:rules="rule1, rule2" />

  this will only execute rule1 and rule2.

  you can also define a list of rules that need to be excluded from execution.

    <businessRuleTask id="businessRuleTask" flowable:ruleVariablesInput="${order}"
          flowable:rules="rule1, rule2" exclude="true" />

  in this example, all other rules deployed with the process definition will be executed except rule1 and rule2.

Note: the business rule task of integrating Drools is an important content in enterprise applications and needs to be mastered.

1.5 execution listener

1.5.1 description

  the execution listener can execute external Java code or evaluate expressions when a specific event occurs during process execution. Events that can be captured are:

  • Start and end of process instances.
  • Process execution transfer.
  • Start and end of activities.
  • Start and end of gateway.
  • Start and end of intermediate events.
  • The end of the start event and the start of the end event.

1.5.2 XML representation

  the following process definition contains three execution listeners:

<process id="executionListenersProcess">

  <extensionElements>
    <flowable:executionListener
      class="org.flowable.examples.bpmn.executionlistener.ExampleExecutionListenerOne"
      event="start" />
  </extensionElements>

  <startEvent id="theStart" />
  <sequenceFlow sourceRef="theStart" targetRef="firstTask" />

  <userTask id="firstTask" />
  <sequenceFlow sourceRef="firstTask" targetRef="secondTask">
    <extensionElements>
      <flowable:executionListener
        class="org.flowable.examples.bpmn.executionListener.ExampleExecutionListenerTwo" />
    </extensionElements>
  </sequenceFlow>

  <userTask id="secondTask" >
    <extensionElements>
      <flowable:executionListener
        expression="${myPojo.myMethod(execution.event)}"
        event="end" />
    </extensionElements>
  </userTask>
  <sequenceFlow sourceRef="secondTask" targetRef="thirdTask" />

  <userTask id="thirdTask" />
  <sequenceFlow sourceRef="thirdTask" targetRef="theEnd" />

  <endEvent id="theEnd" />

</process>

  the first execution listener will be notified when the process starts. The listener is an external Java class (ExampleExecutionListenerOne) and needs to implement org flowable. engine. delegate. Executionlistener interface. When this event occurs (here is the start event), the notify (executionlistener execution) method will be called.

    public class ExampleExecutionListenerOne implements ExecutionListener {

      public void notify(ExecutionListenerExecution execution) throws Exception {
        execution.setVariable("variableSetInExecutionListener", "firstValue");
        execution.setVariable("eventReceived", execution.getEventName());
      }
    }

    you can also use the implementation of org flowable. engine. delegate. Delegate class for the javadelegate interface. These delegate classes can also be used for other structures, such as the delegation of service tasks.

   the second execution listener is called when the process executes the transfer. Note that the listener element does not define an event because only the take event is triggered on the transfer. When a listener is defined on a transition, the value of the event property is ignored.

The last execution listener is called at the end of the secondTask activity. Instead of using class in the listener declaration, expression is defined. This expression will be evaluated / called when the event is triggered.

    <flowable:executionListener expression="${myPojo.myMethod(execution.eventName)}" event="end" />

    like other expressions, you can use and to resolve the execution variable.

1.5.3 perform field injection on the listener

  field injection can be used when using the execution listener configured through the class attribute.

  the following code snippet shows a simple example process with an execution listener using field injection.

<process id="executionListenersProcess">
  <extensionElements>
    <flowable:executionListener
        class="org.flowable.examples.bpmn.executionListener.ExampleFieldInjectedExecutionListener"
        event="start">

      <flowable:field name="fixedValue" stringValue="Yes, I am " />
      <flowable:field name="dynamicValue" expression="${myVar}" />

    </flowable:executionListener>
  </extensionElements>

  <startEvent id="theStart" />
  <sequenceFlow sourceRef="theStart" targetRef="firstTask" />

  <userTask id="firstTask" />
  <sequenceFlow sourceRef="firstTask" targetRef="theEnd" />

  <endEvent id="theEnd" />
</process>

    the ExampleFieldInjectedExecutionListener class will connect two fields (one is fixed value - fixedValue and the other is dynamic value - dynamicValue) and store them in the 'var' process variable.

    @Deployment(resources = {
      "org/flowable/examples/bpmn/executionListener/ExecutionListenersFieldInjectionProcess.bpmn20.xml"})
    public void testExecutionListenerFieldInjection() {
      Map<String, Object> variables = new HashMap<String, Object>();
      variables.put("myVar", "listening!");

      ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
          "executionListenersProcess", variables);

      Object varSetByListener = runtimeService.getVariable(processInstance.getId(), "var");
      assertNotNull(varSetByListener);
      assertTrue(varSetByListener instanceof String);

      // The result is the connection of fixed injection fields and injection expressions
      assertEquals("Yes, I am listening!", varSetByListener);
    }

1.6 task listener

1.6.1 description

  task listener is used to execute custom Java logic or expressions when specific task related events occur.

1.6.2 XML representation

  task listeners can only be used as child elements of user tasks in process definitions. Note that the task listener is a flowable custom structure, so it also needs to be placed under the flowable namespace as BPMN 2.0 extensionElements.

    <userTask id="myTask" >
      <extensionElements>
        <flowable:taskListener event="create" class="com.example.MyTaskCreateListener" />
      </extensionElements>
    </userTask>

1.6.3 task listener properties:

1.6.3.1 event

   task event type that triggers the task listener; required. Available events are:

  • create: triggered when a task has been created and all task parameters have been set.
  • Assignment: triggered when a task has been assigned to someone. Please note: when the process execution reaches the user task, the assignment event will be triggered first before the create event is triggered. This order seems unnatural, but there is a practical reason: when we receive the create event, we usually want to see all the parameters of the task, including the handler.
  • complete: triggered before deleting from the runtime data when the task has been completed.
  • delete: triggered immediately before the task is deleted. Please note that the task will also be triggered when it is normally completed by completeTask.
1.6.3.2 class

  delegate class to be called. This class must implement org flowable. engine. delegate. Tasklistener interface.

    public class MyTaskCreateListener implements TaskListener {
      public void notify(DelegateTask delegateTask) {
        // Here is the business logic to be implemented
      }
    }

  field injection can also be used to pass process variables or execute for delegate classes. Please note that the instance of the delegate class is created during process deployment (like other delegate classes in Flowable), which means that the instance will be shared in the execution of all process instances.

1.6.3.3 expression

    specifies the expression to be executed when the event occurs (cannot be used with the class attribute). The DelegateTask object and event name (using task.eventName) can be passed as parameters for the called object.

    <flowable:taskListener event="create" expression="${myObject.callMethod(task, task.eventName)}" />
1.6.3.4 delegateExpression

   specify an expression that can be resolved to an object of the TaskListener interface implementation class.

    <flowable:taskListener event="create" delegateExpression="${myTaskListenerBean}" />

1.7 multiple instances

1.7.1 description

  multi instance activity is a way to define repetition for specific steps in a business process. In the programming concept, multi instance is similar to the structure of for each: specific steps or even the whole sub process can be executed sequentially or in parallel for each entry in a given set.

  gateways and events cannot be set to multiple instances.

  according to BPMN2 The requirements of the 0 specification are used to create a parent execution for each instance. The following variables are provided:

  • nrOfInstances: total number of instances.
  • nrOfActiveInstances: the number of currently active (i.e. incomplete) instances. For sequential multiple instances, this value is always 1.
  • nrOfCompletedInstances: number of completed instances.

  you can call execution The getvariable (x) method gets these values.

   in addition, each created execution has local variables (not visible to other executions or stored at the process instance level):

  • loopCounter: the index of the given instance in the for each loop.

1.7.2 diagram

  if an activity is multi instance, it will be represented by three short lines at the bottom of the activity. Three vertical lines represent that the instance will execute in parallel, while three horizontal lines represent sequential execution.

1.7.3 XML representation

  to make an activity multi instance, the XML element of the activity must have a multiInstanceLoopCharacteristics child element

    <multiInstanceLoopCharacteristics isSequential="false|true">
     ...
    </multiInstanceLoopCharacteristics>

The   isSequential property represents whether the instances of the activity are executed sequentially or in parallel.

  there are 4 different methods to configure the quantity.

1.7.3.1 designated number

   directly specify the number through the loopCardinality sub element:

    <multiInstanceLoopCharacteristics isSequential="false|true">
      <loopCardinality>5</loopCardinality>
    </multiInstanceLoopCharacteristics>
1.7.3.2 expression

    use an expression that resolves to a positive integer:

    <multiInstanceLoopCharacteristics isSequential="false|true">
      <loopCardinality>${nrOfOrders-nrOfCancellations}</loopCardinality>
    </multiInstanceLoopCharacteristics>
1.7.3.3 specified set

  another way to define the number of instances is to use the loopDataInputRef sub element to specify the name of a collective process variable. For each item in the collection, an instance is created. You can use the inputDataItem child element to set the item to a local variable of the instance. Shown in the following XML example:

    <userTask id="miTasks" name="My Task ${loopCounter}" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="false">
        <loopDataInputRef>assigneeList</loopDataInputRef>
        <inputDataItem name="assignee" />
      </multiInstanceLoopCharacteristics>
    </userTask>

  suppose the variable assigneeList contains [kermit, gonzo, fozzie]. The above code creates three parallel user tasks. Each execution has a (local) process variable named assignee, which contains an item in the set and is used to assign user tasks in this example.

  the disadvantage of loopDataInputRef and inputDataItem is that the names are difficult to remember, and expressions cannot be used due to the limitations of BPMN 2.0 profile. Flowable solves these problems by providing collection and elementVariable attributes on multiInstanceCharacteristics:

    <userTask id="miTasks" name="My Task" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="true"
         flowable:collection="${myService.resolveUsersForTask()}" flowable:elementVariable="assignee" >
      </multiInstanceLoopCharacteristics>
    </userTask>

    please note that the collection property will be parsed as an expression. If the expression is parsed into a string instead of a collection, whether it is configured as a static string value or the expression calculation result is a string, this string will be used as a variable name in the process variable to obtain the actual collection.

  for example, the following code snippet will let the engine find the collection stored in the assigneeList process variable:

    <userTask id="miTasks" name="My Task" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="true"
         flowable:collection="assigneeList" flowable:elementVariable="assignee" >
      </multiInstanceLoopCharacteristics>
    </userTask>
1.7.3.4 conditional quantity

  multi instance activities end when all instances are completed. However, you can also specify an expression that evaluates at the end of each instance. When the expression evaluates to true, all remaining instances will be destroyed, and the multi instance activity will be ended to continue the process. This expression must be defined through the completionCondition child element.

    <userTask id="miTasks" name="My Task" flowable:assignee="${assignee}">
      <multiInstanceLoopCharacteristics isSequential="false"
         flowable:collection="assigneeList" flowable:elementVariable="assignee" >
        <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6 }</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>

  in this example, a parallel instance will be created for each element in the assigneeList collection. When 60% of the tasks are completed, other tasks will be deleted and the process will continue to run.

2, Task type of integration extension

   Flowable also has many integrated and extended tasks. These tasks are not commonly used. Beginners can skip them and go back to them when necessary.

2.1 manual tasks

2.1.1 description

  manual task is used to define tasks that cannot be completed by BPM engine. For the engine, the manual task will be treated as an empty task. When the process execution reaches the manual task, the process will continue to execute automatically.

2.1.2 diagram

  manual tasks are represented by standard BPMN 2.0 tasks (rounded rectangle) with a small "hand" icon in the upper left corner.

2.1.3 XML representation

    <manualTask id="myManualTask" name="Call client for more information" />

2.2 Java receiving task

2.2.1 description

   receive task is a simple task waiting for a specific message to arrive. When the process execution reaches the receiving task, it will remain in the waiting state until the engine receives a specific message and triggers the process to continue execution through the receiving task.

2.2.2 diagram

  the receiving task is represented by a standard BPMN 2.0 task (rounded rectangle) with a message icon in the upper left corner. The message icon is white (the corresponding black message icon represents the meaning of sending).

2.2.3 XML representation

    <receiveTask id="waitState" name="wait" />

2.2.4 application method

  to make the process instance continue to execute from the waiting state of the receiving task, you need to use the execution id of the receiving task and call runtimeservice signal(executionId). The following code snippet shows how to do this:

    ProcessInstance pi = runtimeService.startProcessInstanceByKey("receiveTask");
    Execution execution = runtimeService.createExecutionQuery()
      .processInstanceId(pi.getId())
      .activityId("waitState")
      .singleResult();

    runtimeService.trigger(execution.getId());

2.3 Shell tasks

2.3.1 description

   Shell task can run Shell scripts and commands. Note that the Shell task is not an "official" task of the BPMN 2.0 specification (so there is no dedicated icon).

2.3.2 defining Shell tasks

   the shell task is implemented as a special service task, and the type of the service task is defined as' shell 'for setting.

    <serviceTask id="shellEcho" flowable:type="shell">

2.3.3 Shell task parameters

  Shell tasks are configured through field injection. The values of these parameters can use EL expressions and will be parsed at the process execution run time. The following parameters can be set:

parameterRequired?typedescribeDefault value
commandyesStringShell command to execute.
arg0-5noStringParameter 0 to parameter 5
waitnotrue/falseWhether to wait for the Shell process to terminate.true
redirectErrornotrue/falseWhether to incorporate standard error into standard output.false
cleanEnvnotrue/falseWhether to prevent Shell processes from inheriting the current environment.false
outputVariablenoStringThe name of the variable that holds the outputNo output is recorded.
errorCodeVariablenoStringThe variable name that holds the result error codeError codes are not logged.
directorynoStringDefault directory for Shell processescurrent directory

2.3.4 use examples

  the following XML code snippet is an example of using Shell tasks. The "cmd /c echo EchoTest" Shell script will be run, wait for its end, and store its results in resultVar.

    <serviceTask id="shellEcho" flowable:type="shell" >
      <extensionElements>
        <flowable:field name="command" stringValue="cmd" />
        <flowable:field name="arg1" stringValue="/c" />
        <flowable:field name="arg2" stringValue="echo" />
        <flowable:field name="arg3" stringValue="EchoTest" />
        <flowable:field name="wait" stringValue="true" />
        <flowable:field name="outputVariable" stringValue="resultVar" />
      </extensionElements>
    </serviceTask>

2.4 compensation processor

2.4.1 description

  if you want to use one activity to compensate for the impact of another activity, you can declare it as a compensation handler. The compensation processor does not execute in the normal process, but only when the process throws a compensation event.

  the compensation processor shall not have an inlet or outlet sequence flow.

  the compensation processor must associate a compensation boundary event through a one-way connection.

2.4.2 diagram

  if an activity is a compensation processor, the compensation event icon is displayed in the middle of the lower part. The flowchart excerpted below shows a service task with compensation boundary events and associated to a compensation processor. Note that the compensation processor icon is displayed in the lower middle of the cancel hotel reservation service task.

2.4.3 XML representation

  to declare an activity as a compensation processor, you need to set the isForCompensation property to true:

    <serviceTask id="undoBookHotel" isForCompensation="true" flowable:class="...">
    </serviceTask>

2.5 integration tasks

  • Web Service task: call external Web Service resources.
  • Mail task: used to send mail.
  • Http task: used to issue Http requests.
  • Camel task: integrate message routing framework.
  • Mule task: integrate enterprise system bus framework mule.

    the integration tasks above will be described in detail in subsequent chapters. Just learn about them here.

3, Summary

  this chapter introduces BPMN2 0 specification and Flowable user-defined extended task types. Various task types provided by Flowable basically cover the requirements of enterprise applications. However, there are still many issues that need our attention, such as script security in script tasks and thread security in multiple instances.

Keywords: npm bpmn

Added by AcousticJames on Sun, 16 Jan 2022 11:07:52 +0200