Herunterladen eines Archivs in Amazon S3 Glacier mithilfe der AWS SDK for Java - Amazon S3 Glacier

Diese Seite richtet sich nur an Bestandskunden des S3 Glacier-Dienstes, die Vaults und das Original REST API von 2012 verwenden.

Wenn Sie nach Archivspeicherlösungen suchen, empfehlen wir die Verwendung der S3 Glacier-Speicherklassen in Amazon S3, S3 Glacier Instant Retrieval, S3 Glacier Flexible Retrieval und S3 Glacier Deep Archive. Weitere Informationen zu diesen Speicheroptionen finden Sie unter S3 Glacier-Speicherklassen und Langfristige Datenspeicherung mit S3 Glacier-Speicherklassen im Amazon S3 S3-Benutzerhandbuch. Diese Speicherklassen verwenden Amazon S3API, sind in allen Regionen verfügbar und können in der Amazon S3 S3-Konsole verwaltet werden. Sie bieten Funktionen wie Speicherkostenanalyse, Storage Lens, erweiterte optionale Verschlüsselungsfunktionen und mehr.

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Herunterladen eines Archivs in Amazon S3 Glacier mithilfe der AWS SDK for Java

Sowohl die High-Level- als auch die Low-Level-API, die vom Amazon-SDK für Java bereitgestellt werden, bieten eine Methode zum Herunterladen eines Archivs.

Herunterladen eines Archivs mit der High-Level-API von AWS SDK for Java

Die ArchiveTransferManager-Klasse der High-Level-API bietet die download-Methode, mit der Sie ein Archiv herunterladen können.

Wichtig

Die ArchiveTransferManager-Klasse erstellt ein Amazon Simple Notification Service (Amazon SNS)-Thema und eine Amazon Simple Queue Service (Amazon SQS)-Warteschlange, die dieses Thema abonniert hat. Die Klasse initiiert daraufhin den Abrufauftrag für das Archiv und fragt die Warteschlange für das Archiv nach der Verfügbarkeit ab. Wenn das Archiv verfügbar ist, beginnt der Download. Weitere Informationen zu Abrufzeiten finden Sie unter Archiv-Abrufoptionen.

Beispiel: Herunterladen eines Archivs mithilfe der High-Level-API von AWS SDK for Java

Mit dem folgenden Java-Beispielcode wird ein Archiv aus einem Tresor („examplevault“) in der Region „USA West (Oregon)“ („us-west-2“) heruntergeladen.

Schritt-für-Schritt-Anleitungen für die Ausführung dieses Beispiels finden Sie unter Ausführen von Java-Beispielen für Amazon S3 Glacier unter Verwendung von Eclipse. Sie müssen den Code wie gezeigt mit einer vorhandenen Archiv-ID und dem lokalen Dateipfad zum Speicherort des heruntergeladenen Archivs aktualisieren.

import java.io.File; import java.io.IOException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.glacier.AmazonGlacierClient; import com.amazonaws.services.glacier.transfer.ArchiveTransferManager; import com.amazonaws.services.sns.AmazonSNSClient; import com.amazonaws.services.sqs.AmazonSQSClient; public class ArchiveDownloadHighLevel { public static String vaultName = "examplevault"; public static String archiveId = "*** provide archive ID ***"; public static String downloadFilePath = "*** provide location to download archive ***"; public static AmazonGlacierClient glacierClient; public static AmazonSQSClient sqsClient; public static AmazonSNSClient snsClient; public static void main(String[] args) throws IOException { ProfileCredentialsProvider credentials = new ProfileCredentialsProvider(); glacierClient = new AmazonGlacierClient(credentials); sqsClient = new AmazonSQSClient(credentials); snsClient = new AmazonSNSClient(credentials); glacierClient.setEndpoint("glacier.us-west-2.amazonaws.com"); sqsClient.setEndpoint("sqs.us-west-2.amazonaws.com"); snsClient.setEndpoint("sns.us-west-2.amazonaws.com"); try { ArchiveTransferManager atm = new ArchiveTransferManager(glacierClient, sqsClient, snsClient); atm.download(vaultName, archiveId, new File(downloadFilePath)); System.out.println("Downloaded file to " + downloadFilePath); } catch (Exception e) { System.err.println(e); } } }

Herunterladen eines Archivs mit der Low-Level-API von AWS SDK for Java

Nachfolgend werden die Schritte zum Abrufen eines Tresorbestands mithilfe der Low-Level-API für AWS SDK for Java beschrieben.

  1. Erstellen einer Instance der AmazonGlacierClient-Klasse (Client).

    Sie müssen die AWS-Region angeben, aus der das Archiv heruntergeladen werden soll. Alle Operationen, die Sie mit diesem Client ausführen, gelten für diese AWS-Region.

  2. Initiieren eines mehrteiligen archive-retrieval-Auftrags durch Ausführen der initiateJob-Methode.

    Sie stellen Auftragsinformationen bereit, beispielsweise die Archiv-ID des herunterzuladenden Archivs und optional das Amazon-SNS-Thema, an das Amazon S3 Glacier (S3 Glacier) bei Beendigung des Auftrags eine Nachricht übermitteln soll, indem Sie eine Instance der InitiateJobRequest-Klasse erstellen. S3 Glacier gibt als Antwort eine Auftrags-ID zurück. Die Antwort ist in einer Instance der InitiateJobResult-Klasse verfügbar.

    JobParameters jobParameters = new JobParameters() .withArchiveId("*** provide an archive id ***") .withDescription("archive retrieval") .withRetrievalByteRange("*** provide a retrieval range***") // optional .withType("archive-retrieval"); InitiateJobResult initiateJobResult = client.initiateJob(new InitiateJobRequest() .withJobParameters(jobParameters) .withVaultName(vaultName)); String jobId = initiateJobResult.getJobId();

    Optional können Sie einen Byte-Bereich angeben, um von S3 Glacier anzufordern, dass nur ein Teil des Archivs vorbereitet wird. Sie können beispielsweise die vorherige Anforderung aktualisieren, indem Sie die folgende Anweisung hinzufügen und von S3 Glacier nur die Vorbereitung des Archivteils zwischen 1  und 2 MB anfordern.

    int ONE_MEG = 1048576; String retrievalByteRange = String.format("%s-%s", ONE_MEG, 2*ONE_MEG -1); JobParameters jobParameters = new JobParameters() .withType("archive-retrieval") .withArchiveId(archiveId) .withRetrievalByteRange(retrievalByteRange) .withSNSTopic(snsTopicARN); InitiateJobResult initiateJobResult = client.initiateJob(new InitiateJobRequest() .withJobParameters(jobParameters) .withVaultName(vaultName)); String jobId = initiateJobResult.getJobId();

  3. Warten Sie, bis der Auftrag abgeschlossen wurde.

    Sie müssen warten, bis die Ausgabe des Auftrags zum Download bereit ist. Wenn Sie eine Benachrichtigungskonfiguration für den Tresor eingerichtet haben, in der ein Amazon Simple Notification Service (Amazon SNS)-Thema angegeben ist, oder beim Initiieren des Auftrags ein Amazon-SNS-Thema angegeben haben, sendet S3 Glacier nach Beenden des Auftrags eine Benachrichtigung an das Thema.

    Sie können S3 Glacier auch durch einen Aufruf der describeJob-Methode abfragen, um den Abschlussstatus des Auftrags zu ermitteln. Allerdings wird die Verwendung eines Amazon-SNS-Themas für Benachrichtigungen empfohlen.

  4. Laden Sie die Auftragsausgabe (Archivdaten) herunter, indem Sie die getJobOutput-Methode ausführen.

    Sie erstellen eine Instance der GetJobOutputRequest-Klasse, um die Informationen in der Anforderung, wie beispielsweise die Auftrags-ID und den Tresornamen, bereitzustellen. Die von S3 Glacier zurückgegebene Ausgabe ist im GetJobOutputResult-Objekt verfügbar.

    GetJobOutputRequest jobOutputRequest = new GetJobOutputRequest() .withJobId("*** provide a job ID ***") .withVaultName("*** provide a vault name ****"); GetJobOutputResult jobOutputResult = client.getJobOutput(jobOutputRequest); // jobOutputResult.getBody() // Provides the input stream.

    Mit dem vorherigen Codeabschnitt wird die gesamte Auftragsausgabe heruntergeladen. Sie können optional nur einen Teil der Ausgabe abrufen oder die gesamte Ausgabe in kleineren Datenblöcken herunterladen, indem Sie den Bytebereich für GetJobOutputRequest angeben.

    GetJobOutputRequest jobOutputRequest = new GetJobOutputRequest() .withJobId("*** provide a job ID ***") .withRange("bytes=0-1048575") // Download only the first 1 MB of the output. .withVaultName("*** provide a vault name ****");

    Als Reaktion auf Ihren GetJobOutput-Aufruf gibt S3 Glacier die Prüfsumme für den heruntergeladenen Teil der Daten zurück, sofern bestimmte Bedingungen erfüllt sind. Weitere Informationen finden Sie unter Erhalten von Prüfsummen bei Daten-Download.

    Zum Überprüfen, dass der Downloads fehlerfrei erfolgt ist, können Sie anschließend auf Client-Seite die Prüfsumme berechnen und mit der von S3 Glacier in der Antwort gesendeten Prüfsumme vergleichen.

    Bei einem Auftrag zum Abrufen eines Archivs, bei dem ein optionaler Bereich angegeben ist, ist die Prüfsumme des abgerufenen Bereichs (SHA256TreeHash) in der Auftragsbeschreibung enthalten. Mit diesem Wert können Sie die Genauigkeit des gesamten später herunterzuladenden Byte-Bereichs weiter überprüfen. Sie können beispielsweise einen Auftrag initiieren, durch den zuerst ein mit dem Struktur-Hash abgeglichener Bereich abgerufen und dann die Ausgabe in Datenblöcken so heruntergeladen wird, dass für jede der GetJobOutput-Anforderungen eine Prüfsumme zurückgegeben wird. Anschließend können Sie die Prüfsumme für jeden auf der Clientseite heruntergeladenen Teil und schließlich das Struktur-Hash berechnen. Sie können diesen mit der Prüfsumme vergleichen, die von S3 Glacier als Antwort auf Ihre Anforderung zur Auftragsbeschreibung zurückgegeben wird, um zu überprüfen, ob der gesamte heruntergeladene Byte-Bereich mit dem in S3 Glacier gespeicherten Byte-Bereich übereinstimmt.

    Ein funktionierendes Beispiel finden Sie unter Beispiel 2: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for Java – Herunterladen der Ausgabe in Blöcken .

Beispiel 1: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for Java

Mit dem folgenden Java-Beispielcode wird ein Archiv aus dem angegebenen Tresor heruntergeladen. Nachdem der Auftrag abgeschlossen ist, lädt der Beispielcode die gesamte Ausgabe in einem einzigen getJobOutput-Aufruf herunter. Ein Beispiel für das Herunterladen der Ausgabe in Datenblöcken finden Sie unter Beispiel 2: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for Java – Herunterladen der Ausgabe in Blöcken .

Das Beispiel führt die folgenden Aufgaben durch:

  • Erstellt ein Amazon Simple Notification Service (Amazon SNS)-Thema.

    S3 Glacier sendet nach Abschluss des Auftrags eine Benachrichtigung an dieses Thema.

  • Erstellt eine Amazon Simple Queue Service (Amazon SQS)-Warteschlange.

    Im Beispiel wird der Warteschlange eine Richtlinie angefügt, damit das Amazon-SNS-Thema Nachrichten in der Warteschlange veröffentlichen kann.

  • Initiiert einen Auftrag zum Herunterladen des angegebenen Archivs.

    Das erstellte Amazon-SNS-Thema wird in der Auftragsanforderung angegeben, damit S3 Glacier nach Abschluss des Auftrags eine Benachrichtigung im Thema veröffentlichen kann.

  • Prüft die Amazon-SQS-Warteschlange regelmäßig auf Nachrichten, die die Auftrags-ID enthalten.

    Ist eine Nachricht vorhanden, parsen Sie das JSON und prüfen Sie, ob der Auftrag erfolgreich abgeschlossen wurde. Wenn eine Nachricht enthalten ist, laden Sie das Archiv herunter.

  • Bereinigt das System durch Löschen des Amazon-SNS-Themas und der erstellten Amazon-SQS-Warteschlange.

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.ObjectMapper; import com.amazonaws.AmazonClientException; import com.amazonaws.auth.policy.Policy; import com.amazonaws.auth.policy.Principal; import com.amazonaws.auth.policy.Resource; import com.amazonaws.auth.policy.Statement; import com.amazonaws.auth.policy.Statement.Effect; import com.amazonaws.auth.policy.actions.SQSActions; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.glacier.AmazonGlacierClient; import com.amazonaws.services.glacier.model.GetJobOutputRequest; import com.amazonaws.services.glacier.model.GetJobOutputResult; import com.amazonaws.services.glacier.model.InitiateJobRequest; import com.amazonaws.services.glacier.model.InitiateJobResult; import com.amazonaws.services.glacier.model.JobParameters; import com.amazonaws.services.sns.AmazonSNSClient; import com.amazonaws.services.sns.model.CreateTopicRequest; import com.amazonaws.services.sns.model.CreateTopicResult; import com.amazonaws.services.sns.model.DeleteTopicRequest; import com.amazonaws.services.sns.model.SubscribeRequest; import com.amazonaws.services.sns.model.SubscribeResult; import com.amazonaws.services.sns.model.UnsubscribeRequest; import com.amazonaws.services.sqs.AmazonSQSClient; import com.amazonaws.services.sqs.model.CreateQueueRequest; import com.amazonaws.services.sqs.model.CreateQueueResult; import com.amazonaws.services.sqs.model.DeleteQueueRequest; import com.amazonaws.services.sqs.model.GetQueueAttributesRequest; import com.amazonaws.services.sqs.model.GetQueueAttributesResult; import com.amazonaws.services.sqs.model.Message; import com.amazonaws.services.sqs.model.ReceiveMessageRequest; import com.amazonaws.services.sqs.model.SetQueueAttributesRequest; public class AmazonGlacierDownloadArchiveWithSQSPolling { public static String archiveId = "*** provide archive ID ****"; public static String vaultName = "*** provide vault name ***"; public static String snsTopicName = "*** provide topic name ***"; public static String sqsQueueName = "*** provide queue name ***"; public static String sqsQueueARN; public static String sqsQueueURL; public static String snsTopicARN; public static String snsSubscriptionARN; public static String fileName = "*** provide file name ***"; public static String region = "*** region ***"; public static long sleepTime = 600; public static AmazonGlacierClient client; public static AmazonSQSClient sqsClient; public static AmazonSNSClient snsClient; public static void main(String[] args) throws IOException { ProfileCredentialsProvider credentials = new ProfileCredentialsProvider(); client = new AmazonGlacierClient(credentials); client.setEndpoint("https://glacier." + region + ".amazonaws.com"); sqsClient = new AmazonSQSClient(credentials); sqsClient.setEndpoint("https://sqs." + region + ".amazonaws.com"); snsClient = new AmazonSNSClient(credentials); snsClient.setEndpoint("https://sns." + region + ".amazonaws.com"); try { setupSQS(); setupSNS(); String jobId = initiateJobRequest(); System.out.println("Jobid = " + jobId); Boolean success = waitForJobToComplete(jobId, sqsQueueURL); if (!success) { throw new Exception("Job did not complete successfully."); } downloadJobOutput(jobId); cleanUp(); } catch (Exception e) { System.err.println("Archive retrieval failed."); System.err.println(e); } } private static void setupSQS() { CreateQueueRequest request = new CreateQueueRequest() .withQueueName(sqsQueueName); CreateQueueResult result = sqsClient.createQueue(request); sqsQueueURL = result.getQueueUrl(); GetQueueAttributesRequest qRequest = new GetQueueAttributesRequest() .withQueueUrl(sqsQueueURL) .withAttributeNames("QueueArn"); GetQueueAttributesResult qResult = sqsClient.getQueueAttributes(qRequest); sqsQueueARN = qResult.getAttributes().get("QueueArn"); Policy sqsPolicy = new Policy().withStatements( new Statement(Effect.Allow) .withPrincipals(Principal.AllUsers) .withActions(SQSActions.SendMessage) .withResources(new Resource(sqsQueueARN))); Map<String, String> queueAttributes = new HashMap<String, String>(); queueAttributes.put("Policy", sqsPolicy.toJson()); sqsClient.setQueueAttributes(new SetQueueAttributesRequest(sqsQueueURL, queueAttributes)); } private static void setupSNS() { CreateTopicRequest request = new CreateTopicRequest() .withName(snsTopicName); CreateTopicResult result = snsClient.createTopic(request); snsTopicARN = result.getTopicArn(); SubscribeRequest request2 = new SubscribeRequest() .withTopicArn(snsTopicARN) .withEndpoint(sqsQueueARN) .withProtocol("sqs"); SubscribeResult result2 = snsClient.subscribe(request2); snsSubscriptionARN = result2.getSubscriptionArn(); } private static String initiateJobRequest() { JobParameters jobParameters = new JobParameters() .withType("archive-retrieval") .withArchiveId(archiveId) .withSNSTopic(snsTopicARN); InitiateJobRequest request = new InitiateJobRequest() .withVaultName(vaultName) .withJobParameters(jobParameters); InitiateJobResult response = client.initiateJob(request); return response.getJobId(); } private static Boolean waitForJobToComplete(String jobId, String sqsQueueUrl) throws InterruptedException, JsonParseException, IOException { Boolean messageFound = false; Boolean jobSuccessful = false; ObjectMapper mapper = new ObjectMapper(); JsonFactory factory = mapper.getJsonFactory(); while (!messageFound) { List<Message> msgs = sqsClient.receiveMessage( new ReceiveMessageRequest(sqsQueueUrl).withMaxNumberOfMessages(10)).getMessages(); if (msgs.size() > 0) { for (Message m : msgs) { JsonParser jpMessage = factory.createJsonParser(m.getBody()); JsonNode jobMessageNode = mapper.readTree(jpMessage); String jobMessage = jobMessageNode.get("Message").getTextValue(); JsonParser jpDesc = factory.createJsonParser(jobMessage); JsonNode jobDescNode = mapper.readTree(jpDesc); String retrievedJobId = jobDescNode.get("JobId").getTextValue(); String statusCode = jobDescNode.get("StatusCode").getTextValue(); if (retrievedJobId.equals(jobId)) { messageFound = true; if (statusCode.equals("Succeeded")) { jobSuccessful = true; } } } } else { Thread.sleep(sleepTime * 1000); } } return (messageFound && jobSuccessful); } private static void downloadJobOutput(String jobId) throws IOException { GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() .withVaultName(vaultName) .withJobId(jobId); GetJobOutputResult getJobOutputResult = client.getJobOutput(getJobOutputRequest); InputStream input = new BufferedInputStream(getJobOutputResult.getBody()); OutputStream output = null; try { output = new BufferedOutputStream(new FileOutputStream(fileName)); byte[] buffer = new byte[1024 * 1024]; int bytesRead = 0; do { bytesRead = input.read(buffer); if (bytesRead <= 0) break; output.write(buffer, 0, bytesRead); } while (bytesRead > 0); } catch (IOException e) { throw new AmazonClientException("Unable to save archive", e); } finally { try {input.close();} catch (Exception e) {} try {output.close();} catch (Exception e) {} } System.out.println("Retrieved archive to " + fileName); } private static void cleanUp() { snsClient.unsubscribe(new UnsubscribeRequest(snsSubscriptionARN)); snsClient.deleteTopic(new DeleteTopicRequest(snsTopicARN)); sqsClient.deleteQueue(new DeleteQueueRequest(sqsQueueURL)); } }

Beispiel 2: Abrufen eines Archivs mithilfe der Low-Level-API von AWS SDK for Java – Herunterladen der Ausgabe in Blöcken

Im folgenden Java-Codebeispiel wird ein Archiv aus S3 Glacier abgerufen. Der Beispielcode gibt den abzurufenden Bytebereich in einem GetJobOutputRequest-Objekt an und lädt die Auftragsausgabe in Datenblöcken herunter.

import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.amazonaws.auth.policy.Policy; import com.amazonaws.auth.policy.Principal; import com.amazonaws.auth.policy.Resource; import com.amazonaws.auth.policy.Statement; import com.amazonaws.auth.policy.Statement.Effect; import com.amazonaws.auth.policy.actions.SQSActions; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.glacier.AmazonGlacierClient; import com.amazonaws.services.glacier.TreeHashGenerator; import com.amazonaws.services.glacier.model.GetJobOutputRequest; import com.amazonaws.services.glacier.model.GetJobOutputResult; import com.amazonaws.services.glacier.model.InitiateJobRequest; import com.amazonaws.services.glacier.model.InitiateJobResult; import com.amazonaws.services.glacier.model.JobParameters; import com.amazonaws.services.sns.AmazonSNSClient; import com.amazonaws.services.sns.model.CreateTopicRequest; import com.amazonaws.services.sns.model.CreateTopicResult; import com.amazonaws.services.sns.model.DeleteTopicRequest; import com.amazonaws.services.sns.model.SubscribeRequest; import com.amazonaws.services.sns.model.SubscribeResult; import com.amazonaws.services.sns.model.UnsubscribeRequest; import com.amazonaws.services.sqs.AmazonSQSClient; import com.amazonaws.services.sqs.model.CreateQueueRequest; import com.amazonaws.services.sqs.model.CreateQueueResult; import com.amazonaws.services.sqs.model.DeleteQueueRequest; import com.amazonaws.services.sqs.model.GetQueueAttributesRequest; import com.amazonaws.services.sqs.model.GetQueueAttributesResult; import com.amazonaws.services.sqs.model.Message; import com.amazonaws.services.sqs.model.ReceiveMessageRequest; import com.amazonaws.services.sqs.model.SetQueueAttributesRequest; public class ArchiveDownloadLowLevelWithRange { public static String vaultName = "*** provide vault name ***"; public static String archiveId = "*** provide archive id ***"; public static String snsTopicName = "glacier-temp-sns-topic"; public static String sqsQueueName = "glacier-temp-sqs-queue"; public static long downloadChunkSize = 4194304; // 4 MB public static String sqsQueueARN; public static String sqsQueueURL; public static String snsTopicARN; public static String snsSubscriptionARN; public static String fileName = "*** provide file name to save archive to ***"; public static String region = "*** region ***"; public static long sleepTime = 600; public static AmazonGlacierClient client; public static AmazonSQSClient sqsClient; public static AmazonSNSClient snsClient; public static void main(String[] args) throws IOException { ProfileCredentialsProvider credentials = new ProfileCredentialsProvider(); client = new AmazonGlacierClient(credentials); client.setEndpoint("https://glacier." + region + ".amazonaws.com"); sqsClient = new AmazonSQSClient(credentials); sqsClient.setEndpoint("https://sqs." + region + ".amazonaws.com"); snsClient = new AmazonSNSClient(credentials); snsClient.setEndpoint("https://sns." + region + ".amazonaws.com"); try { setupSQS(); setupSNS(); String jobId = initiateJobRequest(); System.out.println("Jobid = " + jobId); long archiveSizeInBytes = waitForJobToComplete(jobId, sqsQueueURL); if (archiveSizeInBytes==-1) { throw new Exception("Job did not complete successfully."); } downloadJobOutput(jobId, archiveSizeInBytes); cleanUp(); } catch (Exception e) { System.err.println("Archive retrieval failed."); System.err.println(e); } } private static void setupSQS() { CreateQueueRequest request = new CreateQueueRequest() .withQueueName(sqsQueueName); CreateQueueResult result = sqsClient.createQueue(request); sqsQueueURL = result.getQueueUrl(); GetQueueAttributesRequest qRequest = new GetQueueAttributesRequest() .withQueueUrl(sqsQueueURL) .withAttributeNames("QueueArn"); GetQueueAttributesResult qResult = sqsClient.getQueueAttributes(qRequest); sqsQueueARN = qResult.getAttributes().get("QueueArn"); Policy sqsPolicy = new Policy().withStatements( new Statement(Effect.Allow) .withPrincipals(Principal.AllUsers) .withActions(SQSActions.SendMessage) .withResources(new Resource(sqsQueueARN))); Map<String, String> queueAttributes = new HashMap<String, String>(); queueAttributes.put("Policy", sqsPolicy.toJson()); sqsClient.setQueueAttributes(new SetQueueAttributesRequest(sqsQueueURL, queueAttributes)); } private static void setupSNS() { CreateTopicRequest request = new CreateTopicRequest() .withName(snsTopicName); CreateTopicResult result = snsClient.createTopic(request); snsTopicARN = result.getTopicArn(); SubscribeRequest request2 = new SubscribeRequest() .withTopicArn(snsTopicARN) .withEndpoint(sqsQueueARN) .withProtocol("sqs"); SubscribeResult result2 = snsClient.subscribe(request2); snsSubscriptionARN = result2.getSubscriptionArn(); } private static String initiateJobRequest() { JobParameters jobParameters = new JobParameters() .withType("archive-retrieval") .withArchiveId(archiveId) .withSNSTopic(snsTopicARN); InitiateJobRequest request = new InitiateJobRequest() .withVaultName(vaultName) .withJobParameters(jobParameters); InitiateJobResult response = client.initiateJob(request); return response.getJobId(); } private static long waitForJobToComplete(String jobId, String sqsQueueUrl) throws InterruptedException, JsonParseException, IOException { Boolean messageFound = false; Boolean jobSuccessful = false; long archiveSizeInBytes = -1; ObjectMapper mapper = new ObjectMapper(); JsonFactory factory = mapper.getFactory(); while (!messageFound) { List<Message> msgs = sqsClient.receiveMessage( new ReceiveMessageRequest(sqsQueueUrl).withMaxNumberOfMessages(10)).getMessages(); if (msgs.size() > 0) { for (Message m : msgs) { JsonParser jpMessage = factory.createJsonParser(m.getBody()); JsonNode jobMessageNode = mapper.readTree(jpMessage); String jobMessage = jobMessageNode.get("Message").textValue(); JsonParser jpDesc = factory.createJsonParser(jobMessage); JsonNode jobDescNode = mapper.readTree(jpDesc); String retrievedJobId = jobDescNode.get("JobId").textValue(); String statusCode = jobDescNode.get("StatusCode").textValue(); archiveSizeInBytes = jobDescNode.get("ArchiveSizeInBytes").longValue(); if (retrievedJobId.equals(jobId)) { messageFound = true; if (statusCode.equals("Succeeded")) { jobSuccessful = true; } } } } else { Thread.sleep(sleepTime * 1000); } } return (messageFound && jobSuccessful) ? archiveSizeInBytes : -1; } private static void downloadJobOutput(String jobId, long archiveSizeInBytes) throws IOException { if (archiveSizeInBytes < 0) { System.err.println("Nothing to download."); return; } System.out.println("archiveSizeInBytes: " + archiveSizeInBytes); FileOutputStream fstream = new FileOutputStream(fileName); long startRange = 0; long endRange = (downloadChunkSize > archiveSizeInBytes) ? archiveSizeInBytes -1 : downloadChunkSize - 1; do { GetJobOutputRequest getJobOutputRequest = new GetJobOutputRequest() .withVaultName(vaultName) .withRange("bytes=" + startRange + "-" + endRange) .withJobId(jobId); GetJobOutputResult getJobOutputResult = client.getJobOutput(getJobOutputRequest); BufferedInputStream is = new BufferedInputStream(getJobOutputResult.getBody()); byte[] buffer = new byte[(int)(endRange - startRange + 1)]; System.out.println("Checksum received: " + getJobOutputResult.getChecksum()); System.out.println("Content range " + getJobOutputResult.getContentRange()); int totalRead = 0; while (totalRead < buffer.length) { int bytesRemaining = buffer.length - totalRead; int read = is.read(buffer, totalRead, bytesRemaining); if (read > 0) { totalRead = totalRead + read; } else { break; } } System.out.println("Calculated checksum: " + TreeHashGenerator.calculateTreeHash(new ByteArrayInputStream(buffer))); System.out.println("read = " + totalRead); fstream.write(buffer); startRange = startRange + (long)totalRead; endRange = ((endRange + downloadChunkSize) > archiveSizeInBytes) ? archiveSizeInBytes : (endRange + downloadChunkSize); is.close(); } while (endRange <= archiveSizeInBytes && startRange < archiveSizeInBytes); fstream.close(); System.out.println("Retrieved file to " + fileName); } private static void cleanUp() { snsClient.unsubscribe(new UnsubscribeRequest(snsSubscriptionARN)); snsClient.deleteTopic(new DeleteTopicRequest(snsTopicARN)); sqsClient.deleteQueue(new DeleteQueueRequest(sqsQueueURL)); } }