演習 - Batch で使用するリソースを .NET ストレージ ライブラリでアップロードする

完了

重要

この演習を行うには、独自の Azure サブスクリプションが必要です。また、料金が発生することがあります。 Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。

Azure Storage ライブラリを利用することで、Azure Storage アカウントにあるファイル ストレージをプログラムで制御できます。

この演習では、アプリを強化し、Blob Storage に動画をアップロードします。

ストレージ アカウント接続の詳細を追加する

  1. Cloud Shell で、Azure Blob Storage NuGet パッケージを追加します。

    dotnet add package Microsoft.Azure.Storage.Blob
    
  2. エディターで Program.cs ファイルを編集します。

    code Program.cs
    
  3. Program.cs の一番上に次の using ステートメントを追加し、今回のストレージ作業で必要となるライブラリを含めます。

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

    Microsoft.Azure.Storage.BlobMicrosoft.Azure.Storage からアプリに Azure Storage アカウントへのアクセス権限が与えられます。 System.IO からアプリにファイル処理のためのファイル システムへのアクセス権限が与えられます。

  4. Program.csProgram クラスに Azure Storage 資格情報の変数を追加します。

    // Storage account credentials
    private const string envVarStorage = "STORAGE_NAME";
    private const string envVarStorageKey = "STORAGE_KEY";
    private static string storageAccountName;
    private static string storageAccountKey;
    

入力および出力コンテナーを作成する

  1. Program.csMain() を次のアップデートで置換します。これにより、ストレージ アカウントを管理するコードが追加されます。

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

    上記のコードでは、アプリで BLOB クライアントを作成できるように CloudStorageAccount オブジェクトが作成されます。 クライアントは、ストレージ コンテナーを作成する、ファイルをアップロードする、出力コンテナーに書き込む権限をジョブに与えるために使用されます。

ファイルの入力と出力のためにストレージ コンテナーを作成する

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

    上記のコードでは、Main メソッドで作成された CloudBlobClient を使用してコンテナーが作成されます。

アップロードするすべてのファイルの一覧を処理する

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

    上記のコードでは、CloudBlobClient を使用して非同期でファイルをアップロードします。 これにより次の演習で追加されるタスクで使用するリストに追加されるリソース ファイルが構築されます。

出力フォルダーへのアクセスを有効にする

  1. タスクのファイルの書き込み先となる出力コンテナーへの Shared Access Signature (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);
    }
    

    上記のコードでは、アクセスが限定された (2 時間) SAS URL が作成されます。タスクではこの時間内に、変換後のアニメーション GIF を Blob Storage に書き込むことができます。

  2. コード エディターで、右クリックして [保存] を選び、さらに右クリックして [終了] を選びます。

ファイル アップロードをテストする

  1. Cloud Shell で、自分のアプリ ディレクトリに InputFiles フォルダーを作成します。

    mkdir InputFiles
    
  2. Cloud Shell で次の curl コマンドを実行し、モジュールの 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 Storage の資格情報を環境変数に保存します。 2 番目のコマンドでは RESOURCE_GROUP 環境変数が使用されています。これは、前の演習「演習 - .NET クライアント ライブラリを使用し、Batch アカウントにアクセスする」の「アプリケーションの接続詳細を設定する」セクションで定義したものです。 その値は、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 portal を使用してアップロードされたファイルを確認する

  1. Azure Portal に戻ります。 左側のメニューで、[ストレージ アカウント] を選び、最初の演習で作成したストレージ アカウントを選びます。

    Screenshot that shows a user's storage accounts.

  2. 左側のメニューで、[データ ストレージ] の下の [コンテナー] を選び、input フォルダーを選びます。

    Screenshot that shows the created containers in blob storage.

  3. フォルダーにはアップロードされた動画が含まれます。

    Screenshot that shows the uploaded video files.