Ejercicio: Carga de los recursos que va a usar un lote con la biblioteca de almacenamiento de .NET
Importante
Para realizar este ejercicio, se necesita una suscripción de Azure propia y puede que se apliquen cargos. Si aún no tiene una suscripción de Azure, cree una cuenta gratuita antes de comenzar.
La biblioteca de Azure Storage permite controlar mediante programación el almacenamiento de archivos en una cuenta de Azure Storage.
En este ejercicio, se mejorará la aplicación para cargar vídeos al almacenamiento de blobs.
Adición de los detalles de conexión de la cuenta de almacenamiento
En Cloud Shell, agregue el paquete NuGet de Azure Blob Storage:
dotnet add package Microsoft.Azure.Storage.Blob
Modifique el archivo
Program.cs
en el editor:code Program.cs
Agregue las siguientes instrucciones using a la parte superior de Program.cs para incluir las bibliotecas necesarias para el trabajo de almacenamiento:
using Microsoft.Azure.Storage.Blob; using Microsoft.Azure.Storage; using System.IO;
Microsoft.Azure.Storage.Blob
yMicrosoft.Azure.Storage
ofrecen acceso a la aplicación a la cuenta de Azure Storage.System.IO
proporciona acceso a la aplicación al sistema de archivos para el control de los archivos.Agregue variables para las credenciales de Azure Storage a la clase
Program
de 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;
Creación de un contenedor de entrada y salida
En Program.cs, reemplace
Main()
con la actualización siguiente, que agrega código para administrar la cuenta de almacenamiento: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); }
En el código anterior, se crea un objeto
CloudStorageAccount
para permitir que la aplicación cree un cliente de blob. El cliente se usa para crear los contenedores de almacenamiento, cargar los archivos y conceder acceso al trabajo para escribir en el contenedor de salida.
Creación de contenedores de almacenamiento para la entrada y salida de archivos
Agregue el método siguiente,
CreateContainerIfNotExistAsync()
, para crear un contenedor con el nombre especificado:private static async Task CreateContainerIfNotExistAsync(CloudBlobClient blobClient, string containerName) { CloudBlobContainer container = blobClient.GetContainerReference(containerName); await container.CreateIfNotExistsAsync(); Console.WriteLine("Creating container [{0}].", containerName); }
En el código anterior se usa el objeto
CloudBlobClient
creado en el métodoMain
para crear contenedores.
Procesamiento de la lista de todos los archivos para cargar
Agregue el método siguiente,
UploadFilesToContainerAsync()
, para cargar una lista de archivos de entrada en el contenedor: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; }
En el código anterior se usa la lista creada de rutas de archivo para llamar a un método para cargarlas y almacenar la referencia ResourceFile generada para que la use el trabajo de Batch.
Carga de los archivos
Agregue un método para cargar los archivos locales en Azure Storage:
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); }
En el código anterior se usa
CloudBlobClient
para cargar los archivos de forma asincrónica. Crea un archivo de recursos que se agrega a una lista que usará la tarea añadida en el siguiente ejercicio.
Habilitación del acceso a la carpeta de salida
Cree una referencia de Firma de acceso compartido (SAS) al contenedor de salida en el que las tareas escribirán sus archivos:
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); }
En el código anterior se crea una dirección URL SAS con acceso limitado (dos horas) para que la tarea pueda escribir los GIF animados convertidos en el almacenamiento de blobs.
En el editor de código, haga clic con el botón derecho y seleccione Guardar, después haga clic con el botón derecho y seleccione Salir.
Prueba de las cargas de archivo
En Cloud Shell, cree una carpeta InputFiles en el directorio de la aplicación:
mkdir InputFiles
Ejecute los comandos
curl
siguientes en Cloud Shell para copiar un conjunto de vídeos de mascotas de ejemplo desde el repositorio de GitHub del módulo en la carpeta 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 las credenciales de Azure Storage en variables de entorno. El segundo comando usa la variable de entorno RESOURCE_GROUP que se definió en la sección Configuración de los detalles de conexión para la aplicación del ejercicio anterior, Ejercicio: Acceso a la cuenta de Batch mediante la biblioteca cliente de .NET. El valor es el nombre del grupo de recursos que seleccionó cuando creó su cuenta de 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)
Compile y ejecute la aplicación:
dotnet run
El programa debe ejecutar y escribir los mensajes siguientes en el 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]...
Comprobación de los archivos cargados mediante Azure Portal
Vuelva a Azure Portal. En el menú de la izquierda, seleccione Cuentas de almacenamiento, después seleccione la cuenta de almacenamiento que creó en el primer ejercicio.
En el menú de la izquierda, seleccione Contenedores en Almacenamiento de datos, después seleccione la carpeta entrada.
La carpeta contiene los vídeos cargados.