All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dasein.cloud.aws.platform.SNS Maven / Gradle / Ivy

There is a newer version: 2015.10.9
Show newest version
/**
 * Copyright (C) 2009-2015 Dell, Inc.
 * See annotations for authorship information
 *
 * ====================================================================
 * 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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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 org.dasein.cloud.aws.platform;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.dasein.cloud.CloudException;
import org.dasein.cloud.DataFormat;
import org.dasein.cloud.InternalException;
import org.dasein.cloud.ProviderContext;
import org.dasein.cloud.ResourceStatus;
import org.dasein.cloud.aws.AWSCloud;
import org.dasein.cloud.aws.compute.EC2Exception;
import org.dasein.cloud.aws.compute.EC2Method;
import org.dasein.cloud.identity.ServiceAction;
import org.dasein.cloud.platform.*;
import org.dasein.cloud.util.APITrace;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * AWS SNS Support
 *
 * @author George Reese
 * @author Stas Maksimov
 * @version 2014.08 deprecated methods moved to capabilities
 * @since ?
 */
public class SNS implements PushNotificationSupport {
    static private final Logger logger = AWSCloud.getLogger(SNS.class);

    static public final String SERVICE_ID                  = "sns";
    
    static public final String CONFIRM_SUBSCRIPTION        = "ConfirmSubscription";
    static public final String CREATE_TOPIC                = "CreateTopic";
    static public final String DELETE_TOPIC                = "DeleteTopic";
    static public final String GET_TOPIC_ATTRIBUTES        = "GetTopicAttributes";
    static public final String LIST_SUBSCRIPTIONS          = "ListSubscriptions";
    static public final String LIST_SUBSCRIPTIONS_BY_TOPIC = "ListSubscriptionsByTopic";
    static public final String LIST_TOPICS                 = "ListTopics";
    static public final String PUBLISH                     = "Publish";
    static public final String SET_TOPIC_ATTRIBUTES        = "SetTopicAttributes";
    static public final String SUBSCRIBE                   = "Subscribe";
    static public final String UNSUBSCRIBE                 = "Unsubscribe";

    private volatile transient SNSCapabilities capabilities;

    static public @Nonnull ServiceAction[] asSNSServiceAction(@Nonnull String action) {
        if( action.equals(CREATE_TOPIC) ) {
            return new ServiceAction[] { PushNotificationSupport.CREATE_TOPIC };
        }
        else if( action.equals(DELETE_TOPIC) ) {
            return new ServiceAction[] { PushNotificationSupport.REMOVE_TOPIC };
        }
        else if( action.equals(LIST_TOPICS) ) {
            return new ServiceAction[] { PushNotificationSupport.GET_TOPIC, PushNotificationSupport.LIST_TOPIC };
        }
        else if( action.equals(PUBLISH) ) {
            return new ServiceAction[] { PushNotificationSupport.PUBLISH };
        }
        else if( action.equals(SUBSCRIBE) ) {
            return new ServiceAction[] { PushNotificationSupport.SUBSCRIBE };
        }
        return new ServiceAction[0];
    }
    
    private AWSCloud provider = null;
    
    SNS(AWSCloud provider) { this.provider = provider; }
    
    @Override
    public String confirmSubscription(String providerTopicId, String token, boolean authenticateUnsubscribe) throws CloudException, InternalException {
        APITrace.begin(provider, "Notifications.confirmSubscription");
        try {
            Map parameters = provider.getStandardSnsParameters(provider.getContext(), CONFIRM_SUBSCRIPTION);
            EC2Method method;
            NodeList blocks;
            Document doc;

            parameters.put("TopicArn", providerTopicId);
            parameters.put("Token", token);
            if( authenticateUnsubscribe ) {
                parameters.put("AuthenticateOnUnsubscribe", "true");
            }
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("ConfirmSubscriptionResult");
            for( int i=0; i parameters = provider.getStandardSnsParameters(provider.getContext(), CREATE_TOPIC);
            Topic topic = null;
            EC2Method method;
            NodeList blocks;
            Document doc;

            parameters.put("Name", name);
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("CreateTopicResult");
            for( int i=0; i parameters = provider.getStandardSnsParameters(provider.getContext(), LIST_TOPICS);
            EC2Method method;

            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                method.invoke();
                return true;
            }
            catch( EC2Exception e ) {
                if( e.getStatus() == HttpServletResponse.SC_UNAUTHORIZED || e.getStatus() == HttpServletResponse.SC_FORBIDDEN ) {
                    return false;
                }
                String code = e.getCode();

                if( code != null && (code.equals("SubscriptionCheckFailed") || code.equals("AuthFailure") || code.equals("SignatureDoesNotMatch") || code.equals("InvalidClientTokenId") || code.equals("OptInRequired")) ) {
                    return false;
                }
                logger.warn(e.getSummary());
                if( logger.isDebugEnabled() ) {
                    e.printStackTrace();
                }
                throw new CloudException(e);
            }
        }
        finally {
            APITrace.end();
        }
    }
    
    @Override
    public Collection listSubscriptions(String optionalTopicId) throws CloudException, InternalException {
        APITrace.begin(provider, "Notifications.listSubscriptions");
        try {
            Map parameters = provider.getStandardSnsParameters(provider.getContext(), optionalTopicId == null ? LIST_SUBSCRIPTIONS : LIST_SUBSCRIPTIONS_BY_TOPIC);
            ArrayList list = new ArrayList();
            EC2Method method;
            NodeList blocks;
            Document doc;

            if( optionalTopicId != null ) {
                parameters.put("TopicArn", optionalTopicId);
            }
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("Subscriptions");
            for( int i=0; i listTopicStatus() throws CloudException, InternalException {
        APITrace.begin(provider, "Notifications.listTopicStatus");
        try {
            Map parameters = provider.getStandardSnsParameters(provider.getContext(), LIST_TOPICS);
            ArrayList list = new ArrayList();
            EC2Method method;
            NodeList blocks;
            Document doc;

            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("Topics");
            for( int i=0; i listTopics() throws CloudException, InternalException {
        APITrace.begin(provider, "Notifications.listTopics");
        try {
            Map parameters = provider.getStandardSnsParameters(provider.getContext(), LIST_TOPICS);
            ArrayList list = new ArrayList();
            EC2Method method;
            NodeList blocks;
            Document doc;

            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("Topics");
            for( int i=0; i parameters = provider.getStandardSnsParameters(provider.getContext(), PUBLISH);
            EC2Method method;
            NodeList blocks;
            Document doc;

            parameters.put("TopicArn", providerTopicId);
            parameters.put("Subject", subject);
            parameters.put("Message", message);
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("PublishResult");
            for( int i=0; i parameters = provider.getStandardSnsParameters(provider.getContext(), DELETE_TOPIC);
            EC2Method method;

            parameters.put("TopicArn", providerTopicId);
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
        }
        finally {
            APITrace.end();
        }
    }

  @Override
  public @Nullable Topic getTopic( @Nonnull String providerTopicId ) throws CloudException, InternalException {
    try {
      Topic topic = new Topic();
      topic.setProviderTopicId( providerTopicId );
      setTopicAttributes( topic );
      return topic;
    }
    catch ( CloudException e ) {
      Throwable cause = e.getCause();
      if ( cause instanceof EC2Exception ) {
        String code = ((EC2Exception) cause).getCode();
        if ( "NotFound".equals( code ) || "InvalidParameter".equals(code) ) {
          return null;
        }

      }
      throw e;
    }
  }

    private void setTopicAttribute(Topic topic, final String attributeName, final String attributeValue) throws InternalException, CloudException {
        APITrace.begin(provider, "Notifications.setTopicAttributes");
        try {
            Map parameters = provider.getStandardSnsParameters(provider.getContext(), SET_TOPIC_ATTRIBUTES);
            EC2Method method;

            parameters.put("TopicArn", topic.getProviderTopicId());
            parameters.put("AttributeName", attributeName);
            parameters.put("AttributeValue", attributeValue);

            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
        }
        finally {
            APITrace.end();
        }
    }

    private void setTopicAttributes(Topic topic) throws InternalException, CloudException {
        ProviderContext ctx = provider.getContext();

        if( ctx == null ) {
            throw new CloudException("No context was set for this request");
        }
        APITrace.begin(provider, "Notifications.getTopicAttributes");
        try {
            topic.setProviderRegionId(ctx.getRegionId());
            topic.setProviderOwnerId(ctx.getAccountNumber());
            topic.setActive(true);

            Map parameters = provider.getStandardSnsParameters(provider.getContext(), GET_TOPIC_ATTRIBUTES);
            EC2Method method;
            NodeList blocks;
            Document doc;

            parameters.put("TopicArn", topic.getProviderTopicId());
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                doc = method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
            blocks = doc.getElementsByTagName("Attributes");
            for( int i=0; i 0 && idx < id.length()-1 ) {
                    id = id.substring(idx+1);
                }
                topic.setName(id);
            }
            if( topic.getDescription() == null ) {
                topic.setDescription(topic.getName() + " (" + topic.getProviderTopicId() + ")");
            }
        }
        finally {
            APITrace.end();
        }
    }
    
    @Override
    public void subscribe(String providerTopicId, EndpointType endpointType, DataFormat dataFormat, String endpoint) throws CloudException, InternalException {
        APITrace.begin(provider, "Notifications.subscribe");
        try {
            Map parameters = provider.getStandardSnsParameters(provider.getContext(), SUBSCRIBE);
            EC2Method method;

            parameters.put("TopicArn", providerTopicId);
            switch( endpointType ) {
                case HTTP:
                    parameters.put("Protocol", "http");
                    break;
                case HTTPS:
                    parameters.put("Protocol", "https");
                    break;
                case EMAIL:
                    if( dataFormat.equals(DataFormat.JSON) ) {
                        parameters.put("Protocol", "email-json");
                    }
                    else {
                        parameters.put("Protocol", "email");
                    }
                    break;
                case AWS_SQS:
                    parameters.put("Protocol", "sqs");
                    break;
                case SMS:
                    parameters.put("Protocol", "sms");
                    break;
            }
            parameters.put("Endpoint", endpoint);
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
        }
        finally {
            APITrace.end();
        }
    }

    private @Nullable ResourceStatus toStatus(@Nullable Node fromAws) throws InternalException, CloudException {
        if( fromAws == null ) {
            return null;
        }
        NodeList attrs = fromAws.getChildNodes();
        String topicId = null;

        for( int i=0; i parameters = provider.getStandardSnsParameters(provider.getContext(), UNSUBSCRIBE);
            EC2Method method;

            parameters.put("SubscriptionArn", providerSubscriptionId);
            method = new EC2Method(SERVICE_ID, provider, parameters);
            try {
                method.invoke();
            }
            catch( EC2Exception e ) {
                throw new CloudException(e);
            }
        }
        finally {
            APITrace.end();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy