Send messages to an Amazon SQS queue using Spring Boot

In this article we’ll use Spring Boot to create an endpoint that can send messages to an Amazon Simple Queue Service (SQS) queue. In our application messages will consist of famous quotes.

Amazon SQS and Spring Series

This article is part of a series:

  1. Create a queue in Amazon SQS
  2. Set up a Spring Boot app with Amazon SQS
  3. Send messages to an Amazon SQS queue using Spring Boot
  4. Receive messages from an Amazon SQS queue using Spring Boot

Create a class for the quote message

The following Data Transfer Object (DTO) defines the contents of the quote message. The text field is mandatory.

package com.makolyte.springsqsstarter.dto; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import javax.validation.constraints.NotNull; public class Quote { @NotNull private final String text; private final String author; @JsonCreator public Quote(@JsonProperty("text") String text, @JsonProperty("author") String author) { this.text = text; this.author = author; } public String getText() { return text; } public String getAuthor() { return author; } @Override public String toString() { return "Quote{" + "text='" + text + '\'' + ", author='" + author + '\'' + '}'; } }

Configure the QueueMessagingTemplate

We’re going to utilize a QueueMessagingTemplate to send the quote. This class contains various methods for sending and receiving messages to/from an Amazon queue. Before using the class, we need to configure it, so it can connect to Amazon SQS.

package com.makolyte.springsqsstarter; import com.amazonaws.services.sqs.AmazonSQSAsync; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.aws.core.env.ResourceIdResolver; import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringSqsStarterApplication { public static void main(String[] args) { SpringApplication.run(SpringSqsStarterApplication.class, args); } @Bean public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSQSAsync, ResourceIdResolver resourceIdResolver) { return new QueueMessagingTemplate(amazonSQSAsync, resourceIdResolver); } }

We’re creating a bean in the main application class with the necessary configuration:

  • The AmazonSQSAsync parameter is automatically created and passed based on the Amazon credentials defined in application.properties.
  • Since our app is running inside a CloudFormation stack, we’re also passing a ResourceIdResolver to convert logical resource IDs (e.g. the queue name such as “QuoteQueue”) to physical resource IDs used by AWS to uniquely identify resources (e.g. 53DRALVWT774).

Create an endpoint to send messages

Next, we define a POST endpoint to send a quote. We’re adding @Valid so the quote is validated before it’s sent to the queue (e.g. it verifies the text field is present). We use the QueueMessagingTemplate class we configured previously to convert and send the message.

package com.makolyte.springsqsstarter.controller; import com.makolyte.springsqsstarter.model.Quote; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @RestController @RequestMapping("/sqs") public class SqsController { private static final Logger LOG = LoggerFactory.getLogger(SqsController.class); private final QueueMessagingTemplate queueMessagingTemplate; public SqsController(QueueMessagingTemplate queueMessagingTemplate) { this.queueMessagingTemplate = queueMessagingTemplate; } @PostMapping("/quotes") @ResponseStatus(HttpStatus.CREATED) public void sendQuote(@RequestBody @Valid Quote quote) { LOG.info("Sending quote {} to SQS", quote); this.queueMessagingTemplate.convertAndSend("QuoteQueue", quote); } }

Start the app and you can send a request to the new endpoint using a tool such as Postman.

Postman POST Request to send a quote to the queue

To see the quote in AWS:

  1. Go to the SQS Management Console.
  2. Select the queue.
  3. Under Queue Actions select to View/Delete Messages.
  4. Click on Start Polling for Messages.
sqs-queue-view-quote
Quote sent as seen on AWS SQS Management Console

Add tests

We can write an integration test for the send quote endpoint using @WebMvcTest and MockMvc. I’m using @WebMvcTest because it instantiates only the web layer instead of the entire application context.

The following test verifies that we can call the endpoint passing in a quote and that we get a 201 (Created) status code back.

package com.makolyte.springsqsstarter.controller; import com.fasterxml.jackson.databind.ObjectMapper; import com.makolyte.springsqsstarter.dto.Quote; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest class SqsControllerTest { @Autowired private MockMvc mockMvc; @MockBean private QueueMessagingTemplate queueMessagingTemplate; @Test public void sendQuoteToSqs() throws Exception { ObjectMapper mapper = new ObjectMapper(); Quote q = new Quote( "With the new day comes new strength and new thoughts.", "Eleanor Roosevelt" ); String json = mapper.writeValueAsString(q); mockMvc.perform(post("/sqs/quotes") .content(json) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()); } }

You can run the test on the command line using Maven or in your IDE:

Running test using IntelliJ IDEA

Code

The code for this application is available on GitHub.

Leave a Comment