AWS SDK 2: SQS Object Operations using Spring Boot

Upasana | September 09, 2019 | 4 min read | 986 views | AWS Tutorials


In this tutorial, we will walk through new AWS SDK 2.0 for doing message level operations on SQS queue. We will cover queue listing, send message and retrieve/delete message from SQS queue using AWS SDK 2.0

Table of contents

  1. Configure Gradle Build

  2. Creating Singleton Bean for SQS service client

  3. Sending a message to SQS queue

  4. Retrieving a message from SQS queue

  5. Deleting messages from queue

Why AWS SDK 2.0

The AWS SDK for Java 2.0 is a major rewrite of the version 1.x code base. It’s built on top of Java 8+ and adds several frequently requested features. These include support for non-blocking I/O and the ability to plug in a different HTTP implementation at run time.

For more information

Developer Guide V2

Please be noted that you can still use AWS SDK 1.0 alongside SDK 2.0 in the same project. Since package naming is different, there will be absolutely no conflicts using the two versions in parallel in single project.

1. Gradle dependencies

AWS has changed the dependencies versions and naming convention in SDK 2.0

You can follow the AWS Developer Guide for more details

To use the AWS SDK for Java in your Gradle project, use Spring’s dependency management plugin for Gradle.

build.gradle
group 'foo.bar'
version '1.0'

apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
mavenCentral()
}

dependencies {
	implementation platform('software.amazon.awssdk:bom:2.5.29')
	implementation 'software.amazon.awssdk:sqs'  (1)
}
1 Gradle automatically resolves the correct version of your SDK dependencies using the information from the BOM. No need to specify the version for service client libraries.

2. Creating Service Client for SQS

To make requests to AWS, you first need to create a service client object (SqsClient for example). AWS SDK 2.0 provides service client builders to facilitate creation of service clients.

AWS SDK 2.0 has changed the class naming convention and removed AWS prefix from most of the classes. AmazonSQSClient has been replaced with SqsClient. When using Spring Boot, we can simply create bean of SqsClient and use it as and when required.

Creating Bean for SQS Service Client
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;

@Configuration
public class SqsConfig {

    @Bean
    public SqsClient sqsClient(SqsConfig sqsConfig) {
        SqsClient sqs = SqsClient.builder()
                .credentialsProvider(StaticCredentialsProvider
                    .create(AwsBasicCredentials
                        .create(sqsConfig.getAccessKey(), sqsConfig.getSecretKey())))
                .region(Region.of(sqsConfig.getRegion()))
                .build();
        return sqs;
    }
}
Service Client Lifecycle

Service clients in the SDK are thread-safe. For best performance, treat them as long-lived objects. Each client has its own connection pool resource that is released when the client is garbage collected. The clients in the AWS SDK for Java 2.0 now extend the AutoClosable interface. For best practices, explicitly close a client by calling the close method.

3. Listing Queues

We can leverage SqsClient created in previous step to list queues for a given region and account.

Listing queues for a given region
ListQueuesResponse queues = sqsClient.listQueues();
final List<String> queueUrls = queues.queueUrls();
queueUrls.forEach(s -> logger.info(s));

4. Getting Queue URL for a SQS queue

We need to obtain queue url in order to make operations SQS queue.

GetQueueUrlResponse getQueueUrlResponse = sqsClient
                            .getQueueUrl(GetQueueUrlRequest.builder()
                            .queueName(queueName)
                            .build());
queueUrl = getQueueUrlResponse.queueUrl();
logger.info("Autoscaling queueUrl: {}", queueUrl);

This queueUrl will be used in next two sections for adding messages and retrieving messages from SQS queue.

4. Adding a message to the Queue

SqsClient provides a sendMessage method that takes queueUrl and message payload that you want to publish to the SQS queue.

Once you have obtained the SQS url, then below code will allow you to publish message to the queue.

public class SqsMsg {   (1)
    String id;
    //Getter & Setter removed for brevity
}

class ScratchPad {

    public void addMessage(String identifier) {
        SqsMsg msg = new SqsMsg(identifier);
        final String asString;
        try {
            asString = objectMapper.writeValueAsString(msg);
            sqsClient.sendMessage(SendMessageRequest.builder()
                    .queueUrl(queueUrl) (2)
                    .messageBody(asString)
                    .delaySeconds(1)
                    .build());
            logger.info("Added msg {} to the queue", identifier);
        } catch (JsonProcessingException e) {
            logger.error("Error publishing msg to queue", e);
        }
    }
}
1 SqsMsg defines the schema for message that we want to publish to SQS queue.
2 We obtained queueUrl in the previous step.

sendMessage returns SendMessageResponse using which we can obtain the messageId of recently published message.

5. Retrieve and remove the message from Queue

The consumer application will retrieve the message from the Queue and delete it if successfully processed.

Here in the blow code, we are:

  1. Getting one message from queue at a time

  2. Converting the message into domain object using ObjectMapper class

  3. Removing the message by providing the receipt handle

Retrieve & delete message from SQS
class ScratchPad {

    public void removeMsg() throws IOException {
        ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
                .queueUrl(queueUrl)
                .maxNumberOfMessages(1)
                .build();
        List<Message> messages = sqsClient.receiveMessage(receiveMessageRequest).messages();
        for (Message message : messages) {
            final String body = message.body();
            final SqsMsg sqsMsg = objectMapper.readValue(body, SqsMsg.class);
            logger.info("Delete msg: {}", sqsMsg);
            DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
                    .queueUrl(queueUrl)
                    .receiptHandle(message.receiptHandle())
                    .build();
            sqsClient.deleteMessage(deleteMessageRequest);
        }
    }
}

That’s all for now.


AWS Tutorials:
  1. AWS Lambda Interview Questions for Developers
  2. AWS SDK 1.x - S3 file download & upload
  3. Python: Send event from AWS Lambda to AWS SQS
  4. S3 File upload & download with AWS Java SDK v2
  5. AWS Lambda in Kotlin using Spring Cloud Function
  6. Creating AWS Lambda using python 3.6
  7. Invoke AWS Lambda from a Kotlin Client
See all articles in AWS Tutorials
Top articles in this category:
  1. AWS SDK 1.x - S3 file download & upload
  2. Python: Send event from AWS Lambda to AWS SQS

Recommended books for interview preparation:

Find more on this topic:
Buy interview books

Java & Microservices interview refresher for experienced developers.