AWS SNS Example with Spring Boot & Java

aws sns example with spring boot and java

Amazon Simple Notification Service (SNS) is a fully managed pub/sub messaging and mobile notifications service for coordinating the delivery of messages to subscribing endpoints and clients. One can get started with Amazon SNS using AWS console or AWS CLI or AWS SDK. One example of how Amazon SNS can be used is the following:

  • Publish a JSON message (consisting of phone no. and message) to Amazon SNS topic
  • Above which will result in triggering an Amazon Lambda function which could in turn trigger Amazon Polly to generate text-to-speech, and, subsequently, invoke Twilio API to make the call to destined phone number.

In this post, you will learn about how to publish a message to Amazon SNS Topic using a Spring Boot and Java AWS SDK app. The message can be a simple text message or a JSON message.

  • Sample SpringBoot app for publishing message
  • Define a custom interface, PublisherService, for publishing message
  • Create a custom implementation such as AmazonSNSPublisherService
  • Create configuration beans for loading properties
  • Sample application.properties file

Sample SpringBoot app for publishing message

Pay attention to some of the following:

  • An instance of PublisherService is auto-wired. The same is discussed later in this post.
  • A JSON message is posted to the topic. A non-JSON message can as well be posted.
@SpringBootApplication
public class RecruiterbotApplication implements CommandLineRunner {

    @Autowired PublisherService publisherService;

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(RecruiterbotApplication.class);
        app.run(args);
    }

    @Override
    public void run(String... arg0) throws IOException, URISyntaxException {

        try {
            this.publisherService.publish("{\"mobileno\": \"+919996019206\", \"message\": \"Hello Ajitesh! How have you been doing? Hope you are doing great. Good bye!\"}", PublisherService.TOPIC_INTERVIEWSTATUS);
        } catch (TopicNotSupportedException e) {
            e.printStackTrace();
        }
    }

}

Custom Interface for Publishing Message

Pay attention to the Publish API which takes message and topic name for publishing the message to an appropriate topic.

public interface PublisherService {
    //
    // Name of the topic
    //
    public static final String TOPIC_INTERVIEWSTATUS = "interview_status";
    //
    // Publish Message API
    //
    void publish(String message, String topic) throws TopicNotSupportedException;
}

AmazonSNSPublisherService Implementation

Pay attention to some of the following in the implementation given below:

  • An instance of AmazonSNSPublisherService is created (using @Autowired). Note that an instance of BasicSessionCredentials is passed to create an instance of AnazonSNS. The following is the code:
    this.amazonSNS = AmazonSNSClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(sessionCredentials)).build();
    
  • An instance of PublishRequest with TopicARN and Message
  • The message is published using Amazon SNS publish API. This returns an instance PublishResult representing the result of the publishing activity.
  • APIs on PublishResult can be used to process the publishing.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.services.sns.AmazonSNS;
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import com.amazonaws.services.sns.model.PublishRequest;
import com.amazonaws.services.sns.model.PublishResult;

@Service
public class AmazonSNSPublisherService implements PublisherService {

    private AmazonSNS amazonSNS;
    private String snsTopicInterviewStatusARN;

    @Autowired
    public AmazonSNSPublisherService(BasicSessionCredentials sessionCredentials, String snsTopicInterviewStatusARN) {
        this.amazonSNS = AmazonSNSClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(sessionCredentials)).build();
        this.snsTopicInterviewStatusARN = snsTopicInterviewStatusARN;
    }

    @Override
    public void publish(String message, String topic) throws TopicNotSupportedException {
        //
        // Get Appropriate Topic ARN
        //
        String snsTopic = getTopicARN(topic);
        //
        // Create Publish Message Request with TopicARN and Message
        //
        PublishRequest publishRequest = new PublishRequest(snsTopic, message);
        //
        // Publish the message
        //
        PublishResult publishResult = this.amazonSNS.publish(publishRequest);
        //
        // Evaluate the result: Print MessageId of message published to SNS topic
        //
        System.out.println("MessageId - " + publishResult.getMessageId());

    }

    private String getTopicARN(String topic) throws TopicNotSupportedException {
        switch(topic) {
        case TOPIC_INTERVIEWSTATUS:
            return this.snsTopicInterviewStatusARN;
        default:
            throw new TopicNotSupportedException("No matching topic supported!");
        }
    }
}

Configuration Beans for Loading Properties

Pay attention to some of the following:

  • AWS STS Temporary credential mechanism has been used for creating the session credentials which is used for creating an instance of AmazonSNS. I recommend you to read this page, AWS Temporary Credentials with Java & Spring Boot to understand how to use AWS temporary credentials.
  • Topic details such as ARN value is read from application.properties file.
@Configuration
@PropertySource("classpath:application.properties")
public class AWSAppConfig {

    private static final Integer TEMPORARY_CREDENTIALS_DURATION_DEFAULT = 7200;

    @Value("${aws.temporary.credentials.validity.duration}") String credentialsValidityDuration;  

    @Value("${aws.sns.topic.interviewstatus.ARN}") String snsTopicInterviewStatusARN;


    @Bean(name = "snsTopicInterviewStatusARN") 
    public String snsTopcARN() {
        return this.snsTopicInterviewStatusARN;
    }

    @Bean(name = "sessionCredentials")
    public BasicSessionCredentials sessionCredentials() {
        AWSSecurityTokenServiceClient sts_client = (AWSSecurityTokenServiceClient) AWSSecurityTokenServiceClientBuilder.defaultClient();
        GetSessionTokenRequest session_token_request = new GetSessionTokenRequest();
        if(this.credentialsValidityDuration == null || this.credentialsValidityDuration.trim().equals("")) {
            session_token_request.setDurationSeconds(TEMPORARY_CREDENTIALS_DURATION_DEFAULT);
        } else {
            session_token_request.setDurationSeconds(Integer.parseInt(this.credentialsValidityDuration));
        }

        GetSessionTokenResult session_token_result =
                sts_client.getSessionToken(session_token_request);
        Credentials session_creds = session_token_result.getCredentials();
        BasicSessionCredentials sessionCredentials = new BasicSessionCredentials(
                   session_creds.getAccessKeyId(),
                   session_creds.getSecretAccessKey(),
                   session_creds.getSessionToken());
        return sessionCredentials;
    }
}

Sample application.properties file

Pay attention to the ARN URI of the topic. It is read from AWS SNS console.

#
# Amazon SNS Topic 
#
aws.sns.topic.interviewstatus.ARN = arn:aws:sns:us-east-1:165412123501:interview_status

Further Reading / References

Summary

In this post, you learned about creating a sample/example application which publishes a message to AWS SNS Topic using Spring Boot and Java.

Did you find this article useful? Do you have any questions or suggestions about this article in relation to publishing the message to Amazon SNS Topic using a Spring Boot and Java app? Leave a comment and ask your questions and I shall do my best to address your queries.

Ajitesh Kumar

Ajitesh Kumar

I have been recently working in the area of Data analytics including Data Science and Machine Learning / Deep Learning. I am also passionate about different technologies including programming languages such as Java/JEE, Javascript, Python, R, Julia, etc, and technologies such as Blockchain, mobile computing, cloud-native technologies, application security, cloud computing platforms, big data, etc. I would love to connect with you on Linkedin. Check out my latest book titled as First Principles Thinking: Building winning products using first principles thinking.
Posted in AWS, Java. Tagged with , , .