org.dasein.cloud.aws.platform.SNS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dasein-cloud-aws Show documentation
Show all versions of dasein-cloud-aws Show documentation
Implementation of the Dasein Cloud API for AWS.
/**
* 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();
}
}
}