Esercizio: Caricare le risorse che Batch deve usare tramite la libreria di archiviazione .NET

Completato

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

  1. Aggiungere il pacchetto NuGet di Archiviazione BLOB di Azure in Cloud Shell:

    dotnet add package Microsoft.Azure.Storage.Blob
    
  2. Modificare il file Program.cs nell'editor:

    code Program.cs
    
  3. 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 e Microsoft.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.

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

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

  1. 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 metodo Main per creare contenitori.

Elaborare l'elenco di tutti i file da caricare

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

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

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

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

  1. In Cloud Shell creare una cartella InputFiles nella directory dell'app:

    mkdir InputFiles
    
  2. 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
    
  3. 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)
    
  4. Compilare ed eseguire l'app:

    dotnet run
    
  5. 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

  1. Tornare al portale di Azure. Nel menu a sinistra selezionare Account di archiviazione, quindi selezionare l'account di archiviazione creato nel primo esercizio.

    Screenshot that shows a user's storage accounts.

  2. Nel menu a sinistra selezionare Contenitori in Archiviazione dati e quindi selezionare la cartella input.

    Screenshot that shows the created containers in blob storage.

  3. La cartella contiene i video caricati.

    Screenshot that shows the uploaded video files.