Skip to content

Instantly share code, notes, and snippets.

@bryantrobbins
Created September 29, 2017 01:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryantrobbins/818b914c1ae3e76704a8a88582f31e70 to your computer and use it in GitHub Desktop.
Save bryantrobbins/818b914c1ae3e76704a8a88582f31e70 to your computer and use it in GitHub Desktop.
ElasticMQ as a local drop-in for AWS SQS in a SpringBoot + Spring JMS setup
// AWS provides a JMS library for SQS: https://aws.amazon.com/blogs/developer/using-amazon-sqs-with-spring-boot-and-spring-jms/
// I wanted to use that setup in a Spring Boot app, and to run some tests against an in-memory
// ElasticMQ queue, which is SQS (and AWS Java SDK) compatible. In case your scenario is EXACTLY like mine ... here you go
@RunWith(SpringRunner.class)
@SpringBootTest
// This annotation is important: Forces the Application Context (and SQS connections) to reset between tests. ElasticMQ will fail to
// stop if there are active connections.
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class ApplicationTests {
private static String endpoint;
private static SQSRestServer sqsRestServer;
private static String queueUrl;
private static AmazonSQSClient sqsClient;
@BeforeClass
public static void setup() {
// Creates an Elastic MQ Server on a Random Port
sqsRestServer = SQSRestServerBuilder
.withInterface("0.0.0.0")
.withDynamicPort()
.start();
// The equivalent of an SQS service endpoint
endpoint = "http://localhost:" + sqsRestServer.waitUntilStarted().localAddress().getPort();
// An SQS client for operating on queues outside of JMS listeners, etc. in app
sqsClient = new AmazonSQSClient().withEndpoint(endpoint);
// We need this queue to exist before the Spring Application Context loads. Create it and save the URL
queueUrl = sqsClient.createQueue("some-queue").getQueueUrl();
}
// Note this cleanup only runs after the whole class of tests
// The Dirty Context cleanup refers to re-creating the Configuration class (next block) between tests
@AfterClass
public static void cleanup() {
// Delete the queue
sqsClient.deleteQueue(queueUrl);
// Wait for the server to die
sqsRestServer.stopAndWait();
}
// Spring Beans overrides to use for tests
// Here we override one bean (the SQSConnectionFactory) in order to point it to our local SQS service instead
// of e.g., AWS SQS us-east-1. (Note: Actual ApplicationContext not included here - see AWS Blog post linked above
// for sample.)
@TestConfiguration
static class LocalQueueConfiguration {
// TODO: Use an in-memory SQS clone to run in-memory service-level tests
@Bean
public SQSConnectionFactory sqsConnectionFactory() {
return SQSConnectionFactory.builder()
.withAWSCredentialsProvider(new AWSStaticCredentialsProvider(new BasicAWSCredentials("X", "X")))
.withEndpoint(endpoint)
.build();
}
}
@Test
// This is a basic test that ships with generated Boot apps
// Will fail if Beans fail to load, otherwise succeed.
public void contextLoads() {
}
// Put some more interesting tests here, e.g., ones that put messages on a queue your app cares about!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment