Exemple Workflow avec un automate
Dans cet exemple nous allons montrer comment utiliser des files d'attente et un automate pour créer un workflow sur un objet métier.
Le workflow réalise les actions suivantes :
- Lorsque un objet est créé ou bien que l'attribut "unCode" est modifié sur la classe WFClasseA un processus est appelé qui modifie la valeur de l'énuméré unEtat de l'objet à "Initial".
- Lorsque la valeur de l'état de l'objet (unEtat) est modifiée un processus est appelé qui modifie la valeur de l'état de l'objet à finale.
Ce workflow est la base des interactions entre Processus métiers et Objets métiers.
Pour ce faire nous utiliserons :
- La classe métier WFClasseA
- Une classe d'évènement métier définit sur $queue1.class.WFClasseA.create_or_change.unCode
- Une classe d'évènement métier définit sur $queue3.class.WFClasseA.change.Etat
- Une classe file d'attente, en l’occurrence la classe des évènements
- Une file d'attente WFCLASSEA_QUEUE1
- Une file d'attente WFCLASSEA_QUEUE3
- Un processus métier définit par la classe MyProcessusWFClasseA
- Un Automate
Définition des classes d'évènements
Les classe d'évènements sont les mêmes que celles utilisées dans un processus métier :
Lorsque les conditions de ces évènements seront remplies le framework créera automatiquement des objets dans la classe des évènements.
Cette classe étant de stéréotype file d'attente ses objets peuvent être consommés par évènements de type file d'attente.
Définition des files d'attente
Le sujet (queueTopic) des objets sera l'identifiant de file des classes d'évènement en l'occurrence "queue1" et "queue3".
Des files d'attente sont donc définies sur ces sujets :
Notez :
- TdbmEvent est la classe des évènements
- queue1 est le sujet de la première classe d'évènements.
La seconde file est définie de façon identique.
Définition de l'Automate
Un automate est utilisé pour consommer les files d'attente :
Notez :
- Les évènements files d'attente définis sur WFCLASSEA_QUEUE1 et WFCLASSEA_QUEUE3
- Un seul automate est utilisé contenant deux lignes.
- Les lignes étant dans l'état 0 elles sont toutes les deux exécutées.
- Chaque tâche de traitement appelle le même processus MyProcessusWFClasseA
Le processus
Le processus d'exécution est le suivant :
unit TestSYFREWF; interface Type MyProcessusWFClasseA = Class(TitObject) public Procedure doSetFinalState(obj:TQueueObject); Procedure doSetInitialState(obj:TQueueObject); Procedure Execute; end; Implementation {MyProcessusWFClasseA} Procedure MyProcessusWFClasseA.doSetFinalState(obj:TQueueObject); //Procedure doSetFinalState(obj:TQueueObject); var inst:WFClasseA; begin // One transaction by object withP transaction do begin // Get the actual object inst := obj.queueRef as WFClasseA; if Assigned(inst) then begin inst.unEtat.value := WFCAState_Final; end; end; end;; Procedure MyProcessusWFClasseA.doSetInitialState(obj:TQueueObject); //Procedure doChangeState(obj:TQueueObject); var inst:WFClasseA; begin // One transaction by object withP transaction do begin // Get the actual object inst := obj.queueRef as WFClasseA; if Assigned(inst) then begin inst.unEtat.value := WFCAState_Initial; end; end; end; Procedure MyProcessusWFClasseA.Execute; //Procedure Execute; var aMsg:TdbmQueueMessage; begin if Assigned(UserContext.TaskContext) then begin UserContext.TaskContext.AddMessage('MyProcessusWFClasseA.Execute'); if Assigned(UserContext.TaskContext.EventContext.receivedMsg) then begin aMsg := UserContext.TaskContext.EventContext.receivedMsg; UserContext.TaskContext.AddMessage(Format('Object :%s',[aMsg.oidqueueRef]]); UserContext.TaskContext.AddMessage(Format('QueueTopic :%s',[aMsg.queueTopic]]); case aMsg.queueTopic of 'queue1': doSetInitialState(aMsg); 'queue3': doSetFinalState(aMsg); end; end; end; end; end.
La méthode "Exceute", exécutée par les tâche d'automate, extrait le message du contexte de tâche de l'automate puis suivant la valeur du sujet du message exécute l'une ou l'autre des actions.
Exécution
Pour tester le workflow on modifie la valeur "unCode" d'un objet de la classe WFClasseA dans l'interface de saisie utilisateur.
On constate l'exécution suivante :
La suite des déclenchements est la suivante :
- La propriété unCode de l'objet métier est mis à jour
- Un objet TdbmEvent queue1 est créé par le framework
- Il est consommé par l'évènement WFCLASSEA_QUEUE1 de l'automate
- Le processus métier est exécuté
- Il exécute doSetInitialState
- doSetInitialState modifie la valeur de unEtat à "Initial"
- Un objet TdbmEvent queue3 est créé par le framework
- Il est consommé par l'évènement WFCLASSEA_QUEUE3 de l'automate
- Le processus métier est exécuté
- Il exécute doSetFinalState
- doSetFinalState modifie la valeur de unEtat à "Final"
- Un objet TdbmEvent queue3 est créé par le framework
- Il est consommé par l'évènement WFCLASSEA_QUEUE3 de l'automate
- Le processus métier est exécuté
- Il exécute doSetFinalState
- doSetFinalState modifie la valeur de unEtat à "Final" mais cette action n'a aucun effet car l'état est déjà "Final"