Scala, Spring 3, Actor, REST, IoC configuration by code...
... and well, I should be able to put some other buzz words in that title, perhaps agile and Scrum ?
I wanted to test Spring 3 "configuration via code" new feature, and especially how well it works with Scala.
As a Tapestry 5 (former) user, I'm a great fan of IoC configuration done in Java (or Scala). From a developer point of view, it's so much more easy and robust (especially refactoring prone) to have access to a real, type safe language in place of an ersatz like XML... and most of the time, it's also much less verbose.
I needed a pretext and decided to build a trivial web application that allows to upload files to some URL, and post-process them - a rather usual need in a web-application. That will allow to test Spring 3 new "REST" features, a bit of Expression Language, and put in a little Scala Actor to let the (long) processing be done asynchronously.
I also used maven, and Slf4j with NoCommonsLogging to be able to use Slf4j with Spring.
What exactly does the application:
- wait uploads on a REST endpoint URL;
- when an upload comes, save it into a temporary file;
- signal the file's availability to a "file processor". That processing may take a looooooong time to process (for example, it's a big XML report, with a lot of parsing, input validation, graphs generation, etc), and so, the processing should be done in a side process.
Everything comes along really well, and the result is available on github.
To test it, you will need a JVM and Maven (if you haven't done it yet and are not limited by production constrains, just go download the last 1.6 JVM (1.6.0_18), the performances improvements with the last two releases are impressive)
% git clone git://github.com/fanf/scala-spring3-upload.git
% cd scala-spring3-upload
% mvn jetty:runYou should have a Jetty server up and running on localhost.
Now, you can upload a file to http://localhost:8080/upload, and see that the upload is processed and HTTP code returned, and then an asynchronous process is launched to process the file - well, actually it just waits 10 seconds and delete it.
On Linux, you can use Curl to post files:
% curl -F FileToUploadName=@/path/to/the/file/to/upload http://localhost:8080/upload/
Details about the project
Here comes the different files and their purpose:
It contains usual servlet configuration files, in XML :
- web.xml : standard Java servlet config file
UPDATE: as Chris Beams shows me, I should have RTFM more carefully. It's now possible (I do believed it wasn't in first RCs), and I updated the sources to have a full ScalaBased configuration.
That package contains the code to receive file (UploadEndpoint.scala) and process them (FileProcessor.scala).
As you can see, there is very little code, and most of it is self-explanatory.
That last package only contains the AppConfig.scala file, the place where Spring IoC configuration is done.
I really like the cleaness of that file, compared to what may have been the equivalent XML one.
The default sleepTime value is especially cool, typically a things hard to do when you only have XML
This little project could be a good starting-point if you want to use Spring 3 with Scala, or Slf4j with Spring.
I'm also rather impressed by how much little code is needed with Spring 3 to configured the REST endpoint.
And building little asynchronous services thanks to actor is just too simple (OK, here it's a toy, but if you want serious business with actor, look at AKKA).