How to: Emulate Amazon Simple Queue Service (SQS) for Testing Purposes
Amazon Simple Queue Service (SQS) is a fully managed message queuing service from Amazon.
If you want to integrate it, you may also want to test if it works. SQS has probably a sandbox to test it but if you don’t want to get stuck searching for it, or you don’t want to get crazy with login procedures, you can use a mock service that acts as an SQS queue* .
Why do we need this? Why can’t we use a simple Wiremock that always responds “200, OK”?
You can’t do it because the response of SQS is a dynamic response dependent from the request, and it’s based on some MD5 calculation.
What we have done is an extension of Wiremock that always responds something like “200, OK”, with all the fields correctly calculated for SQS. It was both easy and not-so-easy, because every easy task it’s never a “It’s just …“.
In this case, it was more of a “it’s just not enough to…” — just spinning a docker container up or adding a class to the classpath would simply not do.
How To, Step by step guide
First of all we need to define a class that extends the
ResponseDefinitionTransformer class with two easy to implement methods:
applyGobally that returns true, means that “all the requests will receive this response”.
getName it’s a method that Wiremock needs. Then you must implement the real method that responds correctly, the method is transform
calculateResponse does the dirty job, and it’s a dirty method (I know it could be refactored…)
This method gets the body of the request, splits it because it’s an url-like body, and then calculates the MD5 of all the attributes, types and values according to SQS documentation.
updateLengthAndBytes it’s a method to update the MD5 calculation.
To be honest, we also created an additional class SimplifiedMessageAttribute:
After this step, you can build an XML document (the implementation of this is not in this post because it‘s cumbersome) and include the calculated fields (md5OfMessageBody and md5OfMessageAttributes). For other fields, requestId and messageId, we used hard coded values. The final result should be something like this:
After this, you can build your project and obtain a jar.
How can we integrate this into Wiremock?
That’s not so easy. What I’ve found is that you have to move your jar in the same path of the Wiremock jar and start the Wiremock with:
Wiremock has no plugin mechanisms, so what you are doing with this command is:
with -cp “*” you are telling Java “take all the jars in this folder”
… your main class is here: com.github.tomakehurst.wiremock.standalone.WireMockServerRunner
… and use this extension: your.package.name.SQSMock
From this point onwards, you can use it directly, build a docker container or whatever you want.
IT is not an easy task and, from my point of view, every layer added to simplify things is a new topic to learn and understand.
During this journey we have learnt about SQS, wiremock, mvn, unit test and obviously Java. I want to thank:
- Giuseppe Gaeta (Tech Lead)
- Matteo Moci (Software Dev Engineer II)
- Camillo Quatrini (QA Evangelist)
- Tiziana Battiston (Travel Agencies Manager, proofreader)
- SqS documentation: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-attributes.html
- Wiremock Extension: http://wiremock.org/docs/extending-wiremock/
* There are some restrictions: such service doesn’t work for not-string attributes.