Tutoriel : mise à jour de l’inventaire à l’aide du portail Azure et des rubriques/abonnements

Azure Service Bus est un service de messagerie cloud multi-locataire qui envoie des informations entre les applications et les services. Le fonctionnement asynchrone vous offre un service de messagerie répartie flexible, avec messagerie premier entré, premier sorti (FIFO) et fonctionnalités de publication/abonnement. Pour obtenir une vue d’ensemble détaillée d’Azure Service Bus, consultez Qu’est-ce que Service Bus ?.

Ce tutoriel montre comment utiliser les rubriques et abonnements Service Bus dans un scénario d’inventaire de vente au détail, avec des canaux de publication/abonnement à l’aide du portail Azure et de .NET. Un exemple de ce scénario est une mise à jour d’assortiment d’inventaire pour plusieurs magasins de détail. Dans ce scénario, chaque magasin ou ensemble de magasins, reçoit les messages destinés à mettre à jour leurs assortiments. Ce tutoriel montre comment implémenter ce scénario à l’aide des filtres et des abonnements. Tout d’abord, vous créez une rubrique avec trois abonnements, ajoutez des règles et des filtres, puis vous envoyez et recevez des messages à partir de la rubrique et des abonnements.

Image montrant un expéditeur, une rubrique avec trois abonnements, et trois destinataires.

Dans ce tutoriel, vous allez apprendre à :

  • Créer une rubrique Service Bus et trois abonnements à cette rubrique à l’aide du portail Azure
  • Ajouter des filtres pour les abonnements à l'aide du code .NET
  • Créer des messages avec un contenu différent
  • Envoyer les messages et vérifiez qu’ils arrivent dans les abonnements attendus
  • Recevoir des messages des abonnements

Prérequis

Pour suivre ce tutoriel, veillez à disposer des éléments suivants :

  • Abonnement Azure. Pour utiliser des services Azure, dont Azure Service Bus, vous avez besoin d’un abonnement. Si vous n'avez pas d'abonnement Azure, vous pouvez créer un compte gratuit avant de commencer.
  • Visual Studio 2019 ou version ultérieure.

Rubriques et abonnements Service Bus

Chaque abonnement à une rubrique peut recevoir une copie de chaque message. Les rubriques sont entièrement compatibles au niveau de la sémantique et du protocole avec les files d’attente Service Bus. Les rubriques Service Bus prennent en charge un large éventail de règles de sélection avec des conditions de filtre et avec des actions facultatives qui permettent de définir ou de modifier les propriétés des messages. Chaque fois qu’une règle correspond, elle génère un message. Pour en savoir plus sur les règles, filtres et actions, consultez ce lien.

Créer un espace de noms dans le Portail Azure

Pour commencer à utiliser des entités de messagerie Service Bus dans Azure, vous devez d’abord créer un espace de noms avec un nom unique dans Azure. Un espace de noms fournit un conteneur d’étendue pour les ressources du Service Bus (files d’attente, thèmes, etc.) au sein de votre application.

Pour créer un espace de noms :

  1. Connectez-vous au portail Azure.

  2. Accédez à la page Tous les services.

  3. Dans la barre de navigation à gauche, sélectionnez Intégration dans la liste des catégories, passez votre curseur sur Service Bus, puis cliquez le bouton + dans la vignette Service Bus.

    Image illustrant la sélection de Créer une ressource, puis celles de Intégration et de Service Bus, dans le menu.

  4. Dans l’étiquette De base de la page Créer un espace de noms, suivez ces étapes :

    1. Pour l’option Abonnement, choisissez un abonnement Azure dans lequel créer l’espace de noms.

    2. Pour l’option Groupe de ressources, choisissez un groupe de ressources existant dans lequel l’espace de noms sera utilisé, ou créez-en un nouveau.

    3. Entrez un nom pour l’espace de noms. Le nom de l’espace de noms doit respecter les conventions de nommage suivantes :

      • Le nom doit être unique dans tout Azure. Le système vérifie immédiatement si le nom est disponible.
      • Le nom doit inclure entre 6 et 50 caractères.
      • Le nom ne peut contenir que des lettres, des chiffres et des traits d’union (« - »).
      • Le nom doit commencer par une lettre, et se terminer par une lettre ou un chiffre.
      • Le nom ne se termine ni par « -sb » ni par « -mgmt ».
    4. Pour l’option Emplacement, choisissez la région dans laquelle héberger votre espace de noms.

    5. Pour le Niveau tarifaire, sélectionnez le SKU (De base, Standard ou Premium) destiné à l’espace de noms. Pour ce guide de démarrage rapide, sélectionnez Standard.

      Important

      Si vous voulez utiliser des rubriques et des abonnements, choisissez Standard ou Premium. Les rubriques/abonnements ne sont pas pris en charge dans le niveau tarifaire De base.

      Si vous avez sélectionné le SKU Premium, précisez le nombre d’unité de messagerie. Le niveau Premium isole les ressources au niveau du processeur et de la mémoire, ce qui permet d’exécuter chaque charge de travail de manière isolée. Ce conteneur de ressources est appelé unité de messagerie. Un espace de noms Premium a au moins une unité de messagerie. Vous pouvez sélectionner 1, 2, 4, 8 ou 16 unités de messagerie pour chaque espace de noms Service Bus Premium. Pour plus d’informations, consultez Messagerie Service Bus Premium.

    6. Au bas de la page, sélectionnez Examiner et créer.

      Image représentant la page Créer un espace de noms

    7. Dans la page Vérifier + créer, passez en revue les paramètres, puis sélectionnez Créer.

  5. Une fois le déploiement de la ressource réussi, sélectionnez Accéder à la ressource dans la page de déploiement.

    Image représentant la page du déploiement réussi avec le lien Atteindre la ressource.

  6. Vous voyez la page d’accueil de votre espace de noms Service Bus.

    Image représentant la page d’accueil de l’espace de noms Service Bus créé.

Obtenir la chaîne de connexion à l’espace de noms (portail Azure)

La création d’un espace de noms génère automatiquement une première stratégie de signature d’accès partagé (SAS) avec des clés primaires et secondaires, ainsi que des chaînes de connexion primaires et secondaires, qui donnent chacune un contrôle total sur tous les aspects de l’espace de noms. Consultez Authentification et autorisation Service Bus pour plus d’information sur la façon de créer des règles avec des droits plus restreints pour les expéditeurs et destinataires réguliers.

Un client peut utiliser la chaîne de connexion pour se connecter à l’espace de noms Service Bus. Pour copier la chaîne de connexion primaire pour votre espace de noms, suivez ces étapes :

  1. Dans la page Espace de noms Service Bus, sélectionnez Stratégies d’accès partagé dans le menu de gauche.

  2. Dans la page Stratégies d’accès partagé, sélectionnez RootManageSharedAccessKey.

  3. Dans la fenêtre Stratégie : RootManageSharedAccessKey, cliquez sur le bouton Copier situé en regard de Chaîne de connexion primaire, pour copier la chaîne de connexion dans le presse-papiers pour une utilisation ultérieure. Copiez cette valeur dans le Bloc-notes ou un autre emplacement temporaire.

    La capture d’écran montre une stratégie S A S appelée RootManageSharedAccessKey, qui comprend des clés et des chaînes de connexion.

    Vous pouvez utiliser cette page pour copier la clé primaire, la clé secondaire, la chaîne de connexion primaire et la chaîne de connexion secondaire.

Créer une rubrique à l’aide du Portail Azure

  1. Dans la page Espace de noms Service Bus, sélectionnez Rubriques dans le menu de gauche.

  2. Sélectionnez + Rubrique dans la barre d’outils.

  3. Entrez un nom pour la rubrique. Conservez les valeurs par défaut des autres options.

  4. Sélectionnez Create (Créer).

    Capture d’écran de la page Créer un rubrique.

Créer des abonnements à la rubrique

  1. Sélectionnez la rubrique que vous avez créée dans la section précédente.

    Capture d’écran de la page Rubriques avec votre rubrique selectionnée.

  2. Dans la page Rubrique Service Bus, sélectionnez Abonnements dans le menu de gauche, puis + Abonnement dans la barre d’outils.

    Capture d’écran de la page Abonnements avec le bouton Ajouter un abonnement sélectionné.

  3. Dans la page Créer un abonnement, procédez comme suit :

    1. Entrez S1 pour le nom de l’abonnement.

    2. Ensuite, sélectionnez Créer pour créer l’abonnement.

      Capture d’écran de la page Créer un abonnement.

  4. Répétez la dernière étape deux autre fois pour créer des abonnements nommés S2 et S3.

Créer des règles de filtre sur les abonnements

Une fois que l’espace de noms et les rubriques/abonnements sont provisionnés et que vous disposez de la chaîne de connexion à l’espace de noms, vous êtes prêt à créer des règles de filtre sur les abonnements, puis à envoyer et recevoir des messages. Vous pouvez consulter le code dans ce dossier d’exemples GitHub.

Envoyer et recevoir des messages

Pour exécuter le code, procédez comme suit :

  1. Dans une invite de commandes ou une invite PowerShell, clonez le référentiel GitHub Service Bus en exécutant la commande suivante :

    git clone https://github.com/Azure/azure-service-bus.git
    
  2. Accédez à l’exemple de dossier azure-service-bus\samples\DotNet\Azure.Messaging.ServiceBus\BasicSendReceiveTutorialWithFilters.

  3. Obtenez la chaîne de connexion que vous avez copiée dans le Bloc-notes plus haut dans ce tutoriel. Vous avez également besoin du nom de la rubrique que vous avez créé dans la section précédente.

  4. Saisissez ensuite la commande suivante dans l’invite de commandes :

    dotnet build
    
  5. Accédez au dossier BasicSendReceiveTutorialWithFilters\bin\Debug\netcoreapp3.1.

  6. Tapez la commande suivante pour exécuter le programme. Veillez à remplacer myConnectionString par la valeur que vous avez obtenue précédemment, et myTopicName par le nom de la rubrique que vous avez créée :

    dotnet --roll-forward Major BasicSendReceiveTutorialWithFilters.dll -ConnectionString "myConnectionString" -TopicName "myTopicName"
    
  7. Suivez d’abord les instructions dans la console pour sélectionner la création de filtres. La création de filtres implique la suppression des filtres par défaut. Lorsque vous utilisez PowerShell ou CLI, vous n’avez pas besoin de supprimer les filtres par défaut, mais si faites cela dans le code, vous devez les supprimer. Les commandes de console 1 et 3 vous aident à gérer les filtres sur les abonnements que vous avez créés précédemment :

    • Exécutez 1 : pour supprimer les filtres par défaut.

    • Exécutez 2 : pour ajouter vos propres filtres.

    • Exécutez 3 : ignorez cette étape pour le tutoriel. Cette option supprime éventuellement vos propres filtres. Cela ne recréera pas les filtres par défaut.

      Affichage de la sortie de 2

  8. Après la création des filtres, vous pouvez envoyer des messages. Appuyez sur 4 et observez l’envoi de 10 messages à la rubrique :

    Envoi de la sortie

  9. Appuyez sur 5 et observez la réception des messages. Si vous n’obtenez pas 10 messages en retour, appuyez sur « m » pour afficher le menu, puis appuyez de nouveau sur 5.

    Recevoir la sortie

Nettoyer les ressources

Quand vous n’en avez plus besoin, procédez comme suit pour nettoyer les ressources.

  1. Accédez à votre espace de noms dans le portail Azure.
  2. Sur la page Espace de nom du bus de service, sélectionnez Supprimer dans la barre de commande pour supprimer l'espace de nom et les ressources (files d'attente, sujets et abonnements) qu'il contient.

Comprendre l’exemple de code

Cette section contient plus de détails sur ce que fait l’exemple de code.

Obtention de la chaîne de connexion et de la rubrique

Tout d’abord, le code déclare un ensemble de variables qui déterminent l’exécution restante du programme.

string ServiceBusConnectionString;
string TopicName;

static string[] Subscriptions = { "S1", "S2", "S3" };
static IDictionary<string, string[]> SubscriptionFilters = new Dictionary<string, string[]> {
    { "S1", new[] { "StoreId IN('Store1', 'Store2', 'Store3')", "StoreId = 'Store4'"} },
    { "S2", new[] { "sys.To IN ('Store5','Store6','Store7') OR StoreId = 'Store8'" } },
    { "S3", new[] { "sys.To NOT IN ('Store1','Store2','Store3','Store4','Store5','Store6','Store7','Store8') OR StoreId NOT IN ('Store1','Store2','Store3','Store4','Store5','Store6','Store7','Store8')" } }
};
// You can have only have one action per rule and this sample code supports only one action for the first filter, which is used to create the first rule. 
static IDictionary<string, string> SubscriptionAction = new Dictionary<string, string> {
    { "S1", "" },
    { "S2", "" },
    { "S3", "SET sys.Label = 'SalesEvent'"  }
};
static string[] Store = { "Store1", "Store2", "Store3", "Store4", "Store5", "Store6", "Store7", "Store8", "Store9", "Store10" };
static string SysField = "sys.To";
static string CustomField = "StoreId";
static int NrOfMessagesPerStore = 1; // Send at least 1.

Les noms de la rubrique et de la chaîne de connexion sont transmis via des paramètres de ligne de commande comme indiqué, puis sont lus dans la méthode Main() :

static void Main(string[] args)
{
    string ServiceBusConnectionString = "";
    string TopicName = "";

    for (int i = 0; i < args.Length; i++)
    {
        if (args[i] == "-ConnectionString")
        {
            Console.WriteLine($"ConnectionString: {args[i + 1]}");
            ServiceBusConnectionString = args[i + 1]; // Alternatively enter your connection string here.
        }
        else if (args[i] == "-TopicName")
        {
            Console.WriteLine($"TopicName: {args[i + 1]}");
            TopicName = args[i + 1]; // Alternatively enter your queue name here.
        }
    }

    if (ServiceBusConnectionString != "" && TopicName != "")
    {
        Program P = StartProgram(ServiceBusConnectionString, TopicName);
        P.PresentMenu().GetAwaiter().GetResult();
    }
    else
    {
        Console.WriteLine("Specify -Connectionstring and -TopicName to execute the example.");
        Console.ReadKey();
    }
}

Supprimer les filtres par défaut

Lorsque vous créez un abonnement, Service Bus crée un filtre par défaut par abonnement. Ce filtre permet de recevoir tous les messages envoyés à la rubrique. Si vous souhaitez utiliser des filtres personnalisés, vous pouvez supprimer le filtre par défaut, comme indiqué dans le code suivant :

private async Task RemoveDefaultFilters()
{
    Console.WriteLine($"Starting to remove default filters.");

    try
    {
        var client = new ServiceBusAdministrationClient(ServiceBusConnectionString);
        foreach (var subscription in Subscriptions)
        {
            await client.DeleteRuleAsync(TopicName, subscription, CreateRuleOptions.DefaultRuleName);
            Console.WriteLine($"Default filter for {subscription} has been removed.");
        }

        Console.WriteLine("All default Rules have been removed.\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

    await PresentMenu();
}

Création de filtres

Le code suivant ajoute les filtres personnalisés définis dans ce tutoriel :

private async Task CreateCustomFilters()
{
    try
    {
        for (int i = 0; i < Subscriptions.Length; i++)
        {
            var client = new ServiceBusAdministrationClient(ServiceBusConnectionString);
            string[] filters = SubscriptionFilters[Subscriptions[i]];
            if (filters[0] != "")
            {
                int count = 0;
                foreach (var myFilter in filters)
                {
                    count++;

                    string action = SubscriptionAction[Subscriptions[i]];
                    if (action != "")
                    {
                        await client.CreateRuleAsync(TopicName, Subscriptions[i], new CreateRuleOptions
                        {
                            Filter = new SqlRuleFilter(myFilter),
                            Action = new SqlRuleAction(action),
                            Name = $"MyRule{count}"
                        });
                    }
                    else
                    {
                        await client.CreateRuleAsync(TopicName, Subscriptions[i], new CreateRuleOptions
                        {
                            Filter = new SqlRuleFilter(myFilter),
                            Name = $"MyRule{count}"
                        });
                    }
                }
            }

            Console.WriteLine($"Filters and actions for {Subscriptions[i]} have been created.");
        }

        Console.WriteLine("All filters and actions have been created.\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

    await PresentMenu();
}

Supprimer vos filtres personnalisés

Si vous souhaitez supprimer tous les filtres de votre abonnement, le code suivant montre comment procéder :

private async Task CleanUpCustomFilters()
{
    foreach (var subscription in Subscriptions)
    {
        try
        {
            var client = new ServiceBusAdministrationClient(ServiceBusConnectionString);
            IAsyncEnumerator<RuleProperties> rules = client.GetRulesAsync(TopicName, subscription).GetAsyncEnumerator();
            while (await rules.MoveNextAsync())
            {
                await client.DeleteRuleAsync(TopicName, subscription, rules.Current.Name);
                Console.WriteLine($"Rule {rules.Current.Name} has been removed.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
    Console.WriteLine("All default filters have been removed.\n");

    await PresentMenu();
}

Envoyer des messages

L’envoi de messages à une rubrique est similaire à l’envoi de messages à une file d’attente. Cet exemple montre comment envoyer des messages, à l’aide d’une liste des tâches et d’un traitement asynchrone :

public async Task SendMessages()
{
    try
    {
        await using var client = new ServiceBusClient(ServiceBusConnectionString);
        var taskList = new List<Task>();
        for (int i = 0; i < Store.Length; i++)
        {
            taskList.Add(SendItems(client, Store[i]));
        }

        await Task.WhenAll(taskList);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
    Console.WriteLine("\nAll messages sent.\n");
}

private async Task SendItems(ServiceBusClient client, string store)
{
    // create the sender
    ServiceBusSender tc = client.CreateSender(TopicName);

    for (int i = 0; i < NrOfMessagesPerStore; i++)
    {
        Random r = new Random();
        Item item = new Item(r.Next(5), r.Next(5), r.Next(5));

        // Note the extension class which is serializing an deserializing messages
        ServiceBusMessage message = item.AsMessage();
        message.To = store;
        message.ApplicationProperties.Add("StoreId", store);
        message.ApplicationProperties.Add("Price", item.GetPrice().ToString());
        message.ApplicationProperties.Add("Color", item.GetColor());
        message.ApplicationProperties.Add("Category", item.GetItemCategory());

        await tc.SendMessageAsync(message);
        Console.WriteLine($"Sent item to Store {store}. Price={item.GetPrice()}, Color={item.GetColor()}, Category={item.GetItemCategory()}"); ;
    }
}

Recevoir des messages

Là encore, les messages sont reçus via une liste des tâches, et le code utilise le traitement par lot. Vous pouvez envoyer et recevoir à l’aide du traitement par lot, mais cet exemple ne montre que la réception par lots. En réalité, vous ne quitteriez pas la boucle, mais continueriez le bouclage et définiriez une valeur timespan supérieure, par exemple une minute. L’appel de réception au répartiteur est maintenu ouvert pendant ce laps de temps et si des messages arrivent, ils sont retournés immédiatement et un nouvel appel de réception est émis. Ce concept est appelé interrogation longue. Utiliser la pompe de réception que vous pouvez visualiser dans le démarrage rapide, et dans plusieurs autres exemples dans le référentiel, est une option plus classique.

public async Task Receive()
{
    var taskList = new List<Task>();
    for (var i = 0; i < Subscriptions.Length; i++)
    {
        taskList.Add(this.ReceiveMessages(Subscriptions[i]));
    }

    await Task.WhenAll(taskList);
}

private async Task ReceiveMessages(string subscription)
{
    await using var client = new ServiceBusClient(ServiceBusConnectionString);
    ServiceBusReceiver receiver = client.CreateReceiver(TopicName, subscription);

    // In reality you would not break out of the loop like in this example but would keep looping. The receiver keeps the connection open
    // to the broker for the specified amount of seconds and the broker returns messages as soon as they arrive. The client then initiates
    // a new connection. So in reality you would not want to break out of the loop. 
    // Also note that the code shows how to batch receive, which you would do for performance reasons. For convenience you can also always
    // use the regular receive pump which we show in our Quick Start and in other GitHub samples.
    while (true)
    {
        try
        {
            //IList<Message> messages = await receiver.ReceiveAsync(10, TimeSpan.FromSeconds(2));
            // Note the extension class which is serializing an deserializing messages and testing messages is null or 0.
            // If you think you did not receive all messages, just press M and receive again via the menu.
            IReadOnlyList<ServiceBusReceivedMessage> messages = await receiver.ReceiveMessagesAsync(maxMessages: 100);

            if (messages.Any())
            {
                foreach (ServiceBusReceivedMessage message in messages)
                {
                    lock (Console.Out)
                    {
                        Item item = message.As<Item>();
                        IReadOnlyDictionary<string, object> myApplicationProperties = message.ApplicationProperties;
                        Console.WriteLine($"StoreId={myApplicationProperties["StoreId"]}");
                        if (message.Subject != null)
                        {
                            Console.WriteLine($"Subject={message.Subject}");
                        }
                        Console.WriteLine(
                            $"Item data: Price={item.GetPrice()}, Color={item.GetColor()}, Category={item.GetItemCategory()}");
                    }

                    await receiver.CompleteMessageAsync(message);
                }
            }
            else
            {
                break;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}

Notes

Vous pouvez gérer les ressources Service Bus à l'aide de Service Bus Explorer. Service Bus Explorer permet aux utilisateurs de se connecter à un espace de noms Service Bus et de gérer les entités de messagerie en toute simplicité. L’outil fournit des fonctionnalités avancées telles que la fonction d’importation/exportation ou la possibilité de tester une rubrique, des files d’attente, des abonnements, des services de relais, des hubs de notification et des hubs d’événements.

Étapes suivantes

Dans ce tutoriel, vous avez provisionné des ressources à l’aide du portail Azure, puis envoyé et reçu des messages à partir d’une rubrique Service Bus et de ses abonnements. Vous avez appris à :

  • Créer une rubrique Service Bus et un ou plusieurs abonnements à cette rubrique à l’aide du portail Azure
  • Ajouter des filtres de rubrique à l’aide de code .NET
  • Créer deux messages avec un contenu différent
  • Envoyer les messages et vérifiez qu’ils arrivent dans les abonnements attendus
  • Recevoir des messages des abonnements

Pour plus d’exemples d’envoi et de réception de messages, démarrez avec les exemples Service Bus sur GitHub.

Passez au prochain tutoriel pour en savoir plus sur les fonctionnalités de publication/abonnement de Service Bus.