Traitement des messages composés (exemple BizTalk Server)
Cet exemple a pour but de créer une application de traitement des messages composés qui traite les éléments de ligne individuels à partir de messages agrégés.
Plus précisément, nous allons créer une planification d'orchestration qui :
Reçoit un message d'échange par lot composé de plusieurs bons de commande.
Désassemble le message d'échange en documents de bon de commande individuels.
Traite chaque document – convertit chaque bon de commande en message de facture.
Assemble tous les messages de facture en un échange par lot.
L'étape n°3 est simplifiée pour les besoins de l'exemple. Ainsi, dans des applications plus complexes, une orchestration peut envoyer des bons de commande désassemblés à différents systèmes d'inventaire principaux, collecte toutes les réponses, puis les regroupe dans un message de facture par lot.
Pour plus d'informations sur le modèle de traitement des messages composés, consultez la rubrique [1].
Fonctions de l'exemple
La solution de l'exemple est composée de deux projets qui sont détaillés dans les sections suivantes.
Pipelines et schémas
Le projet Pipelines et schémas contient :
Des schémas de fichier plat pour l'échange de bon de commande d'entrée et l'échange de facture de sortie.
Un mappage pour transformer le document de bon de commande en un document de facture.
Des pipelines de réception et d'envoi.
Schémas de fichier plat pour les échanges d'entrée et de sortie
Notre exemple d'application fonctionne avec les échanges dans le format de fichier plat. Voici les exemples d'échange de bon de commande et d'échange de facture :
Échange de bon de commande (CMPInput.txt) :
Northwind Shipping
Batch type:Purchase Orders
PO1999-10-20
US Alice Smith 123 Maple Street Mill Valley CA 90952
US Robert Smith 8 Oak Avenue Old Town PA 95819
Hurry, my lawn is going wild!
ITEMS,ITEM872-AA|Lawnmower|1|148.95|Confirm this is electric,ITEM926-AA|Baby Monitor|1|39.98|Confirm this is electric|1999-10-21
PO1999-10-21
US John Dow 123 Elm Street Mill Valley CA 90952
US July Dow 8 Pine Avenue Old Town PA 95819
Please ship it urgent!
ITEMS,ITEM398-BB|Tire|4|324.99|Wrap them up nicely,ITEM201-BB|Engine Oil|1|12.99|SAE10W30|1999-05-22
PO1999-10-23
US John Connor 123 Cedar Street Mill Valley CA 90952
US Sarah Connor 8 Grass Avenue Old Town PA 95819
Use cheapest shipping method.
ITEMS,ITEM101-TT|Plastic flowers|10|4.99|Fragile handle with care,ITEM202-RR|Fertilizer|1|10.99|Lawn fertilizer,ITEM453-XS|Weed killer|1|5.99|Lawn weed killer|1999-05-25
L'échange, ou document de bon de commande, a un en-tête qui identifie le type des documents qu'il contient :
Northwind Shipping
Batch type:Purchase Orders
Cet échange est constitué de trois documents de bon de commande. Une seule instance regroupe les informations ci-après. Comme vous pouvez le constater, elle contient des informations telles que l'adresse de facturation et de livraison, ainsi que la liste des articles commandés.
PO1999-10-20
US Alice Smith 123 Maple Street Mill Valley CA 90952
US Robert Smith 8 Oak Avenue Old Town PA 95819
Hurry, my lawn is going wild!
ITEMS,ITEM872-AA|Lawnmower|1|148.95|Confirm this is electric,ITEM926-AA|Baby Monitor|1|39.98|Confirm this is electric|1999-10-21
L'échange de facture que nous voulons générer pour cela doit ressembler à ceci :
Northwest Shipping
DocumentTypes:Invoices
INVOICE1999-10-20
BILLTO,US,Alice Smith,123 Maple Street,Mill Valley,CA,90952
872-AA Lawnmower 1 148.95 Confirm this is electric
926-AA Baby Monitor 1 39.98 Confirm this is electric
INVOICE1999-10-21
BILLTO,US,John Dow,123 Elm Street,Mill Valley,CA,90952
398-BB Tire 4 324.99 Wrap them up nicely
201-BB Engine Oil 1 12.99 SAE10W30
INVOICE1999-10-20
BILLTO,US,John Connor,123 Cedar Street,Mill Valley,CA,90952
101-TT Plastic flowers 10 4.99 Fragile handle with care
202-RR Fertilizer 1 10.99 Lawn fertilizer
453-XS Weed killer 1 5.99 Lawn weed killer
Cet échange contient un sous-ensemble d'informations présent dans l'échange de bon de commande. Par ailleurs, le format de l'échange est différent de celui de l'en-tête.
L'en-tête est le suivant :
Northwest Shipping
DocumentTypes:Invoices
L'instance de document inclut les éléments suivants :
INVOICE1999-10-20
BILLTO,US,Alice Smith,123 Maple Street,Mill Valley,CA,90952
872-AA Lawnmower 1 148.95 Confirm this is electric
926-AA Baby Monitor 1 39.98 Confirm this is electric
Tout d'abord, nous devons créer des schémas de fichier plat pour :
le document de bon de commande (PO.xsd)
le document de facture (Invoice.xsd)
l'en-tête du bon de commande (POHeader.xsd)
l'en-tête de la facture (InvoiceHeader.xsd)
Dans le cadre de cet exemple, nous n'allons pas expliquer comment créer des schémas de fichier plat. Pour plus d'informations sur la création de schémas de fichier plat à partir d'instances de document, consultez la section « Création de schémas de fichier plat à partir d'une instance de document » de la documentation.
Mappage pour transformer le document de bon de commande en document de facture
Le mappage (PO2Invoice.btm) transforme une instance du bon de commande en un document de facture.
Pipelines de réception et d'envoi
Le pipeline de réception (FFReceivePipeline.btp) contient un composant Désassembleur de fichier plat utilisé pour traiter un échange de bon de commande. En particulier, pour l'échange dans le fichier CMPInput.txt, il supprime l'en-tête d'échange et produit trois documents XML correspondant aux trois bons de commande.
Le Désassembleur de fichier plat dans le pipeline de réception est configuré comme suit :
Schéma du document : PipelinesAndSchemas.PO
Schéma d’en-tête : PipelinesAndSchemas.POHeader
Conserver l’en-tête : Faux
Échange récupérable : Faux
Schéma de la bande-annonce : (Aucun)
Valider la structure du document : Faux
Le pipeline d'envoi (FFSendPipeline.btp) contient un composant Assembleur de fichier plat utilisé pour créer un échange de facture agrégé.
L'Assembleur de fichier plat dans le pipeline d'envoi est configuré comme suit :
Schéma du document : PipelinesandSchemas.Invoice
Schéma d’en-tête : PipelinesAndSchemas.InvoiceHeader
Conserver la marque d’ordre d’octet : Faux
Jeu de caractères cible : (Aucun)
Schéma de la bande-annonce : (Aucun)
Planification d'orchestration
La planification d'orchestration (CMP.odx) centralise tout le traitement principal. Plus précisément, les opérations suivantes sont effectuées :
Le pipeline de réception est exécuté pour désassembler l'échange de bon de commande.
Chaque message de sortie du pipeline de réception est transformé.
Le pipeline d'envoi est exécuté pour assembler un échange de facture.
Création d'une planification d'orchestration et définition des variables globales
Notre orchestration reçoit un échange de fichier plat en tant qu'entrée et envoie un échange de fichier plat en tant que sortie. Nous devons donc définir des messages d'entrée et de sortie (nommés respectivement InputInterchange et OutputInterchange) indépendants de tout type (par exemple, de type System.Xml.XmlDocument).
En outre, nous devons définir une étendue atomique sur laquelle nous traiterons les messages. Cela est nécessaire car le pipeline de réception peut être exécuté au sein de l'étendue atomique.
Exécution du pipeline de réception
Maintenant, nous allons ajouter une logique pour exécuter un pipeline de réception pour le message reçu dans l'orchestration. Pour ce faire, commençons par déclarer une variable (nommée RcvPipeOutput) de type Microsoft.XLANGs.Pipeline.ReceivePipelineOutputMessages au sein de l'étendue. Cette variable est un énumérateur qui nous permet un cycle dans les messages de sortie du pipeline de réception. Notez que pour accéder à ce type, ainsi qu'à tous les autres types d'exécution des pipelines à partir d'une orchestration, vous devez ajouter des références aux assemblys suivants :
Microsoft.XLANGs.Pipeline.dll
Microsoft.BizTalk.Pipeline.dll
Il n'y a aucune garantie que le pipeline de réception s'exécute toujours avec succès. Des messages peuvent parfois être malformés, ce qui provoque l'échec du traitement du pipeline. Lorsque l'exécution d'un pipeline échoue dans l'orchestration, une exception pouvant être interceptée est générée et la logique de gestion des erreurs peut s'appliquer. Afin d'intercepter l'exception générée par le pipeline, nous devons exécuter le pipeline au sein d'une étendue non atomique, avec une gestion des exceptions. Le code réel pour exécuter le pipeline est appelé à partir d'une forme Expression au sein de cette étendue.
Dans la forme Expression ExecuteRcvPipe, écrivez la ligne de code suivante pour exécuter le pipeline de réception :
RcvPipeOutput = Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteReceivePipeline(typeof(PipelinesAndSchemas.FFReceivePipeline), InputInterchange);
Analysons cette ligne de code de plus près. Comme vous pouvez le voir, nous appelons une méthode statique ExecuteReceivePipeline qui prend comme paramètre un type de pipeline de réception à exécuter et un message d'entrée. Elle produit alors un objet énumérateur avec l'ensemble des messages de sortie. Le résultat est attribué à une variable de type ReceivePipelineOutputMessages précédemment définie dans cette étendue.
Nous avons également inclus un bloc de gestion des exceptions pour l'étendue d'exécution du pipeline. Ce bloc intercepte l'exception de type XLANGPipelineManagerException, puis, pour des raisons de simplicité, termine une instance d'orchestration avec un message d'erreur personnalisé.
Dans des cas plus complexes, une gestion des erreurs supplémentaire peut être effectuée ici, comme la génération du message de notification d'erreur et son envoi par courrier électronique à un utilisateur ou un administrateur des activités.
Transformation des messages de sortie du pipeline
Une fois que le pipeline a été exécuté et que l'ensemble de messages désassemblés a été produit, nous devons convertir chaque message de sortie dans un format différent.
Pour utiliser la transformation dans l'orchestration, nous devons définir deux messages : messages d'entrée et de sortie de transformation. Nous allons définir ces messages au sein de l'étendue atomique. Le message d'entrée de transformation, nommé TmpMessageIn, est de type PipelinesAndSchemas.PO. Le message de sortie de transformation, nommé TmpMessageOut, est de type PipelinesAndSchemas.Invoice. Nous allons appliquer le mappage PO2Invoice.btm défini dans le projet PipelinesAndSchemas.
Comme nous voulons mapper chaque message de sortie du pipeline, nous devons effectuer la transformation dans la boucle. Nous allons utiliser une forme Boucle avec la condition de sortie suivante :
RcvPipeOutput.MoveNext()
La méthode MoveNext() est une méthode standard de l'interface .NET IEnumerator qui autorise le déplacement au sein de la collection de messages de sortie du pipeline. Lorsqu'elle atteint la fin de la collection, elle renvoie false.
La première forme Construire sert à créer un message d'orchestration TmpMessageIn à partir du message de sortie du pipeline.
Le code dans la forme Construction est le suivant :
TmpMessageIn = null;
RcvPipeOutput.GetCurrent(TmpMessageIn);
Dans ce code, nous initialisons le message d'orchestration sur null, puis le définissons sur le message actuel à partir de la collection de messages de sortie du pipeline.
Dans la seconde forme Construire, la transformation réelle de TmpMessageIn est effectuée et le message TmpMessageOut de type PipelinesAndSchemas.Invoice est créé.
Exécution du pipeline d'envoi
La dernière étape de traitement dans l'orchestration consiste à exécuter le pipeline d'envoi de fichier plat pour assembler tous les messages XML transformés en un seul échange de fichier plat.
Afin d'exécuter un pipeline d'envoi, nous devons utiliser une variable de type Microsoft.XLANGs.Pipeline.SendPipelineInputMessages, nommée SendPipeInput, qui contient une collection de messages d'orchestration devant être traitée dans un pipeline d'envoi.
Dans la dernière expression de la boucle où nous avons effectué la transformation, nous allons écrire un code qui ajoute chaque message transformé à une collection de messages pour le pipeline d'envoi :
SendPipeInput.Add(TmpMessageOut);
Comme pour l'exécution du pipeline de réception, le code pour l'exécution du pipeline d'envoi est placé dans une étendue non atomique avec un bloc de gestion des exceptions. Le code d'exécution du pipeline d'envoi se trouve dans la forme Assignation de message du bloc de construction.
OutputInterchange = null;
Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteSendPipeline(typeof(PipelinesAndSchemas.FFSendPipeline), SendPipeInput, OutputInterchange);
Le bloc de construction est utilisé pour créer le message de sortie du pipeline OutputInterchange, indépendant de tout type (par exemple, System.Xml.XmlDocument). Puis, dans la forme Assignation de message, le message nouvellement construit est initialisé sur null. Ensuite, la méthode statique ExecuteSendPipeline est appelée pour exécuter un pipeline d'envoi. Cette méthode prend comme paramètre un type de pipeline d'envoi à exécuter, le message d'entrée et la référence au message de sortie dans lequel la sortie du pipeline sera stockée.
Comme pour l'exécution du pipeline de réception, nous avons ici aussi un bloc de gestion des exceptions pour l'étendue d'exécution du pipeline. Ce bloc intercepte l'exception de type XLANGPipelineManagerException, puis, pour des raisons de simplicité, termine une instance d'orchestration avec un message d'erreur personnalisé.
Accès à l'exemple
Le tableau suivant répertorie les fichiers de cet exemple.
Fichier(s) | Description |
---|---|
Cleanup.bat | Utilisé pour annuler le déploiement des assemblys et les supprimer du Global Assembly Cache (GAC). Supprime les ports d'envoi et de réception. Supprime les répertoires virtuels Microsoft Internet Information Services (IIS) le cas échéant. |
ComposedMessageProcessor.sln | Fichier de solution Visual Studio pour l'exemple. |
ComposedMessageProcessorBinding.xml | Fichier de liaison pour l'exemple. |
Setup.bat | Utilisé pour générer et initialiser cet exemple. |
Dans le dossier Orchestration : CMP.odx |
Orchestration qui exécute le pipeline de réception pour désassembler le message, transforme chaque message désassemblé, puis exécute le pipeline d'envoi pour assembler des messages dans un échange. |
Dans le dossier Orchestration : Orchestration.btproj |
Projet BizTalk pour l'orchestration. |
Dans le dossier Orchestration : SuspendMessage.odx |
Orchestration utilisée pour interrompre les messages dont le traitement du pipeline échoue. |
Dans le dossier PipelinesAndSchemas : CMPInput.xml, CMPOutput.xml |
Instances de document d'entrée et de sortie pour l'exemple. |
Dans le dossier PipelinesAndSchemas : FFReceivePipeline.btp, FFSendPipeline.btp |
Pipelines de réception et d'envoi avec des composants de fichier plat. Ces pipelines sont exécutés au sein de l'orchestration. |
Dans le dossier PipelinesAndSchemas : Invoice.xsd, InvoiceHeader.xsd |
Schémas de fichier plat pour le document et l'en-tête de sortie. |
Dans le dossier PipelinesAndSchemas : PO.xsd, POHeader.xsd |
Schémas de fichier plat pour le document et l'en-tête d'entrée. |
Dans le dossier PipelinesAndSchemas : PropertySchema.xsd |
Schéma de propriété pour l'exemple. |
Création et initialisation de l'exemple
La procédure suivante permet de créer et d'initialiser l'exemple Compose.
Pour créer et initialiser l'exemple Compose
Dans une fenêtre de commande, accédez au dossier suivant :
<Chemin d’accès> d’exemples\Pipelines\ComposedMessageProcessor
Exécutez le fichier Setup.bat, qui effectue les actions suivantes :
Création des dossiers d'entrée (In) et de sortie (Out) associés à cet exemple dans le dossier :
<Chemin d’accès> d’exemples\Pipelines\ComposedMessageProcessor
Compilation des projets Visual Studio pour cet exemple.
Création d'une application appelée « CMP Sample » et déploiement des assemblys de l'exemple au sein de celle-ci.
Création et liaison de l'emplacement de réception de BizTalk Server, ainsi que des ports d'envoi et de réception.
Inscription et démarrage de l'orchestration, activation de l'emplacement de réception et démarrage du port d'envoi.
Si vous choisissez d’ouvrir et de générer les projets dans cet exemple sans exécuter le fichier Setup.bat, vous devez d’abord créer une paire de clés de nom fort à l’aide de l’utilitaire .NET Framework Strong Name (sn.exe). Utilisez cette paire de clés pour signer les assemblys obtenus.
Avant de tenter d'exécuter cet exemple, vous devez vérifier que BizTalk Server n'a pas signalé d'erreur durant le processus de création et d'initialisation.
Pour annuler les modifications apportées par Setup.bat, vous devez effectuer les opérations suivantes :
Arrêtez et redémarrez l'instance de l'hôte à partir de la console Administration de BizTalk Server.
Exécutez Cleanup.bat. Vous devez exécuter Cleanup.bat avant d'exécuter Cleanup.bat une seconde fois.
Exécution de l’exemple
La procédure suivante permet d'exécuter l'exemple ComposedMessageProcessor.
Pour exécuter l'exemple ComposedMessageProcessor
Copiez le fichier texte CMPInput.txt situé dans le dossier PipelinesAndSchemas. Collez le fichier dans le dossier In.
Observez le fichier texte créé dans le dossier Out. Ce fichier contient les mêmes enregistrements que le CMPInput.txt, mais le format des données dans le fichier est différent.
Quand le message transite par BizTalk Server, les événements suivants se produisent :
Le message est désassemblé et converti en messages XML. Chaque message est mappé à un format différent.
Tous les messages mappés sont assemblés et convertis au format de fichier plat.