BPM API

Jmix BPM uses the Flowable API, allowing seamless interaction with the process engine within a Spring Boot environment. This simplifies development and enhances the user experience by offering a cohesive BPM framework.

Additionally, Flowable’s standalone REST API enables external systems to interact with the process engine, promoting interoperability and integration into broader application architectures. Understanding the available APIs and extensions empowers developers to harness the full potential of Flowable within the Jmix BPM ecosystem.

Flowable API

You can use Flowable API to interact with the process engine. This API allows you to start process instances programmatically, complete tasks, and execute various queries, for example, get a list of tasks for a user or get active instances of a process definition.

api services

Flowable FormService and IdentityService are not used in Jmix BPM projects.

Flowable services can be obtained in two ways:

  • Using ProcessEngines as a starting point:

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
    RuntimeService runtimeService = processEngine.getRuntimeService();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    TaskService taskService = processEngine.getTaskService();
  • Injecting services inside your beans as they are registered as Spring beans:

    @Component("sample_MyCustomBean")
    public class MyCustomBean {
    
        @Autowired
        private RuntimeService runtimeService;

Jmix BPM API Extension

The Jmix BPM add-on provides BpmTaskService that extends TaskService of Flowable. See an example of the usage below.

Examples

Starting Process Programmatically

In the example below, the process is started programmatically from the regular entity editor using RuntimeService:

@Autowired
private RuntimeService runtimeService;

@Subscribe("commitAndCloseBtn")
public void onCommitAndCloseBtnClick(Button.ClickEvent event) {
    Customer customer = getEditedEntity();
    String name = customer.getName();
    Map<String, Object> params = new HashMap<>();
    params.put("customer", customer); (1)
    params.put("name", name); (2)
    runtimeService.startProcessInstanceByKey( (3)
            "new-customer", (4)
            params); (5)
}
1 Puts the edited entity to the process variable with the customer name.
2 The customer’s name is put to the process variable with a String type.
3 RuntimeService is used to start the process.
4 new-customer is the process definition key.
5 Puts the process variables map.

Getting a List of User Tasks

Let’s look at the examples that show getting a list of active tasks assigned to the authenticated user:

@Autowired
private TaskService taskService;

@Autowired
private CurrentAuthentication currentAuthentication;

public List<Task> getCurrentUserTasks() {
    return taskService.createTaskQuery() (1)
            .processDefinitionKey("approval") (2)
            .taskAssignee(currentAuthentication.getUser().getUsername()) (3)
            .active()
            .orderByTaskCreateTime()
            .desc()
            .list();
}
1 Uses TaskService to get a list of tasks.
2 Searches for the tasks of the approval process.
3 Searches for the tasks assigned to the current user.

Getting List of Process Instances

The example below shows getting a list of process instances of the approval definition related to the specified Order entity:

@Autowired
private RuntimeService runtimeService;

public List<ProcessInstance> getActiveProcessInstances() {
    return runtimeService.createProcessInstanceQuery() (1)
            .processDefinitionKey("approval") (2)
            .variableValueEquals("orderId", "N-1") (3)
            .active()
            .list();
}
1 Uses RuntimeService to get a list of tasks.
2 Searches for the instances of the approval process.
3 Searches for the process instances with the specified orderId process variable.

Using BpmTaskService

BpmTaskService extends the TaskService and adds a method for completing tasks with an outcome:

void completeTaskWithOutcome(String taskId, String outcomeId, Map<String, Object> processVariables);

You can inject the service into your Spring component:

@Autowired
private BpmTaskService bpmTaskService;

or use the ProcessEngines class:

BpmTaskService bpmTaskService = (BpmTaskService) ProcessEngines
        .getDefaultProcessEngine()
        .getTaskService();

Working with Process Definitions via the API

Flowable provides a rich API for interacting with process definitions:

  1. Deployment: Process definitions are typically deployed as part of a deployment unit, which can include multiple definitions and related resources.

    filename.java
    Deployment deployment = repositoryService.createDeployment()
                            .addClasspathResource("my-process.bpmn20.xml")
                            .deploy();
  2. Querying: The RepositoryService allows querying process definitions based on various criteria:

    filename.java
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                                         .processDefinitionId("myProcessDefinitionId")
                                         .singleResult();
  3. Suspension and Activation: Process definitions can be suspended or activated, controlling whether new process instances can be started based on the definition:

    filename.java
    repositoryService.suspendProcessDefinitionById("myProcessDefinitionId");
  4. Diagram Generation: Flowable can generate process diagram images for deployed process definitions:

    filename.java
    InputStream diagramStream = repositoryService.getProcessDiagram(processDefinition.getId());

Setting and Updating a Business Key

Business key can be updated programmatically via API:

runtimeService.updateBusinessKey("processInstanceId", "businessKey");