I am the founder and lead developer of Hibernate Envers, a Hibernate core module, which provides entity versioning/auditing capabilities. I am also one of the co-founders of SoftwareMill, a company specializing in delivering customized software solutions (http://softwaremill.com, "Extraordinary software as a standard"), based on Java and JBoss technologies. After work, apart from being involved in development of Envers, I work on several small open source projects, like ElasticMQ (simple message queue written in Scala with an SQS interface), projects around static analysis (using JSR 308 - Typestate Annotations/ Checkers Framework and FindBugs), and some CDI/Weld (not always portable) extensions, like autofactories or stackable security interceptors. I am also interested in new JVM-based languages, especially with functional elements (like Scala, JRuby) and frameworks built using them (like Lift), as well as improving the ways we use Dependency Injection. Adam is a DZone MVB and is not an employee of DZone and has posted 52 posts at DZone. You can read more from them at their website. View Full User Profile

Introducing ElasticMQ: Scala SQS alternative

08.17.2011
| 4448 views |
  • submit to reddit

Wanting to explore Scala and some new Scala/Java libraries I started writing ElasticMQ. It is a simple message queueing system, following closely Amazon SQS semantics and exposing a REST SQS-like interface. Currently only the basic operations are implemented. ElasticMQ can be useful as an SQS replacement, e.g. for for testing SQS applications.

My aim was to make the usage as simple as possible, that’s why to create a new node and expose the REST interface all you need to do is:

	
val node = NodeBuilder.createNode
val server = SQSRestServerFactory.start(node.nativeClient, 8888,
                 "http://localhost:8888")

Now simply point your SQS client to http://localhost:8888 and you should be able to create/delete queues, change the visibility timeout, send and receive messages.
When you are done using ElasticMQ, you can shutdown the node and the server:

server.stop()
node.shutdown()

All of the source code is available on GitHub. See the readme for instructions on how to add ElasticMQ as a dependency to your Maven or SBT project.

On the technical side, ElasticMQ uses a number of interesting things.

Firstly, there’s Netty, an asynchronous, event-driven java NIO framework. I used Netty to implement the REST server. All of the requests are processed in a non-blocking way.

The messages are currently stored in an in-memory H2 database (but this can be easily changed to point e.g. to a MySQL or PostgreSQL DB), and managed using the Squeryl Scala library. Squeryl lets you write SQL queries as typesafe Scala code, e.g.:

update(messages)(m =>
  where(m.id === message.id and m.lastDelivered === message.lastDelivered)
    set(m.lastDelivered := lastDelivered))

For integration testing I am using the Typica library.

On the Scala side, I created a simple internal DSL for defining rest handlers. The server (which uses Netty) is generic and can be provided with any number of “rest handlers”, to which requests are dispatched. Each rest handler specifies what is the path it will respond to, what are the required parameters and what should be run in response to a request. For example:

val handler1 = (createHandler
   forMethod GET
   forPath (root / "products" / %("name") / "price")
   requiringParameters List("currency", "quantity")
   requiringParameterValues Map("department"->"electronics")
   running electronicsPriceRequestLogic)
 
val server = RestServer.start(handler1 :: handler2 :: … :: Nil, 8888)

See the RequestHandlerLogic file for the implementation and RequestHandlerBuilderTestSuite for example usage.

In fact there’s another small DSL for defining paths. For example (root / "a" / "b" / "c") will only match a/b/c, but (root / "a" / %("p1") / "c") will match a/anything/c, with the middle component being assigned to the p1 parameter. You can also use regex, e.g. (root / "a" / """[a-z0-9]+""".r / "c") for matching path components. See the RestPath class and test for details.

Not sure where ElasticMQ will go in the future, but I can image lots of interesting possibilities. So stay tuned :).

Comments about the code, Scala style, Netty/Squeryl usage are very welcome! As well as any other ideas, improvement suggestions etc.

Adam

 

From http://www.warski.org/blog/2011/08/introducing-elasticmq-scala-sqs-alternative/

Published at DZone with permission of Adam Warski, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)