Search code examples
flowable

FLOWABLE: Executing Service Tasks from java code without using xml


I am using Flowable 6.4.1 in spring-boot to create processes and run from my java code, but requirement is to not use any xml, so due to this I have hit a blockade.

I have a user task, taking input from user, depending on that input, call to corresponding service task is made.

Below is a short example of what I am going to do:

basic-process.bpmn20.xml:

<process id="basicprocess" name="Basic Process" isExecutable="true">

    <startEvent id="startEvent"/>
    <sequenceFlow sourceRef="startEvent" targetRef="getInput"/>

    <userTask id="getInput" name="Get input from user" />
    <sequenceFlow sourceRef="getInput" targetRef="decision"/>

    <exclusiveGateway id="decision"/>
    <sequenceFlow sourceRef="decision" targetRef="firstServiceTask">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
          ${number>100}
        ]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow  sourceRef="decision" targetRef="secondServiceTask">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
          ${number<=100}
        ]]>
      </conditionExpression>
    </sequenceFlow>

    <serviceTask id="firstServiceTask" name="Number is greater than predefined target"
        flowable:class="demo.service.tasks.FirstServiceTask"/>
    <sequenceFlow sourceRef="firstServiceTask" targetRef="greaterEnd"/>

    <serviceTask id="secondServiceTask" name="Number is less than predefined target"
        flowable:class="demo.service.tasks.SecondServiceTask"/>
    <sequenceFlow sourceRef="secondServiceTask" targetRef="lesserEnd"/>

    <endEvent id="greaterEnd"/>

    <endEvent id="lesserEnd"/>

  </process>

Above, XML shows the process and I'm starting the process using REST API Below is the controller:

DefinitionsController.java:

@RestController
@SuppressWarnings("rawtypes")
public class DefinitionsController {

    @Autowired
    private RepositoryService mRepositoryService;

    @Autowired
    private RuntimeService mRuntimeService;

    @Autowired
    private TaskService mTaskService;

    @PostMapping("/start-service")
    public String startService(@RequestBody String input) {
        Integer request = Integer.parseInt(input);
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("number", request);

        ProcessInstance instance = mRuntimeService.startProcessInstanceByKey("basicprocess", variables);

        Task userTask = mTaskService.createTaskQuery().processInstanceId(instance.getId()).taskDefinitionKey("getInput").singleResult();
        mTaskService.complete(userTask.getId());

        return "ProcessInstance id is "+instance.getProcessInstanceId();
    }

}

FirstServiceTask.java:

public class FirstServiceTask implements JavaDelegate{

    @Override
    public void execute(DelegateExecution execution) {
        System.err.println("Came in first service task");
    }

}

Same for SecondServiceTask.java except the sysout statement.

REST RESPONSE: I get the processInstance Id and sysout statement of respective service task gets printed in console..

Pretty easy to wire the Service Task classes from xml, however if I were to not use XML, I would need to create the same process using flowable-modeler api of FLOWABLE.

So, basically I want to have control over those service tasks from my java code and in order to do that how do I wire the Service Tasks that are created using flowable-modeler with my java code ?

I have gone through docs, but found the xml way only.


Solution

  • Configuring Service Tasks (created using flowable-modeler) with Java code can be done by the 4 ways shown here.

    The delegate expression which is going to be configured should be either present on the classpath or should have a spring-bean created.

    I created bean using a method in main class, and put the name of method in delegate expressionattribute in flowable-modeler/process api and that's what was needed to do that.

    Attached image should clarify things, which shows the way to wire Service Tasks (created using flowable-modeler API) with Java classes in workspace. enter image description here

    firstServiceTask in highlighted field is the method which returns bean of FirstServiceTask

    EDIT: Apart from above solution, we can also specify class name in class field alone and all configuration is done. Forex: I have a class called TestClass.java in package org.flowable.learning, so I'll just specify org.flowable.learning.TestClass in class field, which is just above highlighted Delegate expression field in attached screenshot