DEV Community

Cover image for Using LocalStack in your Java Project - Part 1
Gyowanny (Geo) Queiroz
Gyowanny (Geo) Queiroz

Posted on

Using LocalStack in your Java Project - Part 1

I've been away from the Java world for a while, but I recently helped an old friend with a payment gateway project that required integration with certain AWS services. Unfortunately, the DevOps team didn't provide him with a test account in time to meet his deadline. To solve this issue, we decided to try LocalStack and we were pleasantly surprised by how easy it was to set up and use.
Our mission was to use SQS for payment processing logic to publish and consume messages asynchronously within the payment journey.
In this post I will show you how we configured, used and tested the code with LocalStack.

Configuration

First of all, make sure you have Docker installed.

The project uses Spring Boot 3 with Maven, so the required dependencies are:

    <dependency>
      <groupId>io.awspring.cloud</groupId>
      <artifactId>spring-cloud-aws-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>io.awspring.cloud</groupId>
      <artifactId>spring-cloud-aws-starter-sqs</artifactId>
    </dependency>
Enter fullscreen mode Exit fullscreen mode

A Spring configuration class was created to set things up

@Configuration
@Slf4j // Using Lombok
public class AwsSqsLocalstackConfiguration {
  @Value("${spring.cloud.aws.credentials.access-key}")
  protected String awsAccessKey;

  @Value("${spring.cloud.aws.credentials.secret-key}")
  protected String awsSecretKey;

  @Value("${spring.cloud.aws.region.static:us-east-1}")
  protected String awsRegion;

  protected AwsCredentialsProvider amazonAWSCredentialsProvider() {
    return StaticCredentialsProvider.create(AwsBasicCredentials.create(awsAccessKey, awsSecretKey));
  }

  static LocalStackContainer localStack =
      new LocalStackContainer(DockerImageName.parse("localstack/localstack"));

  @Bean
  @Primary
  SqsAsyncClient sqsClient() {
    //startLocalStack();
    localStack.start();
    return SqsAsyncClient.builder()
        .endpointOverride(URI.create(localStack.getEndpointOverride(SQS).toString()))
        .credentialsProvider(amazonAWSCredentialsProvider()).region(Region.of(awsRegion)).build();
  }

  @Bean
  SqsTemplate sqsTemplate(SqsAsyncClient sqsAsyncClient) {
    return SqsTemplate.builder().sqsAsyncClient(sqsAsyncClient).build();
  }

  // Telling SQSListener to use object mapper for obj serialization.
  @Bean
  SqsListenerConfigurer configurer(ObjectMapper objectMapper) {
    return registrar -> registrar.setObjectMapper(objectMapper);
  }
}
Enter fullscreen mode Exit fullscreen mode

To save time and initialize LocalStack with queues, simply add the following code to the configuration class above. Otherwise, you can execute shell commands directly in the container to add it manually.

  @Autowired
  private LocalstackQueues localstackQeues;

  private void startLocalStack() {
    localStack.start();
    // Creating the queues
    localstackQeues.queues().forEach(queue -> {
      try {
        localStack.execInContainer("awslocal", "sqs", "create-queue", "--queue-name", queue);
        log.info("Queue {} created", queue);
      } catch (IOException e) {
        throw new RuntimeException(e);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    });
    log.info("LOCALSTACK RUNNING AT {}", localStack.getEndpointOverride(SQS).toString());
  }

  // Add the queues in your application.yml e.g.
  // localstack:
  //   queues:
  //     - my.queue.1
  //     - my.queue.2  
  @Component
  @ConfigurationProperties(prefix = "localstack.queues")
  record LocalstackQueues(List<String> queues) {

  }
Enter fullscreen mode Exit fullscreen mode

Ensure that LocalStack's Docker container is running without any errors during initialization by executing your Spring Boot application.

Docker desktop
Image description

Stay tuned for part 2, where we'll write both an SQS Publisher and an SQS Listener. And make no mistake, part 3 will show you how to write tests with LocalStack.

Top comments (0)