Monday, December 8, 2014

Camel: how to expose static resources in http with jetty component

Introduction


For easier developpement of the application, avoid the use of an apache http server configuration in developpement environment. Sometimes it can be interesting to embbed static resources such as html, javascript and css in the application.

An example of use case:

I expose some REST services consumed by an angularjs application. In development I like to have only my application running and I like to avoid a proxy configuration on apache.

My static files are under /static in my project and my rest services exposed on 8080.

My camel context looks like:


 
<restconfiguration bindingmode="off" component="jetty" host="localhost" port="8080"> 


</restconfiguration> 


<rest> <post consumes="application/json" produces="application/json" uri="/rest/search"> 


<to uri="direct:searchMediator"> </to>


</post> </rest>



Here I use the camel 2.14 include the rest dsl.
First I declared the jetty component to serve rest service.

For now only my rest service is declared no static resources are handled.
So if I try to do http://localhost:8080/static, so I get a 404. It's normal, because jetty only exposes the rest service.

How to deal with that ?


After some search about jetty and the camel component it is possible to define some request handlers in camel.
And we are lucky but jetty provide a ResourceHandler that handle the resources.

The solution:

 


<bean id="staticHandler" class="org.eclipse.jetty.server.handler.ResourceHandler">


<property name="resourceBase" value="static" /> 


</bean>

Here I instanciate a ResourceHandler which is a jetty class with spring camel dsl in specifying the resource base path. In my case /static.

After I declare to camel-jetty component that I will use this handler:

   
<route>


<from uri="jetty:http://localhost:8080?handlers=#staticHandler" /> 


<to uri="mock:empty" /> 


</route>

I just create a route that does nothing except declare the jetty component with handlers. Note the uri ending by ?handlers=#staticHandler . It's possible to add several handlers separated by a quote.

Now try it !


If I try  http://localhost:8080/static, so I can see my index.html file.

Maybe you will consider, Why does it work ? Because we declare two times the jetty component on 8080 ?

The trick is that camel instances only one time each jetty component for a specified host/port, so it means the jetty component between the route and the rest configuration, is exactly the same.

So enjoy your static resources in your camel projet !




2 comments:

  1. Instead of the mock you should likely use a log and set the logging level to DEBUG or something. As the mock endpoint keeps a copy of the exchange in memory, and thus it would "eat up memory". You can also set retainFirst=1 on the mock endpoint to only keep the very first in memory, and discard all others.

    But a nice trick. Btw there was another person in the community that was working on a jetty component that can service static content. But I think its worth revisiting what we can do the camel-jetty to make this easier out of the box.

    ReplyDelete
  2. Hi Claus,

    Thank you for the advice, I didn't consider this point.

    I think this trick should be use mainly in development environment to deploy static quickly. For production environment, I recommend to use a http server such as apache and nginx.

    About the jetty component, you are right, I think it could be interesting to add a component parameter permits to specify a static content base path. This need will be more and more required because of the new javascript framework such as angular, Ember etc.

    ReplyDelete