Introduction à Flowable

1. Vue d'ensemble

Flowable est un moteur de processus métier écrit en Java. Dans ce didacticiel, nous allons passer en revue les détails des processus métier et comprendre comment nous pouvons tirer parti de l'API Flowable Java pour créer et déployer un exemple de processus métier.

2. Comprendre les processus métier

En termes simples, un processus métier est un ensemble de tâches qui, une fois accomplies dans un ordre défini, accomplissent un objectif défini . Chaque tâche d'un processus métier a des entrées et des sorties clairement définies. Ces tâches peuvent nécessiter une intervention humaine ou peuvent être complètement automatisées.

OMG (Object Management Group) a défini un standard appelé Business Process Model and Notation (BPMN) pour que les entreprises définissent et communiquent leurs processus . Le BPMN est devenu largement soutenu et accepté dans l'industrie. L'API Flowable prend entièrement en charge la création et le déploiement de définitions de processus BPMN 2.0.

3. Création de définitions de processus

Supposons que nous ayons un processus simple de révision d'article avant la publication.

L'essentiel de ce processus est que les auteurs soumettent un article et que les éditeurs l'acceptent ou le rejettent. S'il est accepté, l'article est publié immédiatement; cependant, s'il est rejeté, l'auteur est averti par e-mail:

Nous créons des définitions de processus sous forme de fichiers XML à l'aide du standard XML BPMN 2.0.

Définissons notre processus simple selon la norme BPMN 2.0:

Maintenant, il y a un certain nombre d'éléments ici qui sont des éléments XML standard, tandis que d'autres sont spécifiques à BPMN 2.0:

  • L' ensemble du processus est entouré d'une balise appelée "processus", qui à son tour fait partie d'une balise appelée "définitions"
  • Un processus se compose d'événements, de flux, de tâches et de passerelles
  • Un événement est soit un événement de début, soit un événement de fin
  • Un flux (dans cet exemple, un flux de séquence) connecte d'autres éléments tels que des événements et des tâches
  • Les tâches sont l'endroit où le travail réel est effectué; il peut s'agir de «tâches utilisateur» ou de «tâches de service», entre autres
  • Une tâche utilisateur nécessite qu'un utilisateur humain interagisse avec l'API Flowable et agisse
  • Une tâche de service représente une tâche automatique, qui peut être un appel à une classe Java ou même un appel HTTP
  • Une passerelle s'exécute en fonction de l'attribut «approuvé»; c'est ce qu'on appelle une variable de processus , et nous verrons comment les définir plus tard

Bien que nous puissions créer des fichiers de définition de processus dans n'importe quel éditeur de texte, ce n'est pas toujours le moyen le plus pratique. Heureusement, cependant, Flowable est également livré avec des options d'interface utilisateur pour ce faire à l'aide d'un plugin Eclipse ou d'une application Web. Si vous utilisez plutôt IntelliJ, un plugin IntelliJ est également disponible.

4. Travailler avec l'API Flowable

Maintenant que nous avons défini notre processus simple dans un fichier XML selon la norme BPMN 2.0, nous avons besoin d'un moyen de le soumettre et de l'exécuter. Flowable fournit l'API Process Engine pour interagir avec Flowable Engines . Flowable est très flexible et propose plusieurs façons de déployer cette API.

Étant donné que Flowable est une API Java, nous pouvons inclure le moteur de processus dans n'importe quelle application Java en incluant simplement les fichiers JAR requis. Nous pouvons très bien tirer parti de Maven pour gérer ces dépendances.

De plus, Flowable est livré avec des API groupées pour interagir avec Flowable sur HTTP. Nous pouvons utiliser ces API pour faire à peu près tout ce qui est possible via l'API Flowable.

Enfin, Flowable offre un excellent support pour l'intégration avec Spring et Spring Boot! Nous utiliserons l'intégration Flowable et Spring Boot dans notre tutoriel.

5. Création d'une application de démonstration avec Process Engine

Créons maintenant une application simple qui enveloppe un moteur de processus de Flowable et offre une API basée sur HTTP pour interagir avec l'API Flowable. Il peut également y avoir une application Web ou mobile au-dessus de l'API pour améliorer l'expérience, mais nous allons sauter pour cela pour ce didacticiel.

Nous allons créer notre démo en tant qu'application Spring Boot.

5.1. Dépendances

Voyons d'abord les dépendances que nous devons extraire de Maven:

 org.springframework.boot spring-boot-starter-web   org.flowable flowable-spring-boot-starter 6.4.1   com.h2database h2 runtime 

Les dépendances dont nous avons besoin sont toutes disponibles chez Maven Central:

  • Spring Boot Starter for Web - il s'agit d'un démarreur standard pour Spring Boot
  • Démarreur fluide pour Spring Boot - Ceci est requis pour les moteurs fluides Spring Boot
  • Base de données H2 - Flowable nécessite une base de données pour stocker les données, et H2 est la base de données en mémoire par défaut

5.2. Définition du processus

Lorsque nous démarrons notre application Spring Boot, elle essaie de charger automatiquement toutes les définitions de processus présentes dans le dossier «ressources / processus». Par conséquent, créons un fichier XML avec la définition de processus que nous avons créée ci-dessus, avec le nom «article-workflow.bpmn20.xml», et placez-le dans ce dossier.

5.3. Configurations

Comme nous savons que Spring Boot adopte une approche très avisée de la configuration des applications, cela vaut également pour Flowable dans le cadre de Spring Boot. Par exemple, en détectant H2 comme le seul pilote de base de données sur le chemin de classe, Flowable le configure automatiquement pour son utilisation .

Évidemment, chaque aspect configurable peut être configuré de manière personnalisée via les propriétés de l'application. Pour ce tutoriel, cependant, nous nous en tiendrons aux valeurs par défaut!

5.4. Délégués Java

In our process definition, we've used a couple of Java classes that are supposed to be invoked as parts of service tasks. These classes implement the JavaDelegate interface and are known as Java Delegates in Flowable. We'll now define dummy classes for these Java Delegates:

public class PublishArticleService implements JavaDelegate { public void execute(DelegateExecution execution) { System.out.println("Publishing the approved article."); } }
public class SendMailService implements JavaDelegate { public void execute(DelegateExecution execution) { System.out.println("Sending rejection mail to author."); } }

Obviously, we must replace these dummy classes with actual services to publish an article or send an email.

5.5. HTTP APIs

Finally, let's create some endpoints to interact with the process engine and work with the process we've defined.

We'll begin by defining a controller exposing three endpoints:

@RestController public class ArticleWorkflowController { @Autowired private ArticleWorkflowService service; @PostMapping("/submit") public void submit(@RequestBody Article article) { service.startProcess(article); } @GetMapping("/tasks") public List getTasks(@RequestParam String assignee) { return service.getTasks(assignee); } @PostMapping("/review") public void review(@RequestBody Approval approval) { service.submitReview(approval); } }

Our controller exposes endpoints to submit an article for review, fetch a list of articles to review, and finally, to submit a review for an article. Article and Approval are standard POJOs that can be found in the repository.

We are actually delegating most of the work to ArticleWorkflowService:

@Service public class ArticleWorkflowService { @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Transactional public void startProcess(Article article) { Map variables = new HashMap(); variables.put("author", article.getAuthor()); variables.put("url", article.getUrl()); runtimeService.startProcessInstanceByKey("articleReview", variables); } @Transactional public List getTasks(String assignee) { List tasks = taskService.createTaskQuery() .taskCandidateGroup(assignee) .list(); return tasks.stream() .map(task -> { Map variables = taskService.getVariables(task.getId()); return new Article(task.getId(), (String) variables.get("author"), (String) variables.get("url")); }) .collect(Collectors.toList()); } @Transactional public void submitReview(Approval approval) { Map variables = new HashMap(); variables.put("approved", approval.isStatus()); taskService.complete(approval.getId(), variables); } }

Now, most of the code here is pretty intuitive, but let's understand the salient points:

  • RuntimeService to instantiate the process for a particular submission
  • TaskService to query and update tasks
  • Wrapping all database calls in transactions supported by Spring
  • Storing details like author and URL, among others, in a Map, and saving with the process instance; these are known as process variables, and we can access them within a process definition, as we saw earlier

Now, we're ready to test our application and process engine. Once we start the application, we can simply use curl or any REST client like Postman to interact with the endpoints we've created.

6. Unit Testing Processes

Flowable supports different versions of JUnit, including JUnit 5, for creating unit tests for business processes. Flowable integration with Spring has suitable support for this as well. Let's see a typical unit test for a process in Spring:

@ExtendWith(FlowableSpringExtension.class) @ExtendWith(SpringExtension.class) public class ArticleWorkflowUnitTest { @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Test @Deployment(resources = { "processes/article-workflow.bpmn20.xml" }) void articleApprovalTest() { Map variables = new HashMap(); variables.put("author", "[email protected]"); variables.put("url", "//baeldung.com/dummy"); runtimeService.startProcessInstanceByKey("articleReview", variables); Task task = taskService.createTaskQuery().singleResult(); assertEquals("Review the submitted tutorial", task.getName()); variables.put("approved", true); taskService.complete(task.getId(), variables); assertEquals(0, runtimeService.createProcessInstanceQuery().count()); } }

This should pretty much look like a standard unit test in Spring, except for few annotations like @Deployment. Now, the @Deployment annotation is provided by Flowable to create and delete a process deployment around test methods.

7. Understanding the Deployment of Processes

While we'll not cover the details of process deployment in this tutorial, it is worthwhile to cover some aspects that are of importance.

Typically, processes are archived as Business Archive (BAR) and deployed in an application. While being deployed, this archive is scanned for artifacts — like process definitions — and processed. You may have noticed the convention of the process definition file ending with “.bpmn20.xml”.

While we've used the default in-memory H2 database in our tutorial, this actually cannot be used in a real-world application, for the simple reason that an in-memory database will not retain any data across start-ups and is practically impossible to use in a clustered environment! Hence, we must use a production-grade relational database and provide the required configurations in the application.

While BPMN 2.0 itself does not have any notion of versioning, Flowable creates a version attribute for the process, which is deployed in the database. If an updated version of the same process, as identified by the attribute “id”, is deployed, a new entry is created with the version being incremented. When we try to start a process by “id”, the process engine fetches the latest version of the process definition deployed.

If we use one of the designers we discussed earlier to create the process definition, we already have a visualization for our process. We can export the process diagram as an image and place it alongside the XML process definition file. If we stick to the standard naming convention suggested by Flowable, this image will be processed by the process engine along with the process itself. Moreover, we can fetch this image through APIs as well!

8. Browsing History of Process Instances

It is often of key importance in the case of business processes to understand what happened in the past. We may need this for simple debugging or complex legal auditing purposes.

Flowable records what happens through the process execution and keeps it in the database. Moreover, Flowable makes this history available through APIs to query and analyze. There are six entities under which Flowable records these, and the HistoryService has methods to query them all.

Let's see a simple query to fetch finished process instances:

HistoryService historyService = processEngine.getHistoryService(); List activities = historyService .createHistoricActivityInstanceQuery() .processInstanceId(processInstance.getId()) .finished() .orderByHistoricActivityInstanceEndTime() .asc() .list();

As we can see, the API to query recorded data is pretty composable. In this example, we're querying finished process instances by ID and ordering them in ascending order of their end time.

9. Monitoring Processes

Monitoring is a key aspect of any business-critical application, and even more so for an application handling business processes of an organization. Flowable has several options to let us monitor processes in real time.

Flowable provides specific MBeans that we can access over JMX, to not only gather data for monitoring but to perform many other activities as well. We can integrate this with any standard JMX client, including jconsole, which is present alongside standard Java distributions.

Using JMX for monitoring opens a lot of options but is relatively complex and time-consuming. However, since we're using Spring Boot, we're in luck!

Spring Boot offers Actuator Endpoints to gather application metrics over HTTP. We can seamlessly integrate this with a tool stack like Prometheus and Grafana to create a production-grade monitoring tool with minimal effort.

Flowable provides an additional Actuator Endpoint exposing information about the running processes. This is not as good as gathering information through JMX, but it is quick, easy and, most of all, sufficient.

10. Conclusion

In this tutorial, we discussed business processes and how to define them in the BPMN 2.0 standard. Then, we discussed the capabilities of Flowable process engine and APIs to deploy and execute processes. We saw how to integrate this in a Java application, specifically in Spring Boot.

En continuant, nous avons discuté d'autres aspects importants des processus tels que leur déploiement, leur visualisation et leur surveillance. Inutile de dire que nous venons de gratter la surface du processus métier et un moteur puissant comme Flowable. Flowable a une API très riche avec une documentation suffisante disponible. Ce tutoriel aurait cependant dû piquer notre intérêt pour le sujet!

Comme toujours, le code des exemples est disponible à l'adresse over sur GitHub.