Exercice - Charger les ressources à utiliser par un travail Batch avec la bibliothèque de stockage .NET

Effectué

Important

Vous avez besoin de votre propre abonnement Azure pour exécuter cet exercice et des frais pourraient vous être facturés. Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.

La bibliothèque Stockage Azure vous permet de contrôler par programmation le stockage de fichiers dans un compte Stockage Azure.

Dans cet exercice, nous allons améliorer notre application pour charger des vidéos dans le stockage d’objets blob.

Ajouter les détails de connexion du compte de stockage

  1. Dans Cloud Shell, ajoutez le package NuGet du Stockage Blob Azure :

    dotnet add package Microsoft.Azure.Storage.Blob
    
  2. Modifiez le fichier Program.cs dans l’éditeur :

    code Program.cs
    
  3. Ajoutez les instructions using suivantes au début de Program.cs pour inclure les bibliothèques nécessaires au travail de stockage :

    using Microsoft.Azure.Storage.Blob;
    using Microsoft.Azure.Storage;
    using System.IO;
    

    Microsoft.Azure.Storage.Blob et Microsoft.Azure.Storage permettent à l’application d’accéder au compte Stockage Azure. System.IO permet à l’application d’accéder au système de fichiers pour la gestion de fichiers.

  4. Ajoutez des variables pour les informations d’identification Stockage Azure à la classe Program dans Program.cs :

    // Storage account credentials
    private const string envVarStorage = "STORAGE_NAME";
    private const string envVarStorageKey = "STORAGE_KEY";
    private static string storageAccountName;
    private static string storageAccountKey;
    

Créer un conteneur d’entrée et de sortie

  1. Remplacez Main() dans Program.cs par la mise à jour suivante. Celle-ci ajoute du code pour gérer le compte de stockage :

    static async Task Main(string[] args)
    {
        // Read the environment variables to allow the app to connect to the Azure Batch and Azure Storage accounts
        batchAccountUrl = Environment.GetEnvironmentVariable(envVarBatchURI);
        batchAccountName = Environment.GetEnvironmentVariable(envVarBatchName);
        batchAccountKey = Environment.GetEnvironmentVariable(envVarKey);
        storageAccountName = Environment.GetEnvironmentVariable(envVarStorage);
        storageAccountKey = Environment.GetEnvironmentVariable(envVarStorageKey);
    
        // Show the user the accounts they are attaching to
        Console.WriteLine("BATCH URL: {0}, Name: {1}, Key: {2}", batchAccountUrl, batchAccountName, batchAccountKey);
        Console.WriteLine("Storage Name: {0}, Key: {1}", storageAccountName, storageAccountKey);
    
        // Construct the Storage account connection string
        string storageConnectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
                            storageAccountName, storageAccountKey);
    
        // Retrieve the storage account
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);
    
        // Create the blob client, for use in obtaining references to blob storage containers
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    
        // Use the blob client to create the containers in blob storage
        const string inputContainerName = "input";
        const string outputContainerName = "output";
    
        await CreateContainerIfNotExistAsync(blobClient, inputContainerName);
        await CreateContainerIfNotExistAsync(blobClient, outputContainerName);
    
        // RESOURCE FILE SETUP
        // Add *.mp4 files into the \<solutiondir>\InputFiles folder.
    
        string inputPath = Path.Combine(Environment.CurrentDirectory, "InputFiles");
        List<string> inputFilePaths = new List<string>(
            Directory.GetFileSystemEntries(inputPath, "*.mp4", SearchOption.TopDirectoryOnly));
    
        // Upload data files.
        // Upload the data files using UploadResourceFilesToContainer(). This data will be
        // processed by each of the tasks that are executed on the compute nodes within the pool.
        List<ResourceFile> inputFiles = await UploadFilesToContainerAsync(blobClient, inputContainerName, inputFilePaths);
    
        // Obtain a shared access signature that provides write access to the output container to which
        // the tasks will upload their output.
        string outputContainerSasUrl = GetContainerSasUrl(blobClient, outputContainerName, SharedAccessBlobPermissions.Write);
    
        // The batch client requires a BatchSharedKeyCredentials object to open a connection
        var sharedKeyCredentials = new BatchSharedKeyCredentials(batchAccountUrl, batchAccountName, batchAccountKey);
        var batchClient = BatchClient.Open(sharedKeyCredentials);
    
        // Create the Batch pool, which contains the compute nodes that execute tasks.
        await CreateBatchPoolAsync(batchClient, PoolId);
    }
    

    Dans le code ci-dessus, un objet CloudStorageAccount est créé pour permettre à l’application de créer un client d’objet blob. Le client est utilisé pour créer les conteneurs de stockage, charger les fichiers et donner accès au travail à écrire dans le conteneur de sortie.

Créer des conteneurs de stockage pour l’entrée et la sortie de fichiers

  1. Ajoutez la méthode suivante, CreateContainerIfNotExistAsync(), pour créer un conteneur portant le nom spécifié :

    private static async Task CreateContainerIfNotExistAsync(CloudBlobClient blobClient, string containerName)
    {
        CloudBlobContainer container = blobClient.GetContainerReference(containerName);
        await container.CreateIfNotExistsAsync();
        Console.WriteLine("Creating container [{0}].", containerName);
    }
    

    Le code précédent utilise le CloudBlobClient créé dans la méthode Main pour créer des conteneurs.

Traiter la liste de tous les fichiers à charger

  1. Ajoutez la méthode suivante, UploadFilesToContainerAsync(), pour charger une liste de fichiers d’entrée dans le conteneur :

    private static async Task<List<ResourceFile>> UploadFilesToContainerAsync(CloudBlobClient blobClient, string inputContainerName, List<string> filePaths)
    {
        List<ResourceFile> resourceFiles = new List<ResourceFile>();
    
        foreach (string filePath in filePaths)
        {
            resourceFiles.Add(await UploadResourceFileToContainerAsync(blobClient, inputContainerName, filePath));
        }
    
        return resourceFiles;
    }
    

    Le code précédent utilise la liste de chemins créée pour appeler une méthode et les charger. Il stocke également la référence ResourceFile produite à des fins d’utilisation par le travail Batch.

Charger les fichiers

  1. Ajoutez une méthode pour charger les fichiers locaux dans le stockage Azure :

    private static async Task<ResourceFile> UploadResourceFileToContainerAsync(CloudBlobClient blobClient, string containerName, string filePath)
    {
        Console.WriteLine("Uploading file {0} to container [{1}]...", filePath, containerName);
    
        string blobName = Path.GetFileName(filePath);
        var fileStream = System.IO.File.OpenRead(filePath);
    
        CloudBlobContainer container = blobClient.GetContainerReference(containerName);
        CloudBlockBlob blobData = container.GetBlockBlobReference(blobName);
        await blobData.UploadFromFileAsync(filePath);
    
        // Set the expiry time and permissions for the blob shared access signature. In this case, no start time is specified,
        // so the shared access signature becomes valid immediately
        SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(2),
            Permissions = SharedAccessBlobPermissions.Read
        };
    
        // Construct the SAS URL for the blob
        string sasBlobToken = blobData.GetSharedAccessSignature(sasConstraints);
        string blobSasUri = String.Format("{0}{1}", blobData.Uri, sasBlobToken);
    
        return ResourceFile.FromUrl(blobSasUri, blobName);
    }
    

    Le code précédent utilise CloudBlobClient pour charger les fichiers de façon asynchrone. Il génère un fichier de ressources qui est ajouté à une liste qui sera utilisée par la tâche ajoutée lors de l’exercice suivant.

Activer l’accès au dossier de sortie

  1. Créez une référence de signature d’accès partagé (SAP) au conteneur de sortie dans lequel les tâches écrivent leurs fichiers :

    private static string GetContainerSasUrl(CloudBlobClient blobClient, string containerName, SharedAccessBlobPermissions permissions)
    {
        // Set the expiry time and permissions for the container access signature. In this case, no start time is specified,
        // so the shared access signature becomes valid immediately. Expiration is in 2 hours.
        SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(2),
            Permissions = permissions
        };
    
        // Generate the shared access signature on the container, setting the constraints directly on the signature
        CloudBlobContainer container = blobClient.GetContainerReference(containerName);
        string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);
    
        // Return the URL string for the container, including the SAS token
        return String.Format("{0}{1}", container.Uri, sasContainerToken);
    }
    

    Le code précédent crée une URL SAP avec un accès limité (deux heures) au cours duquel la tâche peut écrire les images GIF animées converties dans le stockage d’objets blob.

  2. Dans l’éditeur de code, cliquez avec le bouton droit et sélectionnez Enregistrer, puis cliquez avec le bouton droit et sélectionnez Quitter.

Tester le chargement de fichiers

  1. Dans Cloud Shell, créez un dossier InputFiles dans votre répertoire d’application :

    mkdir InputFiles
    
  2. Exécutez les commandes curl suivantes dans Cloud Shell pour copier un ensemble d’exemples de vidéos d’animaux à partir du dépôt GitHub du module dans le dossier InputFiles local.

    curl -L https://github.com/MicrosoftDocs/mslearn-apps-and-batch/raw/master/cutifypets/InputFiles/1.mp4 > ./InputFiles/1.mp4
    curl -L https://github.com/MicrosoftDocs/mslearn-apps-and-batch/raw/master/cutifypets/InputFiles/2.mp4 > ./InputFiles/2.mp4
    curl -L https://github.com/MicrosoftDocs/mslearn-apps-and-batch/raw/master/cutifypets/InputFiles/3.mp4 > ./InputFiles/3.mp4
    curl -L https://github.com/MicrosoftDocs/mslearn-apps-and-batch/raw/master/cutifypets/InputFiles/4.mp4 > ./InputFiles/4.mp4
    curl -L https://github.com/MicrosoftDocs/mslearn-apps-and-batch/raw/master/cutifypets/InputFiles/5.mp4 > ./InputFiles/5.mp4
    curl -L https://github.com/MicrosoftDocs/mslearn-apps-and-batch/raw/master/cutifypets/InputFiles/6.mp4 > ./InputFiles/6.mp4
    
  3. Enregistrez les informations d’identification Stockage Azure dans les variables d’environnement. La deuxième commande utilise la variable d’environnement RESOURCE_GROUP que nous avons définie dans la section Configurer les détails de connexion pour l’application de l’exercice précédent, Exercice : accédez à votre compte Batch à l’aide de la bibliothèque cliente .NET. La valeur est le nom du groupe de ressources que vous avez sélectionné lors de la création de votre compte Batch.

    export STORAGE_NAME=$(az storage account list --query "[?contains(name,'cuti')].name" --output tsv)
    export STORAGE_KEY=$(az storage account keys list --account-name $STORAGE_NAME --query [0].value --output tsv --resource-group $RESOURCE_GROUP)
    
  4. Générez et exécutez l’application :

    dotnet run
    
  5. Le programme doit s’exécuter et écrire les messages suivants dans le terminal :

    BATCH URL: [your batch url], Name: [your batch account name], Key: [your batch key]
    Storage Name: [your storage account name], Key: [your storage key]
    Creating container [input].
    Creating container [output].
    Uploading file ~\cutifypets\InputFiles\3.mp4 to container [input]...
    Uploading file ~\cutifypets\InputFiles\2.mp4 to container [input]...
    Uploading file ~\cutifypets\InputFiles\4.mp4 to container [input]...
    Uploading file ~\cutifypets\InputFiles\1.mp4 to container [input]...
    Uploading file ~\cutifypets\InputFiles\5.mp4 to container [input]...
    Uploading file ~\cutifypets\InputFiles\6.mp4 to container [input]...
    Creating pool [WinFFmpegPool]...
    

Vérifier les fichiers chargés à l’aide du portail Azure

  1. Retournez au Portail Azure. Dans le menu de gauche, sélectionnez Comptes de stockage, puis sélectionnez le compte de stockage que vous avez créé lors du premier exercice.

    Screenshot that shows a user's storage accounts.

  2. Dans le menu de gauche, sélectionnez Conteneurs sous Stockage de données, puis sélectionnez le dossier d’entrée.

    Screenshot that shows the created containers in blob storage.

  3. Le dossier contient les vidéos chargées.

    Screenshot that shows the uploaded video files.