Le développement de BPM n'est pas facile. Cela est dû au fait que le processus doit être lisible et compréhensible pour le client, et non seulement correct d'un point de vue technique.
Tous les outils de développement de processus métier ne permettent pas de trouver un compromis entre une description claire et une fonctionnalité technique. De nombreux outils de développement avancés et descriptions de processus ont souvent un autre inconvénient: ils sont si cool, puissants et complexes que, pendant leur fabrication, les technologies ont fait un grand pas en avant et le développement avec un tel outil est devenu sans objet.
2018 a fondamentalement changé notre approche du développement des processus métiers. Vous trouverez ci-dessous comment cette approche a évolué et comment nous avons changé.
Au lieu d'un prologue
Notre département est engagé dans le développement de processus d'affaires - du plus petit au plus petit, au grand et extrêmement rentable. Jusqu'à récemment, nous utilisions un produit IBM pour le développement, ce qui nous permet de lancer rapidement un processus opérationnel en production.
IBM BPM est une plate-forme puissante qui comprend un riche ensemble de fonctionnalités, telles qu'une description des processus eux-mêmes, des formulaires d'interface utilisateur et des modules d'intégration. De plus, cette plateforme a un seuil d'entrée assez bas, ce qui permet aux développeurs novices de s'immerger immédiatement dans le projet. Mais ce produit présente également des inconvénients qui, s'ils n'entravent pas le développement, ne contribuent certainement pas à la rapidité et à la qualité:
- Il n'y a aucun contrôle de version sain. IBM BPM ne permet tout simplement pas de stocker correctement les processus (code) dans le référentiel et utilise son propre référentiel, qui ne connaît pas un concept tel que la fusion, par exemple.
- Développer en Java 6. Peut-être qu'au moment d'écrire ces lignes, il était déjà possible de développer en Java 7, mais en 2019 c'est un peu de confort.
- IBM BPM tourne sur WebSphere, par conséquent, les développeurs doivent être patients avec chaque mise à jour de leur module. De plus, c'est un casse-tête supplémentaire pour les administrateurs qui doivent périodiquement ramener ce monstre à la vie s'il se bloque.
- Le développement de modules d'intégration dans l'environnement d'Integration Designer, qui en fait n'est pas obscurci pour le mieux Eclipse.
- Il n'y a pas de capacité de test unitaire normale.
- Le coût élevé de la plateforme.
Ces lacunes, outre les inconvénients purement techniques du développement, ont créé un autre problème, qui est peut-être beaucoup plus grave que tout ce qui précède. À l'époque de Java 12, Kotlin, des microservices et autres tendances et pièces de mode, toutes ces nuances démotivent très l'équipe. Il est difficile de ressentir la joie de développer dans le concepteur d'intégration toujours en suspens pour Java 6 en 2019.

Avec toutes ces limitations, il est difficile de rester à flot. Il y a un peu moins d'un an, il y avait une offre pour essayer le moteur Camunda pour décrire les processus d'affaires. Pour commencer, un processus d'enregistrement des terminaux pour les personnes morales pas très important, mais plutôt important a été sélectionné.
Puisque nous l'avons complètement réécrit, il n'y avait presque plus de vieux code, nous ne pouvions pratiquement pas nous limiter à quoi que ce soit, et nous avons donc choisi Kotlin comme langage de développement. Il était intéressant d'essayer cette nouvelle langue, qui a surtout été entendue pour des critiques positives. Certains autres projets de notre département ont connu une expérience de mise en œuvre réussie. La pile finale s'est révélée comme suit: Camunda, Spring Boot 2, Kotlin, Postgre.
Qu'est-ce que Camunda?

Camunda est une plate-forme de modélisation de processus métier open source écrite en Java et utilisant Java comme langage de développement. Il s'agit d'un ensemble de bibliothèques qui vous permettent d'effectuer les processus décrits. Pour intégrer Camunda dans un projet, ajoutez simplement quelques dépendances. Pour stocker des processus, vous pouvez choisir un SGBD en mémoire ou persistant - selon les tâches. Nous avons choisi Postgre, car l'histoire est importante pour nous pour le «débriefing». Par défaut, la plateforme se déploie sur H2.
Le développement se compose de deux parties: la création d'un processus de flux dans un utilitaire spécial Camunda Modeler et l'écriture de code java qui traite les étapes de processus décrites dans le diagramme. Pour appeler le code java à partir du processus, il suffit d'implémenter l'interface JavaDelegate, de lever ce bean (vous pouvez spécifier delagate par le nom complet, mais via le bean c'est plus pratique et flexible) dans le contexte et de spécifier son id à l'étape de processus souhaitée. Chez Kotlin, le délégué semble encore plus succinct. La logique des délégués est assez simple: ils ont soustrait quelque chose du contexte, ont effectué certaines actions et l'ont remis en contexte.
Fenêtre contextuelle de Camunda ModelerExemple de délégué Java:
import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.engine.delegate.JavaDelegate; public class JavaExampleDelegate implements JavaDelegate { @Override public void execute(DelegateExecution execution) { String someVar = (String) execution.getVariable("someVariable");
Exemple de délégué Kotlin:
import org.camunda.bpm.engine.delegate.DelegateExecution import org.camunda.bpm.engine.delegate.JavaDelegate class KotlinExampleDelegate: JavaDelegate { override fun execute(execution: DelegateExecution) { val someVar = execution.getVariable("someVariable")
Dans le délégué, vous pouvez décrire la logique métier, l'intégration et tout ce que votre cœur désire.
Nous essayons de créer une couche sous la forme d'un composant métier avec logique, et n'utilisons le délégué que comme lien vers le flux du processus, afin de mélanger le moins possible le code et le processus.
Dans la plupart des cas, cette approche est pratique et fonctionne avec succès. L'interaction avec le processus se produit via DelegateExecution, qui permet, par exemple, de travailler avec le contexte, les incidents, etc.
Est-ce ce que nous voulions?
Au tout début, lors du choix d'un outil, nous recherchions une solution avec les fonctionnalités suivantes:
- Récupération du processus exactement à l'endroit où la panne s'est produite, et il est souhaitable qu'il soit sorti de la boîte.
- Une interface graphique où vous pouvez voir ce qui arrive au processus en général.
- La possibilité d'écrire des tests unitaires non seulement pour la logique et l'intégration, mais aussi pour le processus lui-même.
- Java 8 et supérieur.
- Communauté développée.
Camunda est très bien avec la récupération et l'analyse des erreurs.
Une trace bien lisible, la possibilité de définir le nombre de tentatives pour faire un pas avant de tomber, un gestionnaire personnalisé lors de la chute - par exemple, si pendant une chute, nous voulons changer le statut d'une entité en Erreur. Ce dernier est facile à faire simplement en implémentant DefaultIncidentHandler. Certes, il y a un moment amusant où ce gestionnaire fonctionne: le code de récupération d'erreur est déclenché chaque fois que vous entrez dans l'étape de processus. Je ne peux pas dire que c'est une superbactérie ou un problème. Au lieu de cela, vous avez juste besoin de vous en souvenir et d'en tenir compte lors du développement.
Nous l'avons résolu comme ceci:
override fun resolveIncident(context: IncidentContext) { val incidentList = Context.getCommandContext().incidentManager.findIncidentByConfiguration(context.configuration) if (incidentList.isNotEmpty()) {
Camunda a une interface graphique et ce n'est pas mal.
Mais si vous voulez un peu plus, par exemple, la migration des instances entre les versions de processus, alors vous devrez travailler dur. L'interface utilisateur par défaut n'a que des fonctionnalités minimales, mais il existe une API Rest très puissante qui vous permet de créer votre propre panneau d'administration - cool et sophistiqué.
C'est sur le chemin de notre panneau d'administration que nous sommes allés. Notre architecte de processus métier en un laps de temps assez court l'a compris, y compris les fonctions de visualisation de l'historique des processus déjà terminés, de migration entre les versions, etc.
Camunda's Rest est vraiment puissant et vous permet de faire à peu près n'importe quoi avec les processus. Par exemple, vous pouvez démarrer un processus en utilisant
/ process-definition / key / aProcessDefinitionKey / start avec une requête aussi simple:
{ "variables": { "aVariable" : { "value" : "aStringValue", "type": "String" }, "anotherVariable" : { "value" : true, "type": "Boolean" } }, "businessKey" : "myBusinessKey" }
L'exemple est tiré de la documentation officielle, qui contient une description détaillée des différents cas d'utilisation de cette API.
Pour les tests unitaires, nous utilisons le Junit habituel. De plus, il existe une bibliothèque assez intéressante pour tester le processus lui-même - 'org.camunda.bpm.extension', nom: 'camunda-bpm-assert'. Avec lui, vous pouvez décrire des tests pour vérifier le processus de flux.
C'est assez pratique, car il est souvent plus difficile de rechercher des problèmes de bogues dans le flux que dans le code. De tels tests protègent, par exemple, d'une refactorisation inexacte et nous ont vraiment aidés plusieurs fois.
Le besoin de Java 8 a partiellement disparu, car l'utilisation de Kotlin sur de nombreux processus a éliminé le besoin du G8. Kotlin s'intègre très bien au projet et vous permet de vous concentrer uniquement sur l'écriture de la logique métier. C'est difficile à croire, mais fondamentalement tout ce que Kotlin dit sur la fraîcheur est vrai. Les entités avec un grand nombre de champs, qui sont connues pour presque toutes les applications avec intégrations, ne semblent plus aussi effrayantes et les correspondances entre entités sont devenues beaucoup plus lisibles. Souvent critiqué, la sécurité nulle fonctionne vraiment et aide dans la plupart des cas.
La communauté de Camunda est assez développée. Cela est démontré par le fait que de nouvelles bibliothèques sur GitHub apparaissent constamment pour les tests et les métriques.
C'est bien que Camunda s'intègre parfaitement avec Spring. Ajoutez les dépendances nécessaires, quelques annotations et quelques beans de configuration - en fait, c'est toute l'intégration! En conséquence, nous écrivons une application régulière au printemps à laquelle tout le monde est habitué, ajoutant le flux d'un processus métier. L'interaction se fait via l'API Java, qui vous permet de manipuler les processus à partir du code java.
Par exemple, vous pouvez démarrer le processus avec une seule commande:
runtimeService.startProcessInstanceByKey( "MyTestProcess", "MyBusinessKey", mapOf( "key1" to "value1", "key2" to "value2", ) )
Ici, MyTestProcess est l'id-shnik du processus, pas l'instance. MyBusinessKey est une clé unique pour une instance de processus en cours d'exécution. Nous utilisons généralement une certaine valeur commerciale pour ce champ - pour une navigation plus rapide entre les instances et la recherche.
De la même manière, vous pouvez réveiller un processus «endormi».
Les inconvénients notables ou les problèmes que nous avons rencontrés, en particulier, ne peuvent pas être rappelés. En conséquence, pendant une période assez courte, il s'est avéré être un processus complètement fonctionnel et le mettre en production en toute sécurité. D'autres processus sont en cours d'implémentation sur la plate-forme et avec succès. Maintenant, sur Camunda, nous avons lancé environ 15 applications sur lesquelles environ 100 000 processus tournent à la fois.

Au lieu d'un épilogue
Voici quelques ressources qui ont été utiles pour implémenter la pile décrite ci-dessus. Je vous recommande de les lire si vous êtes intéressé par des informations supplémentaires sur le sujet.