Pour mon activité professionnelle, je me déplace1 chez les clients afin d’expertiser les solutions qu’ils mettent en place dans leur système d’information et notamment le produit RHPAM2. Pour le compte d’un client donc, j’ai travaillé sur les processus metiers qu’il a mis en place chez lui. Ces processus de type BPMN permettent de gérer des processus de gestion sur lequels nous n’allons pas nous étendre ici. Nous allons juste extraire un patron de conception que j’ai bien aimé de par sa fonctionnalité ainsi que par son interessante implémentation .

Découplage de la réception du signal de son utilisation.

Il est vrai qu’en anglais cela rendrait plutôt “Decoupling Signal Reception”.

Rappel des processus BPMN

Les Processus BPMN permettent de décrire des processus métier de haut niveau sous la forme de graphique standardisés par Object Management Group (OMG) specification. Ces processus métiers facilitent la communication car ils peuvent être écrits par les métiers via des outils de design de type NoCode et deployés sans changement par les intégrateurs sur des moteurs prévus à cet effet. Le standard BPMN normalise les processus métiers avec des concepts largements éprouvés au fil du temps (notion de timer, de signaux, de message, d’appel, etc…).

Les signaux dans BPMN

Les signaux dans le standard BPMN servent à communiquer des événements métiers aux processus. Les processus peuvent être à la fois émetteur ou récepteur des événements de type signal. En fonction des besoins, les processus communiquent les uns avec les autres sur la base de signaux. Les signaux peuvent être éxogènes au système BPM.

Nomeclature

  • Voici le noeud pour démarrer une instance de processus après avoir recu un message.

Signal Start event

  • Pour écouter puis continuer l’éxecution d’une instance de processus après avoir recu le bon signal, on utilisera ce noeud.

Signal Catching Event

Warning

Ce noeud est bloquant, l’instance de processus est en attente de la réception du signal.

  • L’envoi d’un signal en cours de traitement est possible avec le noeud suivant.

Signal Throwing Event

  • Et enfin le noeud permettant de finir une instance de processus tout en envoyant un signal.

Signal End Event

Dans tous les cas, il est nécessaire de donner un nom de signal. Ce nom doit être le plus parlant possible tout en évitant d’être trop technique.

  • RELANCE_CLIENT
  • NOTIFICATION_FOURNISSEUR
  • ERREUR_PROCEDURE

Info

Avec jBPM/RHPAM, les noms des signaux peuvent être variabilisés comme ceci : ALERTE_#{ID_CLIENT}

Scope des Signaux

En fonction du fournisseur BPM, le scope d’émission du message peut être modulé. Le scope correspond à la portée du signal qui peut être envoyé plus ou moins loin.

  • Instance de processus
    • Le signal est envoyé au niveau d’instance de processus
  • Model de processus
    • Le signal est envoyé au niveau de la définition du model du processus courant
  • Project/déploiement
    • Le signal est envoyé à un ensemble des processus d’un ou plusieurs projets techniques.
  • Global
    • Le signal est envoyé à tous les processus du moteur
  • Externe
    • Le signal est diffusé plus largement à l’exterieur de l’instance du moteur de processus.

Mal définir le scope peut avoir un impact sur les performances en fonction des moteurs, car plus ou moins d’instances de processus peuvent réceptionner le signal.

Warning

Les scopes ne sont pas forcement tous implémentés dans les solutions.

Interaction

Les différentes implémentations des moteurs BPM fournissent des interfaces afin de dialoguer via des signaux aux instances de processus.

  • IHM
    • Le logiciel fourni une interface graphique (web, desktop) afin d’émettre le signal à un ou plusieurs processus.
  • API REST
    • Une API REST (ou SOAP) est proposée et permet d’interagir via un appel REST/HTTP/JMS3 au moteur de processus.
  • API code
    • Selon le logiciel BPM, celui-ci est muni d’une (ou plusieurs) librairie(s)4 technique.

Voici un tutorial (en anglais) d’un de mes collègue Donato Marrazzo présentant l’utilisation des signaux avec jBPM/RHPAM

Découplage de signaux

Lors de l’activation d’un signal “Signal Step”, le processus va se mettre en “écoute” pour réceptionner le signal. Il se peut que le signal, pour des besoins métiers, soit lancé (bien) avant l’activation du noeud signal, donc le processus peut manquer la réception du signal, le signal sera donc perdu et le processus restera toujours bloqué. Il est bien sur possible d’avoir une branche incluant un délai afin de créer un branche de sortie et donc débloquer le processus. Mais en toute logique, le branche de délestage ne sera pas la branche nominale.

Mais quant est-il si l’on souhaite tout de même recevoir le signal à n’importe quel moment5, notamment si les actions avant la réception du signal sont longues “Long running Sub-Process”, et tout de même réagir à l’événement signal.

Signal Catching Event

Car comme nous l’avons vu précedement, la réception du signal sera possible dès que le moteur BPM arrivera sur le noeud “Catching Signal”, pas avant. Il nous faut donc essayer de trouver un nouveau pattern afin de découpler la récepetion du signal.

Sous-Processus

Pour cela nous allons créer un sous-processus attenant au processus principal. L’idée principale de ce sous-processus se mettre ne écoute de l’évenement signal même si on ne va pas utiliser cette information tout de suite dans le pocessus principal.

Avec ce sous processus nous allons simplement recevoir le signal via le noeud “Signal Start Event”, à n’importe quel moment du cycle de vie du processus.

Le deuxième noeud “Script Node” va stocker l’événement signal dans la session Drools. et comme la session Drools est difficilement auditable nous copions aussi l’événement dans une variable de processus 6.

// Fact insertion into Drools Session
kcontext.getKieRuntime().insert("SUB_PROCESS_SIGNAL");

// Coping variable of the signal event into process variables 
kcontext.setVariable("SubProcessSignalFlag", "Received");

Drools est le moteur de règle intégré à jBPM. Il fourni à la fois un langage de programmation pour concevoir des règles métiers et un moteur inférence qui réagi automatique à chaque changement de contexte. Ici notre contexte sera la session Drools de l’instance de processus dans laquelle on insere une nouvel objet 7.

Ensuite, on termine simplement le sous-processus et on rend la main.

Avec ce sous-processus de réception de signal, nous stocker dans la session (Drools) et/ou une variable de processus. L’évenement signal est bien sauvegrader dans l’instance de processus. Il va falloir maintenant exploiter cet information disponible dans les infos du processus.

Branche de traitement

Afin d’exploiter l’événement signal stocké dans les infos de l’instance de processus, nous allons modifier notre processus. Voici maintenant le mécanisme d’utilisation de l’événement signal.

Nous remplacons l’attende du signal par une condition particulière. Cette condition, dans notre cas, est stockée dans la session Drools.

Le noeud “Drools Step” configure le “Conditinal Event” sous la forme d’une règle Drools. Ici, ce noeud vérifie la présence de l’objet String dans la session, cette chaîne de caratère devra être égale à “SUB_PROCESS_SIGNAL” pour valider la condition.

La session Drools, mise à jour via le sous-processus de réception du signal, est utilisée quand il le faut par l’instance de processus. L’avantage de l’utilisation du conditionnal event est qu’il peut être rafraichi à tout moment si la session change, donc la session peut être mise à jour avant ou pendant l’activation du noeud et donc faire avancer l’instance de processus comme il se doit.

Final

Voici donc, le schéma complet du processus implémentant le pattern que nous venont de voir. Ce schéma générique ne gère pour l’instant un signal et un type de condition, mais il est tout à fait possible d’avoir une implémentation plus complexe en fonction du besoin métier (plusieurs signaux, plusieurs variables, plusieurs conditions).

Warning

Ce pattern possède néammoins le défaut de perdre la signification, dans la branche de traitement, de la source du “Conditinal Event”. En effet, le signal est réceptionné dans un sous-processus dédié, il est donc important de bien documenter l’élément déclancheur du “Conditinal Event”.

Conclusion

Ce pattern permet de répondre au besoin de découplage de la réception du signal de son utilisation plus tard dans le processus. Il n’y a plus besoin donc de bloquer le processus principal sur le signal et donc il est possible d’effectuer des traitements relativement long tout en continuant à utiliser les signaux. Cela apporte plus de flexibilité dans le design de conception des processus sans trop perdre dans lisibilité des modèles.

Remerciements

  • Un grand remerciement à T. B., mon contact client qui se reconnaitra.
  • À Rachid Snoussi pour la relecture.
  • Thx Donato Marrazzo for your tutorial.

Footnotes


  1. Sur site ou bien à distance depuis mars 2020 :-(. ↩︎

  2. RHPAM est un produit Red Hat, jBPM est le projet communautaire à la base de RHPAM. ↩︎

  3. peut dépendre du fournisseur ↩︎

  4. pour différents langages de programmation Java, C/C++, Python, JS etc… ↩︎

  5. pendant la durée du processus uniquement. ↩︎

  6. On peut bien entendu utiliser les fonctions de “Data Assignments” pour le stockage de l’événement signal dans la table d’audit (activer le mécanisme d’audit de jBPM) ou bien les listeners afin de tracer le signal via un code spécifique. ↩︎

  7. Objet plus ou moins complexe. ↩︎