Amazon S3 Glacier
開発者ガイド (API バージョン 2012-06-01)

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

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

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

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

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

    InitiateJobRequest オブジェクトでジョブ情報を指定します。Amazon S3 Glacier (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 トピックを指定している場合は、ジョブの完了後に Glacier によりそのトピックにメッセージが送信されます。以下のセクションに示しているコード例では、Amazon SNS を使用して、Glacier でメッセージを発行します。

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

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

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

    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 トピックを設定します。

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

  • Amazon SQS キューを設定します。

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

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

    この例では、ジョブのリクエストとして、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.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\"," + " \"Statement\" : [" + " {" + " \"Sid\" : \"sns-rule\"," + " \"Effect\" : \"Allow\"," + " \"Principal\" : \"*\"," + " \"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); } } } }