Amazon Glacier で AWS SDK for .NETを使用してボールトインベントリをダウンロードする - Amazon Glacier

このページは、ボールトと 2012 年リリース当時の REST API を使用する、Amazon Glacier サービスの既存のお客様のみを対象としています。

アーカイブストレージソリューションをお探しの場合は、Amazon S3 の Amazon Glacier ストレージクラス (S3 Glacier Instant Retrieval、S3 Glacier Flexible Retrieval、S3 Glacier Deep Archive) を使用することをお勧めします。これらのストレージオプションの詳細については、「Amazon Glacier ストレージクラス」を参照してください。

Amazon Glacier (元のスタンドアロンのボールトベースのサービス) は、2025 年 12 月 15 日以降、新規のお客様を受け入れなくなります。既存のお客様に影響はありません。Amazon Glacier は、ボールトにデータを保存する独自の API を備えたスタンドアロンサービスであり、Amazon S3 および Amazon S3 Glacier ストレージクラスとは異なります。既存のデータは Amazon Glacier で無期限に安全性が確保され、引き続きアクセス可能です。移行は必要ありません。低コストの長期アーカイブストレージをお探しの場合、AWS は Amazon S3 Glacier ストレージクラスを推奨します。このストレージクラスは、コストを抑えながら、S3 バケットベースの API、AWS リージョン全体での可用性、AWS サービス統合により、優れたカスタマーエクスペリエンスを提供します。拡張機能が必要な場合は、Amazon Glacier ボールトから Amazon S3 Glacier ストレージクラスにデータを転送するための AWS ソリューションガイダンスを使用して、Amazon S3 Glacier ストレージクラスへの移行を検討してください。

Amazon Glacier で AWS SDK for .NETを使用してボールトインベントリをダウンロードする

以下に、AWS SDK for .NET の低レベル API を使用してボールトインベントリを取得する手順を示します。高レベル API では、ボールトインベントリの取得はサポートされていません。

  1. AmazonGlacierClient クラスのインスタンス(クライアント)を作成します。

    ボールトが属する AWS リージョンを指定する必要があります。このクライアントを使用して実行するすべてのオペレーションは、そのAWSリージョンに適用されます。

  2. InitiateJob メソッドを実行してインベントリの取得ジョブを開始します。

    InitiateJobRequestオブジェクトでジョブ情報を指定します。Amazon Glacier (Amazon Glacier) は、レスポンスとしてジョブ ID を返します。レスポンスは、InitiateJobResponse クラスのインスタンスで使用できます。

    AmazonGlacierClient client; client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2); InitiateJobRequest initJobRequest = new InitiateJobRequest() { VaultName = vaultName, JobParameters = new JobParameters() { Type = "inventory-retrieval", SNSTopic = "*** Provide Amazon SNS topic arn ***", } }; InitiateJobResponse initJobResponse = client.InitiateJob(initJobRequest); string jobId = initJobResponse.JobId;
  3. ジョブが完了するまで待ちます。

    ジョブの出力をダウンロードする準備が整うまで待つ必要があります。ボールトの通知設定により Amazon Simple Notification Service (Amazon SNS) トピックを指定している場合、またはジョブを開始したときに Amazon SNS トピックを指定している場合は、ジョブの完了後に Amazon Glacier によりそのトピックにメッセージが送信されます。以下のセクションに示しているコード例では、Amazon SNS を使用して、Amazon Glacier でメッセージを発行します。

    また、DescribeJob メソッドを呼び出して Amazon Glacier にポーリングすることで、ジョブの完了ステータスを調べることもできます。ただし、通知のために Amazon SNS トピックを使用することをお勧めします。

  4. GetJobOutput メソッドを実行し、ジョブの出力 (ボールトインベントリデータ) をダウンロードします。

    GetJobOutputRequest クラスのインスタンスを作成して、アカウント ID、ボールト名、およびジョブ ID 情報を指定します。アカウント ID を指定しなかった場合には、リクエストに署名する際に使用した認証情報に関連付けられているアカウント ID が使用されます。詳細については、「Amazon Glacier でのAWS SDK for .NET の使用」を参照してください。

    Amazon Glacier により返される出力は GetJobOutputResponse オブジェクトで使用できます。

    GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() { JobId = jobId, VaultName = vaultName }; GetJobOutputResponse getJobOutputResponse = client.GetJobOutput(getJobOutputRequest); using (Stream webStream = getJobOutputResponse.Body) { using (Stream fileToSave = File.OpenWrite(fileName)) { CopyStream(webStream, fileToSave); } }

    注記

    基本となるジョブ関連の REST API の詳細については、「ジョブのオペレーション」を参照してください。

例: AWS SDK for .NET の低レベル API を使用してボールトインベントリを取得する

次の C# コード例では、指定されたボールトのボールトインベントリを取得します。

この例では次のタスクを実行しています。

  • Amazon SNS トピックを設定します。

    Amazon Glacier は、ジョブの完了後、このトピックに通知を送信します。

  • Amazon SQS キューを設定する。

    この例では、ポリシーをキューにアタッチして、Amazon SNS トピックでメッセージを投稿できるようにします。

  • 指定したアーカイブをダウンロードするジョブを開始します。

    この例では、ジョブのリクエストとして、Amazon Glacier によりジョブの完了後にメッセージが送信されるように Amazon SNS トピックを指定します。

  • Amazon SQS キューにメッセージがあるかどうかを定期的に確認します。

    メッセージがある場合は、JSON を解析し、ジョブが正常に完了したかどうかを確認します。正常に完了している場合は、アーカイブをダウンロードします。コード例では、JSON.NET ライブラリ (JSON.NET 参照) を使用して JSON を解析しています。

  • Amazon SNS トピックおよび作成された Amazon SQS キューを削除して、クリーンアップします。

using System; using System.Collections.Generic; using System.IO; using System.Threading; using Amazon.Glacier; using Amazon.Glacier.Model; using Amazon.Glacier.Transfer; using Amazon.Runtime; using Amazon.SimpleNotificationService; using Amazon.SimpleNotificationService.Model; using Amazon.SQS; using Amazon.SQS.Model; using Newtonsoft.Json; namespace glacier.amazon.com.rproxy.govskope.ca.docsamples { class VaultInventoryJobLowLevelUsingSNSSQS { static string topicArn; static string queueUrl; static string queueArn; static string vaultName = "*** Provide vault name ***"; static string fileName = "*** Provide file name and path where to store inventory ***"; static AmazonSimpleNotificationServiceClient snsClient; static AmazonSQSClient sqsClient; const string SQS_POLICY = "{" + " \"Version\" : \"2012-10-17\",&TCX5-2025-waiver;" + " \"Statement\" : [" + " {" + " \"Sid\" : \"sns-rule\"," + " \"Effect\" : \"Allow\"," + " \"Principal\" : {\"AWS\" : \"arn:aws:iam::123456789012:root\" }," + " \"Action\" : \"sqs:SendMessage\"," + " \"Resource\" : \"{QuernArn}\"," + " \"Condition\" : {" + " \"ArnLike\" : {" + " \"aws:SourceArn\" : \"{TopicArn}\"" + " }" + " }" + " }" + " ]" + "}"; public static void Main(string[] args) { AmazonGlacierClient client; try { using (client = new AmazonGlacierClient(Amazon.RegionEndpoint.USWest2)) { Console.WriteLine("Setup SNS topic and SQS queue."); SetupTopicAndQueue(); Console.WriteLine("To continue, press Enter"); Console.ReadKey(); Console.WriteLine("Retrieve Inventory List"); GetVaultInventory(client); } Console.WriteLine("Operations successful."); Console.WriteLine("To continue, press Enter"); Console.ReadKey(); } catch (AmazonGlacierException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } finally { // Delete SNS topic and SQS queue. snsClient.DeleteTopic(new DeleteTopicRequest() { TopicArn = topicArn }); sqsClient.DeleteQueue(new DeleteQueueRequest() { QueueUrl = queueUrl }); } } static void SetupTopicAndQueue() { long ticks = DateTime.Now.Ticks; // Setup SNS topic. snsClient = new AmazonSimpleNotificationServiceClient(Amazon.RegionEndpoint.USWest2); sqsClient = new AmazonSQSClient(Amazon.RegionEndpoint.USWest2); topicArn = snsClient.CreateTopic(new CreateTopicRequest { Name = "GlacierDownload-" + ticks }).TopicArn; Console.Write("topicArn: "); Console.WriteLine(topicArn); CreateQueueRequest createQueueRequest = new CreateQueueRequest(); createQueueRequest.QueueName = "GlacierDownload-" + ticks; CreateQueueResponse createQueueResponse = sqsClient.CreateQueue(createQueueRequest); queueUrl = createQueueResponse.QueueUrl; Console.Write("QueueURL: "); Console.WriteLine(queueUrl); GetQueueAttributesRequest getQueueAttributesRequest = new GetQueueAttributesRequest(); getQueueAttributesRequest.AttributeNames = new List<string> { "QueueArn" }; getQueueAttributesRequest.QueueUrl = queueUrl; GetQueueAttributesResponse response = sqsClient.GetQueueAttributes(getQueueAttributesRequest); queueArn = response.QueueARN; Console.Write("QueueArn: ");Console.WriteLine(queueArn); // Setup the Amazon SNS topic to publish to the SQS queue. snsClient.Subscribe(new SubscribeRequest() { Protocol = "sqs", Endpoint = queueArn, TopicArn = topicArn }); // Add the policy to the queue so SNS can send messages to the queue. var policy = SQS_POLICY.Replace("{TopicArn}", topicArn).Replace("{QuernArn}", queueArn); sqsClient.SetQueueAttributes(new SetQueueAttributesRequest() { QueueUrl = queueUrl, Attributes = new Dictionary<string, string> { { QueueAttributeName.Policy, policy } } }); } static void GetVaultInventory(AmazonGlacierClient client) { // Initiate job. InitiateJobRequest initJobRequest = new InitiateJobRequest() { VaultName = vaultName, JobParameters = new JobParameters() { Type = "inventory-retrieval", Description = "This job is to download a vault inventory.", SNSTopic = topicArn, } }; InitiateJobResponse initJobResponse = client.InitiateJob(initJobRequest); string jobId = initJobResponse.JobId; // Check queue for a message and if job completed successfully, download inventory. ProcessQueue(jobId, client); } private static void ProcessQueue(string jobId, AmazonGlacierClient client) { ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest() { QueueUrl = queueUrl, MaxNumberOfMessages = 1 }; bool jobDone = false; while (!jobDone) { Console.WriteLine("Poll SQS queue"); ReceiveMessageResponse receiveMessageResponse = sqsClient.ReceiveMessage(receiveMessageRequest); if (receiveMessageResponse.Messages.Count == 0) { Thread.Sleep(10000 * 60); continue; } Console.WriteLine("Got message"); Message message = receiveMessageResponse.Messages[0]; Dictionary<string, string> outerLayer = JsonConvert.DeserializeObject<Dictionary<string, string>>(message.Body); Dictionary<string, object> fields = JsonConvert.DeserializeObject<Dictionary<string, object>>(outerLayer["Message"]); string statusCode = fields["StatusCode"] as string; if (string.Equals(statusCode, GlacierUtils.JOB_STATUS_SUCCEEDED, StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("Downloading job output"); DownloadOutput(jobId, client); // Save job output to the specified file location. } else if (string.Equals(statusCode, GlacierUtils.JOB_STATUS_FAILED, StringComparison.InvariantCultureIgnoreCase)) Console.WriteLine("Job failed... cannot download the inventory."); jobDone = true; sqsClient.DeleteMessage(new DeleteMessageRequest() { QueueUrl = queueUrl, ReceiptHandle = message.ReceiptHandle }); } } private static void DownloadOutput(string jobId, AmazonGlacierClient client) { GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() { JobId = jobId, VaultName = vaultName }; GetJobOutputResponse getJobOutputResponse = client.GetJobOutput(getJobOutputRequest); using (Stream webStream = getJobOutputResponse.Body) { using (Stream fileToSave = File.OpenWrite(fileName)) { CopyStream(webStream, fileToSave); } } } public static void CopyStream(Stream input, Stream output) { byte[] buffer = new byte[65536]; int length; while ((length = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, length); } } } }