com.amazonaws.services.glacier.transfer.JobStatusMonitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk Show documentation
Show all versions of aws-java-sdk Show documentation
The Amazon Web Services SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).
The newest version!
/*
* Copyright 2012-2014 Amazon Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.services.glacier.transfer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentialsProvider;
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.policy.conditions.ConditionFactory;
import com.amazonaws.services.glacier.model.StatusCode;
import com.amazonaws.services.sns.AmazonSNSClient;
import com.amazonaws.services.sns.model.CreateTopicRequest;
import com.amazonaws.services.sns.model.DeleteTopicRequest;
import com.amazonaws.services.sns.model.SubscribeRequest;
import com.amazonaws.services.sqs.AmazonSQSClient;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.DeleteMessageRequest;
import com.amazonaws.services.sqs.model.DeleteQueueRequest;
import com.amazonaws.services.sqs.model.GetQueueAttributesRequest;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
import com.amazonaws.util.BinaryUtils;
import com.amazonaws.util.json.JSONException;
import com.amazonaws.util.json.JSONObject;
/**
* Utility for monitoring the status of an Amazon Glacier job, through Amazon
* SNS/SQS.
*/
public class JobStatusMonitor {
private AmazonSQSClient sqs;
private AmazonSNSClient sns;
private String queueUrl;
private String topicArn;
private static final Log log = LogFactory.getLog(JobStatusMonitor.class);
public JobStatusMonitor(AWSCredentialsProvider credentialsProvider, ClientConfiguration clientConfiguration) {
sqs = new AmazonSQSClient(credentialsProvider, clientConfiguration);
sns = new AmazonSNSClient(credentialsProvider, clientConfiguration);
setupQueueAndTopic();
}
/**
* Constructs a JobStatusMonitor that will use the specified clients for
* polling archive download job status.
*
* @param sqs
* The client for working with Amazon SQS when polling archive
* retrieval job status.
* @param sns
* The client for working with Amazon SNS when polling archive
* retrieval job status.
*/
public JobStatusMonitor(AmazonSQSClient sqs, AmazonSNSClient sns) {
this.sqs = sqs;
this.sns = sns;
setupQueueAndTopic();
}
public String getTopicArn() {
return topicArn;
}
public void shutdown() {
try {
sqs.deleteQueue(new DeleteQueueRequest(queueUrl));
} catch (Exception e) {
log.warn("Unable to delete queue: " + queueUrl, e);
}
try {
sns.deleteTopic(new DeleteTopicRequest(topicArn));
} catch (Exception e) {
log.warn("Unable to delete topic: " + topicArn, e);
}
}
/** Poll the SQS queue to see if we've received a message about the job completion yet. **/
public void waitForJobToComplete(String jobId) {
while (true) {
List messages = sqs.receiveMessage(new ReceiveMessageRequest(queueUrl)).getMessages();
for (Message message : messages) {
String messageBody = message.getBody();
if (!messageBody.startsWith("{")) {
messageBody = new String(BinaryUtils.fromBase64(messageBody));
}
try {
JSONObject json = new JSONObject(messageBody);
String jsonMessage = json.getString("Message").replace("\\\"", "\"");
json = new JSONObject(jsonMessage);
String messageJobId = json.getString("JobId");
String messageStatus = json.getString("StatusMessage");
// Don't process this message if it wasn't the job we were looking for
if (!jobId.equals(messageJobId)) continue;
try {
if (StatusCode.Succeeded.toString().equals(messageStatus)) return;
if (StatusCode.Failed.toString().equals(messageStatus)) {
throw new AmazonClientException("Archive retrieval failed");
}
} finally {
deleteMessage(message);
}
} catch (JSONException e) {
throw new AmazonClientException("Unable to parse status message: " + messageBody, e);
}
}
sleep(1000 * 30);
}
}
private void sleep(long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException ie) {
throw new AmazonClientException("Archive download interrupted", ie);
}
}
private void deleteMessage(Message message) {
try {
sqs.deleteMessage(new DeleteMessageRequest(queueUrl, message.getReceiptHandle()));
} catch (Exception e) {}
}
private void setupQueueAndTopic() {
String queueName = "glacier-archive-transfer-" + System.currentTimeMillis();
String topicName = "glacier-archive-transfer-" + System.currentTimeMillis();
queueUrl = sqs.createQueue(new CreateQueueRequest(queueName)).getQueueUrl();
topicArn = sns.createTopic(new CreateTopicRequest(topicName)).getTopicArn();
String queueARN = sqs.getQueueAttributes(new GetQueueAttributesRequest(queueUrl).withAttributeNames("QueueArn")).getAttributes().get("QueueArn");
Policy sqsPolicy =
new Policy().withStatements(
new Statement(Effect.Allow)
.withPrincipals(Principal.AllUsers)
.withActions(SQSActions.SendMessage)
.withResources(new Resource(queueARN))
.withConditions(ConditionFactory.newSourceArnCondition(topicArn)));
sqs.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, newAttributes("Policy", sqsPolicy.toJson())));
sns.subscribe(new SubscribeRequest(topicArn, "sqs", queueARN));
}
private Map newAttributes(String... keyValuePairs) {
if (keyValuePairs.length % 2 != 0)
throw new IllegalArgumentException("Incorrect number of arguments passed. Input must be specified as: key, value, key, value, ...");
Map map = new HashMap();
for (int i = 0; i < keyValuePairs.length; i += 2) {
String key = keyValuePairs[i];
String value = keyValuePairs[i+1];
map.put(key, value);
}
return map;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy