Esercizio: Caricare le risorse che Batch deve usare tramite la libreria di archiviazione .NET
Importante
Per eseguire questo esercizio è necessario disporre di una propria sottoscrizione di Azure e questo potrebbe comportare dei costi. Se non hai ancora una sottoscrizione di Azure, crea un account gratuito prima di iniziare.
La libreria di Archiviazione di Azure consente di controllare a livello di codice l'archiviazione di file in un account di Archiviazione di Azure.
In questo esercizio si ottimizzerà l'app per caricare i video nell'archiviazione BLOB.
Aggiungere i dettagli di connessione dell'account di archiviazione
Aggiungere il pacchetto NuGet di Archiviazione BLOB di Azure in Cloud Shell:
dotnet add package Microsoft.Azure.Storage.Blob
Modificare il file
Program.cs
nell'editor:code Program.cs
Aggiungere le istruzioni using seguenti all'inizio di Program.cs per includere le librerie necessarie all'archiviazione:
using Microsoft.Azure.Storage.Blob; using Microsoft.Azure.Storage; using System.IO;
Microsoft.Azure.Storage.Blob
eMicrosoft.Azure.Storage
concedono all'app l'accesso all'account Archiviazione di Azure.System.IO
concede all'app l'accesso al file system per la gestione dei file.Aggiungere le variabili per le credenziali di Archiviazione di Azure per la classe
Program
in 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;
Creare un contenitore di input e di output
Sostituire
Main()
in Program.cs con l'aggiornamento seguente che aggiunge codice per gestire l'account di archiviazione: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); }
Nel codice precedente viene creato un oggetto
CloudStorageAccount
che consente all'app di generare un client BLOB. Il client viene usato per creare i contenitori di archiviazione, caricare i file e concedere l'accesso al processo per scrivere nel contenitore di output.
Creare contenitori di archiviazione per input e output di file
Aggiungere il metodo
CreateContainerIfNotExistAsync()
seguente per creare un contenitore con il nome specificato:private static async Task CreateContainerIfNotExistAsync(CloudBlobClient blobClient, string containerName) { CloudBlobContainer container = blobClient.GetContainerReference(containerName); await container.CreateIfNotExistsAsync(); Console.WriteLine("Creating container [{0}].", containerName); }
Il codice precedente usa l'oggetto
CloudBlobClient
creato nel metodoMain
per creare contenitori.
Elaborare l'elenco di tutti i file da caricare
Aggiungere il metodo
UploadFilesToContainerAsync()
seguente per caricare un elenco dei file di input nel contenitore: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; }
Il codice precedente usa l'elenco di percorsi file creato per chiamare un metodo e caricarli, poi archivia il riferimento ResourceFile generato che sarà usato dal processo di Batch.
Caricare i file
Aggiungere un metodo per caricare i file locali in Archiviazione di 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); }
Il codice precedente usa l'oggetto
CloudBlobClient
per caricare i file in modo asincrono. Crea un file di risorse che viene aggiunto a un elenco che sarà usato dall'attività aggiunta nel prossimo esercizio.
Abilitare l'accesso alla cartella di output
Creare un riferimento di firma di accesso condiviso (SAS) per il contenitore di output in cui le attività possono scrivere i file:
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); }
Il codice precedente crea un URL di firma di accesso condiviso con accesso limitato (due ore) per l'attività, che le consente di scrivere le GIF animate convertite nell'archiviazione BLOB.
Nell'editor di codice fare clic con il pulsante destro del mouse e scegliere Salva, quindi fare clic con il pulsante destro del mouse e scegliere Esci.
Testare i caricamenti dei file
In Cloud Shell creare una cartella InputFiles nella directory dell'app:
mkdir InputFiles
Eseguire il comando
curl
seguente in Cloud Shell per copiare un set di video di esempio degli animali dal repository GitHub del modulo nella cartella InputFiles locale.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
Salvare le credenziali di Archiviazione di Azure nelle variabili di ambiente. Il secondo comando usa la variabile di ambiente RESOURCE_GROUP definita nella sezione Configurare i dettagli di connessione per l'applicazione dell'esercizio precedente Esercizio: Accedere all'account Batch usando la libreria client .NET. Il valore è il nome del gruppo di risorse selezionato durante la creazione dell'account 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)
Compilare ed eseguire l'app:
dotnet run
Il programma eseguirà e scriverà i messaggi seguenti nel terminale:
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]...
Controllare i file caricati nel portale di Azure
Tornare al portale di Azure. Nel menu a sinistra selezionare Account di archiviazione, quindi selezionare l'account di archiviazione creato nel primo esercizio.
Nel menu a sinistra selezionare Contenitori in Archiviazione dati e quindi selezionare la cartella input.
La cartella contiene i video caricati.