In this series, we’ll look at creating modular and flexible server applications based on OSGi/Equinox and Restlet. The first article of this series covers the basics: It will walk you through creating a simple REST style web service using Restlet and show you how to roll it into a standalone application based on the equinox OSGi framework.
The next posts will go into how the different Restlet types can be assembled into bigger applications. We’ll then build extension points to lift the actual plumbing to a declarative level instead of hardcoding it.
We’ll see that the uniform interface proposed in the REST architectural style and the extension/extension point mechanisms in Equinox make quite a good couple.
PrerequisitesAll we need for development is a current Eclipse RCP IDE and the Restlet distribution. To test drive our service we’ll also need a tool that allows us to play with HTTP requests. A simple one to get started is the Firefox add-on Poster 1, but there are others 2 Â 3, too.
We’ll use the current Eclipse Helios RCP Release (3.6M6) 4 and the current Restlet 2.0 Release Candidate 5. You’ll probably be just fine with a 3.5 Eclipse as well, but I haven’t tested it. If it works for you, please drop me a note.Extract the Restlet distribution to an arbitrary directory; start Eclipse and create a new workspace.
Preparing the Target PlatformEclipse allows for using target platforms 6 to define the bundles that make up the platform you are developing for. Everything in your workspace will be built and run against the currently used target platform.
Conveniently, all Restlet libraries are come in the form of OSGi bundles. This means we can simply add Restlet to the target platform and don’t need to pollute our workspace with third party libraries. This also means we’ll have one excuse less to slack off 7.
First, we’ll need to create the new target platform. Since we’re currently not interested in getting the leanest possible platform, we’ll just start from the the currently running platform, which is simply the eclipse installation we’re working in. Then we add everything from our Restlet distribution and give the newly created platform an appropriate name. I used “Helios M6 RCP + Restlet”.
In the preferences dialog (Window->Preferences), open the Target Platform preference page and add a new Platform.
As said above, we just start from the current platform.
You see that all bundles from our eclipse installation are already included, now we can add the Restlet bundles additionally.
Choose the directory you extracted the Restlet distribution to. All bundles are contained in the lib/ folder.
Your target platform should now look like this. Verify that the Restlet bundles can be found.
Make sure that the new platform is activated and save the preference page.
Creating the Application BundleNow that the platform is set up, we are nearing the point on which we actually start writing code. But before that, we need a bundle that hosts our code and our http server 8. Use the New Plug-In9 Wizard to create a bundle targeted to run on equinox and have it generate an Activator class for us.
Pick a nicer name if you can think of one.
Writing the Application CodeFinally. Coding time. We’ll create an application that says “Hello World”. Or something different. In fact, we’ll write an application that allows you to tell it what to say 10. You can find the complete code on github 11
The following packages from Restlet are used by our application. Use the ‘Dependencies’ tab in the plug-in manifest editor to import the packages or simply add them to the MANIFEST.MF by hand: Our application will consist of four artifacts:
- The application itself,
- the server that hosts the application,
- a resource for the greeting text
- and a kind of persistent storage that holds the current greeting text.
The resource is responsible for returning the current greeting text and accepting and saving a new one. The requests will be served by looking up or setting the text in the storage component. The resource class needs to be derived from Restlet’s ServerResource. The methods corresponding to the request types GET and PUT are annotated with @Get and @Put respectively. This makes them known to the restlet engine. The put method disassembles the request and looks for a form value (this means that our PUT requests need to have the content type application/x-www-form-urlencoded) Â named ‘greeting’.
The application is even simpler: We just extend Restlet’s Application and overwrite the createInboundRoot method. In this method, we attach our resource to an URL 13.
To attach this application to a server and run it, we’ll use the Activator’s start method. This method is called by the OSGi runtime whenever this bundle is started. It would be wise to stop the server when the bundle is stopped, but I’ll leave that to you as an exercise.
That’s all we have to do. We can now go ahead and run, debug, export and deploy the application. Remember, if you get stuck, the whole code can be found on github 11.
RunningNow that we have crafted this awesome piece of niceness, let’s run it to see whether anything happens. To do so, we need to define a launch configuration that knows which bundles are part of our application.
Open the ‘Run configurations’ dialog from the toolbar menu of the ‘Run’ button and create a new launch configuration.
To avoid having loads of bundles we don’t need in our application, deselect all bundles first, then select only our application bundle from the workspace.
If you validate the configuration, it complains about missing Restlet libraries. This is correct as we have not yet told our configuration to include those.
Now run it already, would you? Of course you can also run in debug mode and add breakpoints to see what is going on behind the scenes.
Simply click ‘Add required bundles’ and validate again. Now everything we need is included in the launch configuration.
TestingThe console view should now tell you that the HTTP server has been started. Point your browser to http://localhost:8182/tutorial1/greet. There you are.
If you go back to the console view within eclipse, you’ll see that some requests have been logged.
To set the current greeting using a PUT request, we use the Poster Firefox add-on. Open Poster from the ‘Extras’ menu 15, go to the Parameters tab and add a parameter called ‘greeting’ with an arbitrary value (remember, this is what we are looking for in the method annotated with @Put). ï»¿ Go back to the ‘Content to send’ tab, enter the same URI as above, click ‘Parameter Body’ and start the PUT request.
Poster now tells you that the request was successful.
Now use either Poster or your browser again to GET the newly set greeting:Â http://localhost:8182/tutorial1/greet.
So do our logs.
PackagingOk, now we have a working application. Time to tell the world. Unfortunately, the world rarely wants to clone our workspace, so we’ll have to think of something else. Eclipse RCP allows us define and export Eclipse based products, and this is what we’ll do.
Select our application bundle and choose ‘New->Product Configuration’ from the context menu.
Enter a file name, e.g. ‘greetings.product” and select ‘Use a launch configuration’ and select the configuration created in the previous steps.
In the list of required bundles, we can stick with the defaults that come from the launch configuration. However, I noted Â that if you remove all bundles, add the greeting application bundle and then re-add the required bundles gives a different result. In this case, only the org.eclipse.osgi and org.restlet bundles are loaded. If you know the reason why the required dependency calculation in the launch configuration dialog behaves different as in the product configuration editor, please leave a comment.
To make sure our bundle is started automagically when the OSGi framework is launched, we need to set a start level and enable autostart for our bundle.
Feel free to customize additional aspects of the product like the launcher name, splash screen and icons 16.
Go back to the Overview page and start the product export by clicking “Eclipse Product export wizard” 17 Choose an output directory and finish the wizard.
The result is a folder containing our application and a launcher for it. You can now start the greeting application and play around with Poster Â once more.
ConclusionWe have seen that it is possible to build a small standalone REST style server application in very short time with just a few lines of code. The eclipse tooling for creating OSGi based products assisted us along the way.
I found this approach useful for showcases that needed a simple server backend as well as for enhancing existing OSGi based applications using proprietary communication protocols with REST like services for consumption by additional systems.
In the next posts of this series, we’ll build upon today’s results to get a more complete application and grow a flexible architecture from this example. And we’ll improve upon our unit test code coverage (which currently is 0%).
Please let me know whether you liked this tutorial in the comments. Any kind of feedback is appreciated.
- https://addons.mozilla.org/de/firefox/addon/2691 ↩
- http://www.ywebb.com/eclipse-restful-http-client-plugin-http4e/ ↩
- http://code.google.com/p/rest-client/ ↩
- Â http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/helios/M6/eclipse-rcp-helios-M6-win32.zip ↩
- Â http://www.restlet.org/downloads/testing ↩
- http://help.eclipse.org/galileo/nav/4_1 ↩
- Â http://xkcd.com/303/ ↩
- Has it ever struck you as odd how much time nowadays goes into setting up your environment and getting the required libraries (read “configuring the tools that get the required libraries”) and how little actually goes into coding? ↩
- Wait. I thought you said OSGi bundle, not Plug-In? It’s actually the same; some eclipse RCP folks still stick to ‘plug-in’ while plain OSGi people use ‘bundle’. See also http://eclipsesource.com/blogs/2009/04/29/plug-in-bundle-blugin/ ↩
- What? ↩
- Â http://github.com/wwerner/net.wolfgangwerner.tutorial1.restlet ↩
- http://www.imdb.com/title/tt0080455/quotes?qt0320027 ↩
- or an URL template for that matter, but this will be covered in a later post ↩
- Â http://github.com/wwerner/net.wolfgangwerner.tutorial1.restlet ↩
- Or use Ctrl-Alt-P ↩
- http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/guide/tools/editors/product_editor/editor.htm ↩
- Well, duh. ↩