com.pocketdealhunter.HotDealsMessagesUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.pocketdealhunter.HotDealsMessagesUtil.java

Source

/*
 * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. 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.pocketdealhunter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
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.ListSubscriptionsByTopicRequest;
import com.amazonaws.services.sns.model.ListSubscriptionsByTopicResult;
import com.amazonaws.services.sns.model.ListTopicsRequest;
import com.amazonaws.services.sns.model.ListTopicsResult;
import com.amazonaws.services.sns.model.PublishRequest;
import com.amazonaws.services.sns.model.SetTopicAttributesRequest;
import com.amazonaws.services.sns.model.SubscribeRequest;
import com.amazonaws.services.sns.model.Subscription;
import com.amazonaws.services.sns.model.Topic;
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.DeleteMessageRequest;
import com.amazonaws.services.sqs.model.GetQueueAttributesRequest;
import com.amazonaws.services.sqs.model.GetQueueAttributesResult;
import com.amazonaws.services.sqs.model.ListQueuesResult;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.services.sqs.model.ReceiveMessageResult;
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;

// This singleton class provides all the functionality to manipulate the Amazon 
// SNS Topic and Amazon SQS Queue used in this sample application.
public class HotDealsMessagesUtil {

    private static HotDealsMessagesUtil instance = null;
    private AmazonSNSClient snsClient = null;
    private AmazonSQSClient sqsClient = null;
    private String topicARN;
    private String queueUrl;

    public synchronized static HotDealsMessagesUtil instance() {
        if (instance == null) {
            instance = new HotDealsMessagesUtil();
        }

        return instance;
    }

    public HotDealsMessagesUtil() {
        AWSCredentials credentials = new BasicAWSCredentials(Constants.ACCESS_KEY_ID, Constants.SECRET_KEY);
        Region region = Region.getRegion(Regions.US_WEST_2);

        this.snsClient = new AmazonSNSClient(credentials);
        this.snsClient.setRegion(region);

        this.sqsClient = new AmazonSQSClient(credentials);
        this.sqsClient.setRegion(region);

        // Find the Topic for this App or create one.
        this.topicARN = this.findTopicArn();
        if (topicARN == null) {
            this.topicARN = this.createTopic();
        }

        // Find the Queue for this App or create one.
        this.queueUrl = this.findQueueUrl();
        if (this.queueUrl == null) {
            this.queueUrl = this.createQueue();

            // Allow time for the queue to be created.
            try {
                Thread.sleep(4 * 1000);
            } catch (Exception exception) {
            }

            this.subscribeQueue();
        }
    }

    protected String createTopic() {
        try {
            CreateTopicRequest ctr = new CreateTopicRequest(Constants.TOPIC_NAME);
            CreateTopicResult result = snsClient.createTopic(ctr);

            // Adding the DisplayName attribute to the Topic allows for SMS
            // notifications.
            SetTopicAttributesRequest tar = new SetTopicAttributesRequest(result.getTopicArn(), "DisplayName",
                    "MessageBoard");
            this.snsClient.setTopicAttributes(tar);

            return result.getTopicArn();
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
            return null;
        }
    }

    public void subscribeEmail(String email) {
        try {
            SubscribeRequest sr = new SubscribeRequest(this.topicARN, "email", email);
            this.snsClient.subscribe(sr);
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
        }
    }

    public void subscribeSms(String sms) {
        try {
            SubscribeRequest sr = new SubscribeRequest(this.topicARN, "sms", sms);
            this.snsClient.subscribe(sr);
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
        }
    }

    // Post a notification to the topic.
    public void post(String message) {
        try {
            PublishRequest pr = new PublishRequest(this.topicARN, message);
            this.snsClient.publish(pr);
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
        }
    }

    public List<Subscription> listSubscribers() {
        try {
            ListSubscriptionsByTopicRequest ls = new ListSubscriptionsByTopicRequest(this.topicARN);
            ListSubscriptionsByTopicResult response = this.snsClient.listSubscriptionsByTopic(ls);
            return response.getSubscriptions();
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
            return Collections.emptyList();
        }
    }

    // Undsubscribe an endpoint from the topic.
    public void removeSubscriber(String subscriptionArn) {
        try {
            UnsubscribeRequest unsubscribeRequest = new UnsubscribeRequest(subscriptionArn);
            this.snsClient.unsubscribe(unsubscribeRequest);
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
        }
    }

    public List<Message> getMessageQueue() {
        try {
            ReceiveMessageRequest rmr = new ReceiveMessageRequest(this.queueUrl);
            rmr.setMaxNumberOfMessages(10);
            rmr.setVisibilityTimeout(2);

            List<Message> messages = null;
            ArrayList<Message> allMessages = new ArrayList<Message>(100);
            do {
                ReceiveMessageResult result = this.sqsClient.receiveMessage(rmr);
                messages = result.getMessages();
                allMessages.addAll(messages);
                try {
                    Thread.sleep(1 * 1000);
                } catch (Exception exception) {
                }
            } while (!messages.isEmpty());

            return allMessages;
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
            return Collections.emptyList();
        }
    }

    protected void subscribeQueue() {
        try {
            String queueArn = this.getQueueArn(this.queueUrl);

            SubscribeRequest request = new SubscribeRequest();
            request.withEndpoint(queueArn).withProtocol("sqs").withTopicArn(this.topicARN);

            this.snsClient.subscribe(request);
        } catch (Exception exception) {
            System.out.println("Exception = " + exception);
        }
    }

    private String createQueue() {
        try {
            CreateQueueRequest cqr = new CreateQueueRequest(Constants.QUEUE_NAME);
            CreateQueueResult result = this.sqsClient.createQueue(cqr);

            String queueArn = this.getQueueArn(result.getQueueUrl());
            this.addPolicyToQueueForTopic(result.getQueueUrl(), queueArn);

            return result.getQueueUrl();
        } catch (Exception exception) {
            System.out.println("Exception = " + exception);
            return null;
        }
    }

    // Get the QueueArn attribute from the Queue. The QueueArn is necessary for
    // create a policy on the queue
    // that allows for messages from the Amazon SNS Topic.
    private String getQueueArn(String queueUrl) {
        try {
            GetQueueAttributesRequest gqar = new GetQueueAttributesRequest(queueUrl)
                    .withAttributeNames(new String[] { "QueueArn" });
            GetQueueAttributesResult result = this.sqsClient.getQueueAttributes(gqar);

            return (String) result.getAttributes().get("QueueArn");
        } catch (Exception exception) {
            System.out.println("Exception = " + exception);
            return null;
        }
    }

    // Add a policy to a specific queue by setting the queue's Policy attribute.
    // Assigning a policy to the queue is necessary as described in Amazon SNS'
    // FAQ:
    // http://aws.amazon.com/sns/faqs/#26
    private void addPolicyToQueueForTopic(String queueUrl, String queueArn) {
        HashMap<String, String> attributes = new HashMap<String, String>();
        attributes.put("Policy", generateSqsPolicyForTopic(queueArn, this.topicARN));
        this.sqsClient.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributes));

        // It can take some time for policy to propagate to the queue.
    }

    // Creates the policy object that is necessary to allow the topic to send
    // message to the queue. The topic will
    // send all topic notifications to the queue.
    private String generateSqsPolicyForTopic(String queueArn, String topicArn) {
        Map<String, Object> principalMap = new HashMap<String, Object>();
        principalMap.put("AWS", "*");

        Map<String, Object> arnMap = new HashMap<String, Object>();
        arnMap.put("aws:SourceArn", topicArn);

        Map<String, Object> conditionMap = new HashMap<String, Object>();
        conditionMap.put("StringEquals", arnMap);

        Map<String, Object> statementMap = new HashMap<String, Object>();
        statementMap.put("Sid", queueArn + "/statementId");
        statementMap.put("Effect", "Allow");
        statementMap.put("Principal", principalMap);
        statementMap.put("Action", "SQS:SendMessage");
        statementMap.put("Resource", queueArn);
        statementMap.put("Condition", conditionMap);

        Map<String, Object> policyMap = new HashMap<String, Object>();

        policyMap.put("Version", "2008-10-17");
        policyMap.put("Id", queueArn + "/policyId");
        policyMap.put("Statement", new Object[] { statementMap });

        ObjectMapper mapper = new ObjectMapper();
        String policy = null;
        try {
            policy = mapper.writeValueAsString(policyMap);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return policy;
    }

    // Determines if a topic exists with the given topic name.
    // The topic name is assigned in the Constants.java file.
    protected String findTopicArn() {
        try {
            String topicNameToFind = ":" + Constants.TOPIC_NAME;
            String nextToken = null;
            do {
                ListTopicsRequest listTopicsRequest = new ListTopicsRequest(nextToken);
                ListTopicsResult result = this.snsClient.listTopics(listTopicsRequest);

                for (Topic topic : (List<Topic>) result.getTopics()) {
                    if (topic.getTopicArn().endsWith(topicNameToFind)) {
                        return topic.getTopicArn();
                    }
                }

                nextToken = result.getNextToken();
            } while (nextToken != null);

            return null;
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
            return null;
        }
    }

    // Determine if a queue exists with the given queue name.
    // The queue name is assigned in the Constants.java file.
    protected String findQueueUrl() {
        try {
            String queueNameToFind = "/" + Constants.QUEUE_NAME;
            ListQueuesResult queuesResult = this.sqsClient.listQueues();

            for (String queueUrl : (List<String>) queuesResult.getQueueUrls()) {
                if (queueUrl.endsWith(queueNameToFind)) {
                    return queueUrl;
                }
            }

            return null;
        } catch (Exception exception) {
            System.out.println("Exception  = " + exception);
            return null;
        }
    }

    public void deleteMessageFromQueue(Message message) {
        try {
            DeleteMessageRequest request = new DeleteMessageRequest(this.queueUrl, message.getReceiptHandle());
            this.sqsClient.deleteMessage(request);
        } catch (Exception exception) {
            System.out.println("Exception = " + exception);
        }
    }
}