Упражнение. Загрузка ресурсов для использования в пакетной обработке с помощью библиотеки для хранилища .NET.

Завершено

Важный

Для выполнения этого упражнения вам потребуется собственная подписка Azure, и могут взиматься сборы. Если у вас еще нет подписки Azure, создайте бесплатный аккаунт прежде чем начать.

Библиотека службы хранилища Azure позволяет программно управлять хранилищем файлов в учетной записи хранения Azure.

В этом упражнении мы расширим наше приложение, чтобы загружать видео в объектное хранилище.

Добавление сведений о подключении учетной записи хранения

  1. В Cloud Shell добавьте пакет NuGet для хранилища BLOB-объектов Azure.

    dotnet add package Microsoft.Azure.Storage.Blob
    
  2. Измените файл Program.cs в редакторе:

    code Program.cs
    
  3. Добавьте следующие инструкции using в верхнюю часть Program.cs, чтобы включить библиотеки, необходимые для работы хранилища:

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

    Microsoft.Azure.Storage.Blob и Microsoft.Azure.Storage предоставляют приложению доступ к учетной записи Azure Storage. System.IO предоставляет приложению доступ к файловой системе для обработки файлов.

  4. Добавьте переменные для учетных данных службы хранилища Azure в класс Program в 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;
    

Создание контейнера ввода и вывода

  1. Замените Main() в Program.cs следующим обновлением, которое добавляет код для управления учетной записью хранения:

    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);
    }
    

    В приведенном выше коде создается объект CloudStorageAccount, позволяющий приложению создать BLOB-клиент. Клиент используется для создания контейнеров хранилища, отправки файлов и предоставления доступа к заданию для записи в выходной контейнер.

Создание контейнеров хранилища для входных и выходных данных файлов

  1. Добавьте следующий метод, CreateContainerIfNotExistAsync(), чтобы создать контейнер с заданным именем:

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

    Приведенный выше код использует CloudBlobClient, созданный в методе Main для создания контейнеров.

Обработка списка всех файлов для отправки

  1. Добавьте следующий метод, UploadFilesToContainerAsync(), чтобы отправить список входных файлов в контейнер:

    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;
    }
    

    Приведенный выше код использует созданный список путей к файлам для вызова метода отправки и хранения созданной ссылки на ResourceFile для использования в пакетной задаче.

Отправка файлов

  1. Добавьте метод для отправки локальных файлов в хранилище 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);
    }
    

    Приведенный выше код использует CloudBlobClient для асинхронной отправки файлов. Он создает файл ресурсов, добавленный в список, который будет использоваться задачей, добавленной в следующее упражнение.

Включение доступа к выходной папке

  1. Создайте ссылку с маркером доступа (SAS) на выходной контейнер, чтобы задачи могли записывать в него свои файлы.

    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);
    }
    

    Приведенный выше код создает URL-адрес SAS с ограниченным доступом (два часа) для задачи, чтобы позволить записать преобразованные анимированные GIF-файлы в хранилище Blob.

  2. В редакторе кода щелкните правой кнопкой мыши и выберите Сохранить, а затем щелкните правой кнопкой мыши и выберите Выйти.

Проверка отправки файлов

  1. В Cloud Shell создайте папку InputFiles в каталоге приложения:

    mkdir InputFiles
    
  2. Выполните следующие команды curl в Cloud Shell, чтобы скопировать набор примеров видео домашних животных из репозитория GitHub модуля в локальную папку InputFiles.

    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. Сохраните учетные данные службы хранилища Azure в переменные среды. Вторая команда использует переменную среды RESOURCE_GROUP, которую мы определили в разделе Настройка сведений о подключении для приложения из предыдущего упражнения, Упражнение — доступ к учетной записи пакетной службы с помощью клиентской библиотеки .NET. Значение — это имя группы ресурсов, которое вы выбрали при создании аккаунта 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. Создайте и запустите приложение:

    dotnet run
    
  5. Программа должна запускаться и записывать в терминал следующие сообщения:

    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]...
    

Проверка файлов, отправленных с помощью портала Azure

  1. Вернитесь на портал Azure. В меню слева выберите учетные записи хранения, а затем выберите учетную запись хранения, созданную в первом упражнении.

    снимок экрана, на котором показаны учетные записи хранения пользователя.

  2. В меню слева выберите Контейнеры в разделе хранилище данных, а затем выберите папку ввода.

    снимок экрана, на котором показаны созданные контейнеры в хранилище объектов BLOB.

  3. Папка содержит загруженные видео.

    снимок экрана, на котором показаны загруженные видеофайлы.