Automatiser la transformation des flux synchrones BPEL en flux asynchrones avec ANT
Les flux BPEL se décomposent en deux catégories, les flux synchrones et les flux asynchrones. Tandis que les flux synchrones permettent aux applications d’échanger directement des messages, les flux asynchrones eux ont tendance à découpler les applications les unes des autres, les appels sont non-bloquants. Au cours d’un projet, on est amené à gérer des évolutions, et pour diverses raisons les besoins peuvent changer et c’est pourquoi on peut être amené à transformer un flux synchrone en un flux asynchrone et inversement. Ces évolutions peuvent affecter tout ou partie des flux déjà réalisés, un processus d’automatisation de ce type de transformation devient alors intéressant car il permet non seulement de gagner du temps mais également de garantir qu’aucune faute ne sera commise. Ce post à double intérêt vous permettra de pouvoir aisément changer le mode (synchrone / asynchrone) d’un flux BPEL mais également d’acquérir quelques notions de base sur les scripts ANT et leur mise en œuvre.
Ci-dessous, vous trouverez la démarche à suivre afin de passer un processus en mode synchrone vers un processus en mode asynchrone. Les modifications à effectuer sont toujours les mêmes puisqu’il s’agit d’ajouter et supprimer certains blocs XML dans les fichiers WSDL et BPEL. cet article se base sur la transformation synchrone vers asynchrone, l’opération inverse est tout à fait symétrique.
Résumé des tâches à effectuer
Modification du WSDL
- Ajouter un bloc portType correpondant au callback avec une opération ‘onResult’ :
<portType name="BPELProcessCallback">
<operation>
<input message="client: BPELProcessResponseMessage"/>
</operation>
</portType>
- Supprimer le message d’output sur l’opération process, en effet, on passe en asynchrone, on n’attend donc plus de retour. Il faut également modifier le nom de l’opération et passer de process à initiate :
<portType name="BPELProcess">
<operation>
<input message="client: BPELProcessRequestMessage"/>
</operation>
</portType>
- Ajouter un bloc role dans le bloc partnerLinkType, ce nouveau bloc correspond au portType que l’on vient d’ajouter :
<plnk:partnerLinkType name="BPELProcess">
<plnk:role name="BPELProcessProvider">
<plnk:portType/>
</plnk:role>
<plnk:role name="BPELProcessRequester">
<plnk:portType/>
</plnk:role>
</plnk:partnerLinkType>
Modification du BPEL
- Modifier le partnerLink ‘client’ en ajoutant un attribut partnerRole ayant pour valeur ‘BPELProcessRequester’, c’est-à-dire le role qu’on ajouté dans le WSDL.
<partnerLink myRole="BPELProcessProvider"
partnerLinkType="client: BPELProcess"
partnerRole="BPELProcessRequester"/>
- Remplacer le nom de l’opération dans le bloc receive en entrée de flux :
<receive createInstance="yes" name="receiveInput" operation="initiate"
partnerLink="client" portType="client:SynchToAsynch_BPEL"
variable="inputVariable"/>
- Remplacer le bloc reply en sortie de flux par un bloc invoke avec les bonnes valeurs d’attributs (opération ‘onResult’ que l’on a créée dans le WSDL):
<invoke inputVariable="outputVariable"
operation="onResult" partnerLink="client"
portType="client: BPELProcessCallback"/>
Notes : Une fois le flux redéployé, vider le cache WSDL via la console BPEL (Administration / Actions). En effet, il se peut que vous ayiez une erreur à l’exécution stipulant que l’opération initiate n’est pas disponible au niveau du WSDL, cette erreur se produit car le moteur BPEL s’appuie sur l’ancien WSDL qui est resté dans le cache.
Conclusion
Une fois toutes ces tâches réalisées, il reste à compiler le processus et le redéployer pour valider et rendre les modifications effectives. Il s’agit d’une tâche fastidieuse et qui peut mener à diverses erreurs, et comme mentionné plus haut, les modifications à apporter sont tout le temps les mêmes, ainsi ce processus peut facilement être rendu automatiques, notamment via un script ANT.
Automatisation via ANT
ANT permet, entre autre, de modifier de façon automatique les fichiers XML. Dans ce qui suit, ANT est utilisé pour automatiser les transformations des fichiers BPEL et WSDL et passer des flux synchrones en flux asynchrones. Vous trouverez donc ci-dessous comment utiliser des librairies XmlTask et CustomizeDocument pour réaliser cette opération ; il existe plusieurs façons pour construire ce script, il s’agit d’une solution parmi d’autres.
Ajout de librairies
Deux librairies sont nécessaires pour l’opération décrite:
- XmlTask : va permettre d’ajouter des blocs dans la structure XML (copier, coller, etc.)
- CustomizeDocument : va permettre de modifier des valeurs d’attributs au sein d’un fichier XML.
Il ne faut donc pas oublier de récupérer les jar de ces deux librairies : xmltask-v1.15.1.jar et customtasks.jar.
Par ailleurs, dans vote script ANT de passage d’un flux synchrone à un flux asynchrone, il vous faudra importer ces jar :
<taskdef classname="com.oopsconsultancy.xmltask.ant.XmlTask">
<classpath>
<pathelement path="${process.dir}/AntExport/xmltask-v1.15.1.jar"/>
</classpath>
</taskdef>
<taskdef name="customizeDocument"
classname="com.collaxa.cube.ant.taskdefs.customize.document.CustomizeDocument">
<classpath>
<pathelement path="${process.dir}/customtasks.jar"/>
</classpath>
</taskdef>
Utilisation de ces librairies
Ci-dessous, vous trouverez un petit mémo expliquant comment utiliser les deux librairies XmlTask et CustomizeDocument afin de pouvoir écrire un script ANT permettant de passer un flux BPEL synchrone à un flux BPEL asynchrone. Les actions qui vont être utilisées dans le script ANT sont les suivantes :
- Copier/Coller (XmlTask)
- Supprimer (XmlTask)
- Ajouter un attribut (XmlTask)
- Remplacer un bloc par un autre (XmlTask)
- Changer la valeur d’un attribut (CustomizeDocument)
Les explications ci-dessous concernant l’utilisation des opérations ne sont pas exhaustives, elles se limitent aux notions nécessaires pour réaliser ce script ANT. Pour des informations plus complètes sur l’exploitation de ces opérations, veuillez-vous référer aux documentations accessibles en ligne (voir les références).
Copier/Coller
<copy path="/:definitions/:portType" buffer="myBuffer"/> <paste path="/:definitions/:portType" buffer="myBuffer" position="after"/>
Dans l’exemple ci-dessus, on copie un bloc XML spécifié par un chemin XPATH dans un buffer à l’aide de l’opération copy. Le contenu de ce buffer peut alors être récupéré et collé au sein du document à l’aide de l’opération paste, on définit l’emplacement via une chaîne XPATH à l’aide de l’attribut path et la position par rapport au bloc copié avec l’attribut position.
Supprimer
<remove path="/:definitions/:portType[1]/:operation/:output"/>
La commande remove permet de supprimer un bloc XML en précisant un chemin XPATH. Dans cet exemple, on va supprimer l’élément output se trouvant dans le bloc operation du deuxième bloc portType.
Ajouter un attribut dans un élément XML existant
<attr path="/:process/:partnerLinks/:partnerLink[@name = 'client']"
attr="partnerRole" value="${process.name}Requester"/>
La commande attr permet d’ajouter un attribut dans un élément existant du document XML. Les attributs path, attr et value précisent le chemin XPATH vers l’élément dans lequel on veut ajouter l’attribut portant le nom attr et ayant la valeur définie par value. Si cet attribut existe déjà, cette opération ne fera alors que remplacer sa valeur.
Remplacer un bloc par un autre
<replace path="/:process/:sequence[@name = 'main']/:reply"> <![CDATA[<invoke name="callbackClient" partnerLink="client" portType="" operation="onResult" inputVariable="" xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/"/>]]> </replace>
L’opération replace permet de supprimer le bloc spécifié par le chemin XPATH défini via l’attribut path et de le remplacer par le bloc défini entre les balises ouvrantes et fermantes. Ici, on spécifie directement entre les balises le bloc à insérer, on peut très bien aller chercher le contenu dans un buffer ou un fichier.
Changer la valeur d’un attribut
<setTextContent select="/wsdl:definitions/plnk:partnerLinkType/plnk:role[2]/@name"
textcontent="${process.name}Requester"/>
Avec l’attribut select, on sélectionne l’emplacement où on souhaite ajouter le texte donné par l’attribut textcontent. La valeur de l’attribut textcontent peut être une chaîne de caractères ou alors une variable. S’il s’agit d’une variable, alors elle doit être spécifiée dans le fichier de propriétés rattacher au script ANT.
Structure du script ANT
Le script ANT final se décompose en deux parties (deux target), une partie pour la modification du WSDL et l’autre pour la modification du BPEL. Sa structure est la suivante :
<?xml version="1.0" encoding="UTF-8"?>
<project default="SynchToAsynch" basedir=".">
<property value=".."/>
<property value="http://schemas.xmlsoap.org/wsdl/"/>
<property value="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"/>
<property value="http://schemas.xmlsoap.org/ws/2003/03/business-process/"/>
<property value="http://schemas.xmlsoap.org/wsdl/soap/"/>
<property value="http://www.w3.org/2001/XMLSchema"/>
<taskdef classname="com.oopsconsultancy.xmltask.ant.XmlTask">
<classpath>
<pathelement path="${process.dir}/AntExport/xmltask-v1.15.1.jar"/>
</classpath>
</taskdef>
<taskdef name="customizeDocument"
classname="com.collaxa.cube.ant.taskdefs.customize.document.CustomizeDocument">
<classpath>
<pathelement path="${process.dir}/customtasks.jar"/>
</classpath>
</taskdef>
<!-- Fichier de propriétés dans lequel on peut définir
les propriétés utilisées dans le script (emplacement du projet, etc.) -->
<property file="ChangeMode.properties"/>
<target depends="replaceWSDL,replaceBPEL"/>
<!-- Mise à jour du WSDL -->
<target name="replaceWSDL">
<xmltask source="${process.dir}/bpel/${process.name}.wsdl"
dest="${process.dir}/bpel/${process.name}.wsdl">
<!-- Insérer les traitements Copier/Coller, Suppression, etc. -->
</xmltask>
<customizeDocument infile="${process.dir}/bpel/${process.name}.wsdl"
outfile="${process.dir}/bpel/${process.name}.wsdl">
<!-- Insérer les traitements de remplacement de texte :
remplacer le nom de l'opération, etc. -->
</customizeDocument>
</target>
<!-- Mise à jour du BPEL -->
<target name="replaceBPEL">
<xmltask source="${process.dir}/bpel/${process.name}.bpel"
dest="${process.dir}/bpel/${process.name}.bpel">
<!-- Insérer les traitements Copier/Coller, Suppression, etc. -->
</xmltask>
<customizeDocument infile="${process.dir}/bpel/${process.name}.bpel"
outfile="${process.dir}/bpel/${process.name}.bpel">
<!-- Insérer les traitements de remplacement de texte : remplacer le nom de l'opération, etc. -->
</customizeDocument>
</target>
</project>
Le fichier de propriétés sur lequel s’appuie le script est un fichier texte dans lequel on énumère ces propriétés et on leur associe une valeur :
process.dir = C:/jdev/Tests process.name = SynchToAsynch_BPEL
Il reste alors à exploiter les différentes opérations détaillées ci-dessus pour mettre en place le script ANT de passage d’un flux synchrone à un flux asynchrone.
A vous de jouer et d’exploiter ce qui a été décrit plus haut …
Conclusion
L’automatisation de ce processus permettant de passer d’un flux synchrone à un flux asynchrone permet non seulement de gagner du temps mais permet également d’éviter toutes confusions ou erreurs inhérentes à ce genre de tâches fastidieuses.
Au travers de cet exemple d’utilisation des scripts ANT, vous pouvez découvrir une partie des possibilités offertes par ces scripts. Ils sont également utilisés pour le déploiement des flux et sont notamment utiles lorsqu’on est amené à déployer sur des environnements différents. En effet, ils permettent de modifier au déploiement les paramètres de connexion propres aux différents environnements.
Si vous voulez en savoir plus lisez absolument en savoir plus sur XmlTask


