Exercício – carregar recursos para serem utilizados por um Batch com a biblioteca de armazenamento .NET
Importante
Precisa da sua própria subscrição do Azure para executar este exercício e poderá incorrer em custos. Se ainda não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
A biblioteca do Armazenamento do Azure permite-lhe controlar de forma programática o armazenamento de ficheiros numa conta de Armazenamento do Azure.
Neste exercício, vamos melhorar a nossa aplicação para carregar vídeos para o armazenamento de blobs.
Adicionar detalhes da ligação da conta de armazenamento
No Cloud Shell, adicione o pacote NuGet de armazenamento de Blob do Azure:
dotnet add package Microsoft.Azure.Storage.Blob
Edite o ficheiro
Program.cs
no editor:code Program.cs
Adicione as seguintes instruções using à parte superior do Program.cs para incluir as bibliotecas de que nosso trabalho de armazenamento precisa:
using Microsoft.Azure.Storage.Blob; using Microsoft.Azure.Storage; using System.IO;
Microsoft.Azure.Storage.Blob
eMicrosoft.Azure.Storage
dão à aplicação acesso à conta de Armazenamento do Azure.System.IO
dá à aplicação acesso ao sistema de ficheiros para processamento de ficheiros.Adicione variáveis para as credenciais de Armazenamento do
Program
Azure à classe em 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;
Criar um contentor de entrada e saída
Substitua
Main()
no Program.cs pela seguinte atualização, que adiciona código para gerenciar a conta de armazenamento: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); }
No código anterior, um
CloudStorageAccount
objeto é criado para permitir que o aplicativo crie um cliente de blob. O cliente é utilizado para criar os contentores de armazenamento, carregar os ficheiros e dar acesso ao trabalho para escrever no contentor de saída.
Criar contentores de armazenamento para a entrada e saída de ficheiros
Adicione o seguinte método,
CreateContainerIfNotExistAsync()
, para criar um contêiner com o nome próprio:private static async Task CreateContainerIfNotExistAsync(CloudBlobClient blobClient, string containerName) { CloudBlobContainer container = blobClient.GetContainerReference(containerName); await container.CreateIfNotExistsAsync(); Console.WriteLine("Creating container [{0}].", containerName); }
O código anterior usa o
CloudBlobClient
criado noMain
método para criar contêineres.
Processar a lista de todos os ficheiros a carregar
Adicione o seguinte método,
UploadFilesToContainerAsync()
, para carregar uma lista de arquivos de entrada para o contêiner: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; }
O código anterior usa a lista criada de caminhos de arquivo para chamar um método para carregá-los e armazenar a referência ResourceFile produzida para uso pelo trabalho em lote.
Carregar os ficheiros
Adicione um método para carregar os arquivos locais no armazenamento do 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); }
O código anterior usa o para carregar os arquivos de forma assíncrona
CloudBlobClient
. Ele cria um arquivo de recurso que é adicionado a uma lista que a tarefa adicionada no próximo exercício usará.
Ativar o acesso à pasta de saída
Crie uma referência SAS (Assinatura de Acesso Compartilhado) ao contêiner de saída para tarefas para gravar seus arquivos em:
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); }
O código anterior cria um URL SAS com acesso limitado (duas horas) para a tarefa para permitir que ela escreva os GIFs animados convertidos no armazenamento de Blob.
No editor de códigos, clique com o botão direito do mouse e selecione Salvar, clique com o botão direito do mouse e selecione Sair.
Testar os carregamentos de ficheiros
No Cloud Shell, crie uma pasta InputFiles no diretório do aplicativo:
mkdir InputFiles
Execute os seguintes comandos
curl
no Cloud Shell para copiar um conjunto de exemplo de vídeos de animais do repositório GitHub do módulo para a pasta 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
Guarde as credenciais do Armazenamento do Azure em variáveis de ambiente. O segundo comando consiste em utilizar a variável de ambiente RESOURCE_GROUP que definimos na secção Configurar detalhes de ligação da aplicação do exercício anterior, Exercício – aceder à conta do Batch com a biblioteca de cliente do .NET. O valor é o nome do grupo de recursos que você selecionou quando criou sua conta de lote.
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)
Crie e execute o aplicativo:
dotnet run
O programa deve executar e escrever as seguintes mensagens no 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]...
Verificar os ficheiros carregados com o portal do Azure
Regresse ao portal do Azure. No menu à esquerda, selecione Contas de armazenamento e, em seguida, selecione a conta de armazenamento criada no primeiro exercício.
No menu à esquerda, selecione Contêineres em Armazenamento de dados e, em seguida, selecione a pasta de entrada.
A pasta contém os vídeos carregados.