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.
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
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.
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.
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>
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();
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 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);
});
Close the connection when the process is complete. Just call close ().
sqsClient.close();
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