Créer un service de workflow de longue durée
Cet article explique comment créer un service de workflow de longue durée, qui peut s'exécuter sur de longues périodes. À un certain stade, le workflow peut devenir inactif en attendant des informations supplémentaires. Lorsque cela se produit, le workflow est rendu persistant dans une base de données SQL et supprimé de la mémoire. Une fois que les informations supplémentaires sont disponibles, l'instance de workflow est à nouveau chargée dans la mémoire et continue de s'exécuter.
Dans ce scénario, vous implémentez un système de commande simplifié. Le client envoie un message initial au service de workflow pour commencer la commande. Un ID de commande est retourné au client. À ce stade, le service de workflow attend un autre message du client, passe à l'état inactif et est rendu persistant dans une base de données SQL Server. Lorsque le client envoie le message suivant pour commander un article, le service de workflow est à nouveau chargé dans la mémoire et termine le traitement de la commande.
Dans l'exemple de code, il retourne une chaîne indiquant que l'article a été ajouté à la commande. L'exemple de code n'est pas censé refléter une application réelle de la technologie mais plutôt un exemple simple illustrant des services de workflow de longue durée.
Prérequis
Les logiciels suivants doivent être installés pour suivre cette procédure pas à pas :
- Microsoft SQL Server 2008
- Visual Studio 2012
- Microsoft .NET Framework 4.6.1
Vous devez également connaître WCF et Visual Studio 2012 et savoir comment créer des projets/solutions.
Configurer SQL Database
Pour que les instances du service de workflow soient persistantes, Microsoft SQL Server doit être installé et vous devez configurer une base de données pour stocker les instances de workflow persistantes. Exécutez Microsoft SQL Management Studio en cliquant sur le bouton Démarrer, puis en sélectionnant Tous les programmes, Microsoft SQL Server 2008 et Microsoft SQL Management Studio.
Cliquez sur le bouton Se connecter pour vous connecter à l’instance SQL Server.
Cliquez avec le bouton droit sur Bases de données dans l'arborescence et sélectionnez Nouvelle base de données pour créer une nouvelle base de données nommée
SQLPersistenceStore
.Exécutez le fichier de script SqlWorkflowInstanceStoreSchema.sql situé dans le répertoire C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en dans la base de données SQLPersistenceStore pour configurer les schémas de base de données requis.
Exécutez le fichier de script SqlWorkflowInstanceStoreLogic.sql situé dans le répertoire C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en dans la base de données SQLPersistenceStore pour configurer la logique de base de données requise.
Créer le service de workflow hébergé sur le web
Créez une solution Visual Studio 2012 vide et nommez-la
OrderProcessing
.Ajoutez à la solution un nouveau projet d'application de service de workflow WCF appelée
OrderService
.Dans la boîte de dialogue des propriétés du projet, sélectionnez l’onglet Web.
Sous Action de démarrage, sélectionnez Page spécifique et spécifiez
Service1.xamlx
.Sous Serveurs, sélectionnez Utiliser le serveur web IIS local.
Avertissement
Vous devez exécuter Visual Studio 2012 en mode Administrateur pour effectuer ce paramétrage.
Ces deux étapes configurent le projet du service de workflow pour qu'il soit hébergé par IIS.
Ouvrez
Service1.xamlx
s’il n’est pas déjà ouvert et supprimez les activités ReceiveRequest et SendResponse.Sélectionnez l’activité Sequential Service, cliquez sur le lien Variables et ajoutez les variables indiquées dans l’illustration suivante. Cette action permet d'ajouter des variables qui seront utilisées ultérieurement dans le service de workflow.
Notes
Si CorrelationHandle ne figure pas dans la liste déroulante Type de variable, sélectionnez Rechercher des types dans la liste. Saisissez CorrelationHandle dans la zone Nom du type, sélectionnez CorrelationHandle dans la zone de liste, puis cliquez sur OK.
Faites glisser et déposez un modèle d’activité ReceiveAndSendReply dans l’activité Sequential Service. Cet ensemble d'activités recevra un message d'un client et enverra une réponse en retour.
Sélectionnez l’activité Receive et définissez les propriétés mises en surbrillance dans l’illustration suivante.
La propriété DisplayName définit le nom affiché pour l'activité Receive dans le concepteur. Les propriétés ServiceContractName et OperationName spécifient le nom du contrat de service et de l'opération implémentés par l'activité Receive. Pour plus d’informations sur l’utilisation des contrats dans les services de workflow, consultez Utilisation de contrats dans les services de workflow.
Cliquez sur le lien Définir dans l'activité ReceiveStartOrder et définissez les propriétés indiquées dans l'illustration suivante. Notez que la case d’option Paramètres est sélectionnée ; un paramètre nommé
p_customerName
est lié à la variablecustomerName
. L'activité Receive est alors configurée pour recevoir des données et les lier à des variables locales.Sélectionnez l’activité SendReplyToReceive et définissez la propriété mise en surbrillance dans l’illustration suivante.
Cliquez sur le lien Définir dans l'activité SendReplyToStartOrder et définissez les propriétés indiquées dans l'illustration suivante. Notez que la case d’option Paramètres est sélectionnée ; un paramètre nommé
p_orderId
est lié à la variableorderId
. Ce paramètre spécifie que l'activité SendReplyToStartOrder retournera une valeur de type String à l'appelant.Faites glisser et déposez une activité Assign entre les activités Receive et SendReply, et définissez les propriétés comme indiqué dans l’illustration suivante :
Cette action permet de créer un nouvel ID de commande et de placer la valeur dans la variable orderId.
Sélectionnez l’activité ReplyToStartOrder. Dans la fenêtre des propriétés, cliquez sur le bouton de sélection deCorrelationInitializers. Sélectionnez le lien Ajouter un initialiseur, entrez
orderIdHandle
dans la zone de texte Initialiseur, sélectionnez Initialiseur de corrélation de requête dans le champ Type de corrélation, puis sélectionnez p_orderId sous la zone de liste déroulante Requêtes XPATH. Ces paramètres sont affichés dans l’illustration suivante. Cliquez sur OK. Cette action permet d'initialiser une corrélation entre le client et cette instance du service de workflow. Lorsqu'un message contenant cet ID de commande est reçu, il est routé vers cette instance du service de workflow.
Faites glisser et déposez une autre activité ReceiveAndSendReply à la fin du workflow (en dehors de la séquence contenant les premières activités Receive et SendReply). Le second message envoyé par le client sera alors reçu et une réponse sera renvoyée.
Sélectionnez la séquence contenant les activités Receive et SendReply récemment ajoutées, puis cliquez sur le bouton Variables. Ajoutez la variable mise en surbrillance dans l'illustration suivante :
Ajoutez également
orderResult
en tant que chaîne dans l’étendueSequence
.Sélectionnez l’activité Receive et définissez les propriétés indiquées dans l’illustration suivante :
Notes
N’oubliez pas de modifier le champ ServiceContractName en saisissant
../IAddItem
.Cliquez sur le lien Définir dans l'activité ReceiveAddItem et ajoutez les paramètres indiqués dans l'illustration suivante. Cette action permet de configurer l'activité de réception de façon à accepter deux paramètres, l'ID de commande et l'ID de l'article commandé.
Cliquez sur le bouton de sélection CorrelateOn et entrez
orderIdHandle
. Sous Requêtes XPath, cliquez sur la flèche déroulante et sélectionnezp_orderId
. Cela permet de configurer la corrélation sur la deuxième activité Receive. Pour plus d’informations sur la corrélation, consultez Corrélation.Faites glisser et déposez une activité If juste après l’activité ReceiveAddItem. Cette activité agit de la même façon qu'une instruction if.
Définissez la propriété Condition sur
itemId=="Zune HD" (itemId="Zune HD" for Visual Basic)
.Faites glisser et déposez une activité Assign dans la section Then et une autre dans la section Else, puis définissez les propriétés des activités Assign, comme indiqué dans l’illustration suivante.
Si la condition est
true
, la section Then est exécutée. Si la condition estfalse
, la section Else est exécutée.Sélectionnez l’activité SendReplyToReceive et définissez la propriété DisplayName indiquée dans l’illustration suivante.
Cliquez sur le lien Définir dans l'activité SetReplyToAddItem et configurez-la comme indiqué dans l'illustration suivante. Cette action permet de configurer l’activité SendReplyToAddItem de façon à renvoyer la valeur dans la variable
orderResult
.
Ouvrez le fichier web.config et ajoutez les éléments suivants dans la section <behavior> pour activer la persistance du workflow. (Veillez à mettre à jour la chaîne de connexion.)
<sqlWorkflowInstanceStore connectionString="...;Asynchronous Processing=True" instanceEncodingOption="None" instanceCompletionAction="DeleteAll" instanceLockedExceptionAction="BasicRetry" hostLockRenewalPeriod="00:00:30" runnableInstancesDetectionPeriod="00:00:02" /> <workflowIdle timeToUnload="0"/>
Générez la solution.
Créer une application cliente pour appeler le service de workflow
Ajoutez à la solution un nouveau projet d'application console nommé
OrderClient
.Ajoutez les références aux assemblys suivantes au projet
OrderClient
:System.ServiceModel.dll
System.ServiceModel.Activities.dll
Ajoutez une référence de service au service de workflow et spécifiez
OrderService
comme espace de noms.Dans la méthode
Main()
du projet client, ajoutez le code suivant :static void Main(string[] args) { // Send initial message to start the workflow service Console.WriteLine("Sending start message"); StartOrderClient startProxy = new StartOrderClient(); string orderId = startProxy.StartOrder("Kim Abercrombie"); // The workflow service is now waiting for the second message to be sent Console.WriteLine("Workflow service is idle..."); Console.WriteLine("Press [ENTER] to send an add item message to reactivate the workflow service..."); Console.ReadLine(); // Send the second message Console.WriteLine("Sending add item message"); AddItemClient addProxy = new AddItemClient(); AddItem item = new AddItem(); item.p_itemId = "Zune HD"; item.p_orderId = orderId; string orderResult = addProxy.AddItem(item); Console.WriteLine("Service returned: " + orderResult); }
Générez la solution et exécutez l'application
OrderClient
. Le client affiche le texte suivant :Sending start messageWorkflow service is idle...Press [ENTER] to send an add item message to reactivate the workflow service...
Pour vérifier que la persistance du service de workflow a été activée, démarrez SQL Server Management Studio en sélectionnant le menu Démarrer, puis Tous les programmes, Microsoft SQL Server 2008 et SQL Server Management Studio.
- Dans le volet gauche, développez Bases de données, SQLPersistenceStore, Vues, puis cliquez avec le bouton droit sur System.Activities.DurableInstancing.Instances et choisissez Sélectionner les 1 000 premières lignes. Dans le volet Résultats, vérifiez qu’au moins une instance est répertoriée. D'autres instances d'exécutions précédentes peuvent également être présentes si une exception s'est produite pendant l'exécution. Vous pouvez supprimer des lignes existantes. Pour ce faire, cliquez avec le bouton droit sur System.Activities.DurableInstancing.Instances, sélectionnez Modifier les 200 premières lignes, cliquez sur le bouton Exécuter, sélectionnez toutes les lignes dans le volet de résultats et choisissez Supprimer. Pour vous assurer que l'instance affichée dans la base de données est bien l'instance créée par votre application, vérifiez que la vue Instances est vide avant d'exécuter le client. Une fois que le client est en cours d'exécution, réexécutez la requête (Sélectionner les 1000 lignes du haut) et assurez-vous qu'une nouvelle instance a été ajoutée.
Appuyez sur Entrée pour envoyer le message d'ajout d'élément au service de workflow. Le client affiche le texte suivant :
Sending add item messageService returned: Item added to orderPress any key to continue . . .