camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andreas Gies <>
Subject Using the Servlet component in a Blueprint container
Date Tue, 16 Apr 2013 10:45:51 GMT
Hello Community, 

I apologize for the long post upon list entry, but I thought this might be

I was working on a use case that involves running Camel inside an OSGi
Container and for configuration I am using Apache Aries 1.0.0.
As i have a HTTP Service already running and need to support HTTP posts, I
figured using the servlet component would make sense.

This having said, trying to use the configuration found here
( doesn't work out of the box.
The main reason seems to be that CamelServlet is a class rather than an
interface, so it can't be registered as an OSGi service
easily. Googling around indicated that using the attribute "ext:classes" on
the blueprint reference should do the trick, but I got
errors from Blueprint not being able to create the service proxy.

I stepped back and tried to understand what *should* happen and came up with
a solution / workaround that I thought was worth sharing.

1. I need to gain access to the CamelServlet by OSGI means.
2. I need to stick a HTTP Registry into that servlet.
3. I need to define an endpoint that wires the Registry and the Servlet

First, I have defined an Interface CamelServletProvider that has merely one

public interface CamelServletProvider {

  public CamelServlet getCamelServlet();

with an associated implementation:

public class CamelServletProviderImpl implements CamelServletProvider {

  private CamelServlet camelServlet = null;

  public void setCamelServlet(CamelServlet camelServlet) {
    this.camelServlet = camelServlet;

  public CamelServlet getCamelServlet() {
    return camelServlet;

The idea for this class is, that it lives alongside the CamelServlet and a
CamelServletProvider is registered as an OSGi Service like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>


  <bean id="camelServlet"
class="org.apache.camel.component.servlet.CamelHttpTransportServlet" />

  <bean id="servletProvider"
    <property name="camelServlet" ref="camelServlet" />

  <service ref="camelServlet" interface="javax.servlet.Servlet" >
      <entry key="alias"                value="/camel/services" />
      <entry key="matchOnUriPrefix"     value="true" />
      <entry key="servlet-name"         value="CamelServlet"/>
      <entry key="osgi.web.contextpath" value="/camel/services" />

  <service ref="servletProvider"
      <entry key="servlet-name"         value="CamelServlet"/>


Now we have a bundle that exposes a Camel Servlet as HTTP transport which I
can use in endpoints to come in another bundle.

To make this work I need a HTTP Registry, that I can stick into Blueprint
and that reacts to CamelServletProviders coming and going.
The DefaultHTTPRegistry in Camel reacts to javax.servlet.Servlet.

I have simply cloned the DefaultHTTPRegistry and made it react to

public class  CamelServletHTTPRegistry implements HttpRegistry {
  private static final transient Logger LOG = LoggerFactory.getLogger(

  private static HttpRegistry singleton;

  private final Set<HttpConsumer> consumers;
  private final Set<CamelServlet> providers;

  public  CamelServletHTTPRegistry() {
    consumers = new HashSet<HttpConsumer>();
    providers = new HashSet<CamelServlet>();

   * Lookup or create a HttpRegistry
  public static synchronized HttpRegistry getSingletonHttpRegistry() {
    if (singleton == null) {
      singleton = new  CamelServletHTTPRegistry();
    return singleton;

  public void register(HttpConsumer consumer) {
    LOG.debug("Registering consumer for path {} providers present: {}",
     consumer.getPath(), providers.size());
    for (CamelServlet provider : providers) {

  public void unregister(HttpConsumer consumer) {
    LOG.debug("Unregistering consumer for path {} ", consumer.getPath());
    for (CamelServlet provider : providers) {

  public void register(CamelServletProvider provider, Map properties) {"Registering provider through OSGi service listener {}",
    try {
      CamelServlet camelServlet = provider.getCamelServlet();
      camelServlet.setServletName((String) properties.get("servlet-name"));
    } catch (ClassCastException cce) {"Provider is not a Camel Servlet");

  public void unregister(CamelServletProvider provider, Map<String, Object>
properties) {"Deregistering provider through OSGi service listener {}",
    try {
      CamelServlet camelServlet = provider.getCamelServlet();
    } catch (ClassCastException cce) {"Provider is not a Camel Servlet");

  public void register(CamelServlet provider) {
    LOG.debug("Registering CamelServlet with name {} consumers present: {}",
     provider.getServletName(), consumers.size());
    for (HttpConsumer consumer : consumers) {

  public void unregister(CamelServlet provider) {

  public void setServlets(List<Servlet> servlets) {
    for (Servlet servlet : servlets) {
      if (servlet instanceof CamelServlet) {
        providers.add((CamelServlet) servlet);

The trick here is in the register / unregister method reacting to the
CamelServletProvider interface.

Now I was able to stick all of that together in a bundle configuration:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>


  <!-- Get an instance of the registry -->
  <bean id="httpRegistry"
class="de.woq.camel.sib.http.CamelServletHTTPRegistry" />

  <!-- Get hold of the Servlet Provider by its interface and servlet name
    <reference-listener ref="httpRegistry" bind-method="register"
unbind-method="unregister" />

  <!-- Create the servlet component -->
  <bean id="servlet"
    <property name="httpRegistry" ref="httpRegistry" />


    <!-- Just convenience to stick file into a directory and have them
posted to a URL. -->
    <!-- /camel/services was the root context of my transport service above
      <camel:from uri="file:///tmp/woq-in" />
      <camel:to uri="http://localhost:8080/camel/services/test" />

    <!-- The actual route -->
      <!-- Three /// are important, otherwise the endpoint will be
registered with path "/" -->
      <camel:from uri="servlet:///test" />
      <camel:to uri="file:///tmp/woq-out" />



If you think this is usefull, I am happy to stick it in the wiki rather than
in the user's list.

Best regards
Andreas Gies

WoQ ­ Way of Quality UG

Geschäftsführer & CTO


Tel DE: +49 151 23470823

Tel UK: +44 755 1381918

Fax: +49 1805 006534 2114

Amtsgericht Landshut: HRB 8352
Ust.-Id.: DE274771254

Diese Email kann vertrauliche und/oder rechtlich geschützte Informationen
enthalten und ist ausschließlich für den/die benannten Adressaten bestimmt.
Sollten Sie nicht der beabsichtigte Empfänger sein oder diese Email
irrtümlich erhalten haben, ist es Ihnen nicht gestattet diese Mail oder
einen Teil davon ohne unsere Erlaubnis zu verbreiten, zu kopieren, unbefugt
weiterzuleiten oder zu behalten. Informieren Sie bitte sofort den Absender
telefonisch oder per Email und löschen Sie diese Email und alle Kopien aus
Ihrem System. Wir haften nicht für die Unversehrtheit von Emails, nachdem
sie unseren Einflussbereich verlassen haben.


This email may contain confidential and/or privileged information and is
intended solely for the attention and use of the named addressee(s). If you
are not the intended recipient, or a person responsible for delivering it to
the intended recipient, you are not authorized to and must not disclose,
copy, distribute, or retain this message or any part of it without our
authority. Please contact the sender by call or reply email immediately and
destroy all copies and the original message. We are not responsible for the
integrity of emails after they have left our sphere of control.

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message