Develop a Java application that uses Amazon SQS (Part 1)

About this article

I researched how to use Amazon SQS in Java applications for a certain job. I didn't use SQS after all, but here's what I researched.

What is Amazon SQS?

Amazon SQS (Simple Queue Service) is a managed message queuing service available on AWS. It is available from a variety of applications using the AWS SDK. Details are below.

Amazon Simple Queue Service Documentation

Using Elastic MQ

Actually, I couldn't use my AWS account for various reasons. So I tried using Elastic MQ, which can use messaging with an SQS compatible interface.

ElasticMQ - Github

This time, we will use the following Docker image.

$ docker run --name test-sqs -p 9324:9324 softwaremill/elasticmq
Unable to find image 'softwaremill/elasticmq:latest' locally
latest: Pulling from softwaremill/elasticmq
・ ・ ・
07:14:26.858 [main] INFO  org.elasticmq.server.Main$ - Starting ElasticMQ server (0.14.7) ...
07:14:27.625 [elasticmq-akka.actor.default-dispatcher-3] INFO  akka.event.slf4j.Slf4jLogger - Slf4jLogger started
07:14:28.722 [elasticmq-akka.actor.default-dispatcher-3] INFO  o.e.rest.sqs.TheSQSRestServerBuilder - Started SQS rest server, bind address 0.0.0.0:9324, visible server address http://localhost:9324
07:14:28.723 [main] INFO  org.elasticmq.server.Main$ - === ElasticMQ server (0.14.7) started in 2402 ms ===

Try accessing it with the AWS CLI. Set a dummy Credential in advance.

$ aws configure 
AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxx
・ ・ ・

Create a queue and try sending a message. (There are two types of queues that can be created in SQS: standard queues and FIFO queues, but this article uses standard queues.) You must specify the --endpoint-url option to access the Elastic MQ container that runs locally.

$ aws sqs create-queue --queue-name test --endpoint-url http://localhost:9324
{
    "QueueUrl": "http://localhost:9324/queue/testqueue"
}

$ aws sqs send-message --queue-url http://localhost:9324/queue/testqueue --message-body "THIS IS TEST MESSAGE." --endpoint-url http://localhost:9324
{
    "MD5OfMessageBody": "81fe6881acb296073763f9e5af225aa9",
    "MD5OfMessageAttributes": "d41d8cd98f00b204e9800998ecf8427e",
    "MessageId": "bfb653eb-390a-45d1-bf26-bf52d795099e"
}

Receives queued messages.

$ aws sqs receive-message --queue-url http://localhost:9324/queue/testqueue --endpoint-url http://localhost:9324
{
    "Messages": [
        {
            "MessageId": "bfb653eb-390a-45d1-bf26-bf52d795099e",
            "ReceiptHandle": "bfb653eb-390a-45d1-bf26-bf52d795099e#eea50e0b-dd35-4caf-bce8-479f4b1168f3",
            "MD5OfBody": "81fe6881acb296073763f9e5af225aa9",
            "Body": "THIS IS TEST MESSAGE."
        }
    ]
}

By the way, SQS does not automatically remove received messages from the queue. After receiving the message, the message can be received again after a certain period of time (visibility timeout). Therefore, explicitly delete the received message as shown below.

$ aws sqs delete-message --queue-url http://localhost:9324/queue/testqueue --endpoint-url http://localhost:9324 --receipt-handle bfb653eb-390a-45d1-bf26-bf52d795099e#28831fc9-1c77-44e1-813d-7715bde62312

As you can see, Elastic MQ can be used in the same way as SQS using the AWS CLI.

Access using AWS SDK for Java

Finally, let's get into the main subject and explain how to develop a Java application that accesses SQS. First, use the AWS SDK for Java 2.0 provided by AWS.

How to get started with AWS SDK for Java 2.0-AWS SDK for Java

If you are using Maven, you will add the dependency to pom.xml as follows. (Adding only the dependencies for SQS, not the entire SDK)

	<dependencyManagement>
	  <dependencies>
	    <dependency>
	      <groupId>software.amazon.awssdk</groupId>
	      <artifactId>bom</artifactId>
	      <version>2.7.0</version>
	      <type>pom</type>
	      <scope>import</scope>
	    </dependency>
	  </dependencies>
	</dependencyManagement>
・ ・ ・
     <dependencies>
	    <dependency>
	      <groupId>software.amazon.awssdk</groupId>
	        <artifactId>sqs</artifactId>
	    </dependency>
     </dependencies>

Connection to SQS (Elastic MQ)

Finally, I'm going to code Java. First of all, regarding the connection to the service, it is necessary to set the appropriate Credential and endpoint URL for the client builder provided by the SDK. As mentioned earlier in the AWS CLI, you must explicitly override the endpoint URL to connect to ElasticMQ (call endpointOverride ()).

    SqsClient sqsClient = SqsClient.builder()
            .credentialsProvider(DefaultCredentialsProvider.create())
            .region(Region.US_EAST_1)
            .endpointOverride(new URI("http://localhost:9324")) //URL for Elastic MQ container
            .build();

Access to queue information

Let's get the list of queues created on ElasticMQ and the URL of the queue created with CLI earlier. From here, you can check the code example provided by AWS at the link below. Amazon SQS example using AWS SDK for Java

    String prefix = "test";
    ListQueuesRequest listQueuesRequest = ListQueuesRequest.builder().queueNamePrefix(prefix).build();
    ListQueuesResponse listQueuesResponse = sqsClient.listQueues(listQueuesRequest);
    for (String url : listQueuesResponse.queueUrls()) {
        System.out.println(url);
    }

    String queueName = "testqueue";
    GetQueueUrlResponse getQueueUrlResponse =
        sqsClient.getQueueUrl(GetQueueUrlRequest.builder().queueName(queueName).build());
    String queueUrl = getQueueUrlResponse.queueUrl();
    System.out.println(queueUrl);

Send and receive messages

Send and receive messages using the queue URL obtained above. Although not covered in detail here, the SDK also supports batch sending of multiple messages.

//Send Messege
    SendMessageResponse res = 
        sqsClient.sendMessage(
            SendMessageRequest.builder()
            .queueUrl(queueUrl)
            .messageBody("Hello world!")
            .delaySeconds(10)
            .build());

//Receive message
    ReceiveMessageRequest receiveMessageRequest = 
        ReceiveMessageRequest.builder()
          .queueUrl(queueUrl)
          .maxNumberOfMessages(5)
          .build();
    List<Message> messages= sqsClient.receiveMessage(receiveMessageRequest).messages();
    messages.forEach(m -> System.out.println(m.body()));

And don't forget to delete it as you did with the CLI.

    messages.forEach(m -> {
        DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
          .queueUrl(queueUrl)
          .receiptHandle(m.receiptHandle())
          .build();
        DeleteMessageResponse delRes = 
            sqsClient.deleteMessage(deleteMessageRequest);
    });

Disconnect from SQS

Close the connection when the process is complete. Just call close ().

sqsClient.close();

Well next time

What do you think. It may be that the code is a little verbose. If you pay attention to the connection, Elastic MQ seems to be usable enough for development.

Next time would like to challenge access using JMS and Spring.

Recommended Posts

Develop a Java application that uses Amazon SQS (Part 1)
Develop a Java application that uses Amazon SQS (Part 2)
A bat file that uses Java in windows
How to implement a job that uses Java API in JobScheduler
Access Teradata from a Java application
Build a web application development environment that uses Java, MySQL, and Redis with Docker CE for Windows
Creating a java web application development environment with docker for mac part1
Create a java web application development environment with docker for mac part2
[Java] Implement a function that uses a class implemented in the Builder pattern
I want to develop a web application!
Creating a matrix class in Java Part 1
Connect to Aurora (MySQL) from a Java application
[Ruby] A program that uses search and each_with_index
CICS-Run Java application-(1) Run a simple sample app