Apache Karaf Cellar and DOSGi

November 29, 2011 Posted by jbonofre

Next version of Apache Karaf Cellar will include a DOSGi (Distributed OSGi) implementation.

There are several existing DOSGi implementations: in Apache CXF (powered by the CXF stack), in Fuse Fabric, etc.

The purpose of the Cellar one is to leverage the Cellar existing (Hazelcast instance, distributed map, etc), and to be very easy to use.

Karaf Cellar DOSGi installation

Cellar DOSGi is part of the main cellar feature. To install it:


karaf@root> features:addurl mvn:org.apache.karaf.cellar/apache-karaf-cellar/3.0.0-SNAPSHOT/xml/features
karaf@root> features:install cellar

Distributed services

You can note a new command available in Cellar:


karaf@root> cluster:list-services

It displays the list of services “cluster aware”. It means a service that could be used remotely from another node.

Code sample

To illustrate the Cellar DOSGi usage, we will use two bundles:

  • the provider bundle is installed on node A and “expose” a distributed service
  • the client bundle is installed on node B and will use the provider service

Provider bundle

The provider bundle expose an OSGi service, flagged as a distributed service.

The service is very simple, it’s just an echo service.

Here’s the interface describing the service:


package org.apache.karaf.cellar.sample;

public interface EchoService {

  String process(String message);

}

and the corresponding implementation:


package org.apache.karaf.cellar.sample;

public class EchoServiceImpl implements EchoService {

&nbps; public String process(String message) {
    return "Processed by distributed service: " + message;
  }

}

Up to now, nothing special, nothing related to DOSGi or Cellar.

To expose the service in Karaf, we create a blueprint descriptor:


<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

  <bean id="echoService" class="org.apache.karaf.cellar.sample.EchoServiceImpl"/>

  <service ref="echoService" interface="org.apache.karaf.cellar.sample.EchoService">
    <service-properties>
      <entry key="service.exported.interfaces" value="*"/>
    </service-properties>
  </service>

</blueprint>

We can note that the only “special” part is that we added the service.exported.interfaces property to the echoService.

It’s just a flag to define the interface/service to define as distributed (it means accessible from remote node).

We didn’t change the code of the service itself, just added this property. It means that it’s really easy to turn an existing service as a distributed service.

Client bundle

The client bundle will get a reference to the echoService. In fact, the reference will be a kind of proxy to the service implementation located remotely, on another node.

The client is really simple, it indefinitely iterates to use the clusterService:


package org.apache.karaf.cellar.sample.client;

public class ServiceClient {

  private EchoService echoService;

  public void setEchoService(EchoService echoService) {
    this.echoService = echoService;
  }

  public EchoService getEchoService() {
    return this.echoService;
  }

  public void process() throws Exception {
    int count = 0;
    while (true) {
      System.out.println(echoService.process("Call " + count));
      Thread.sleep(5000);
      count++;
    }
  }

}

We inject the echoService using Blueprint:


&lt?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

  <reference id="echoService" interface="org.apache.karaf.cellar.sample.EchoService"/>

  <bean id="serviceClient" class="org.apache.karaf.cellar.sample.client.ServiceClient" init-method="process">
&nbps;   <property name="echoService" ref="echoService"/>
  </bean>

</blueprint>

It’s done. The serviceClient will use the echoService. If a “local” echoService exists, the OSGi framework will bind the reference to this service, else Cellar will look for a distributed service (on all node) exporting the EchoService interface and bind a proxy to the distributed service.

About jbonofre

ASF Member, PMC for Apache Karaf, PMC for Apache ServiceMix, PMC for Apache ACE, PMC for Apache Syncope, Committer for Apache ActiveMQ, Committer for Apache Archiva, Committer for Apache Camel, Contributor for Apache Falcon Twitter: jbonofre IRC: jbonofre on #servicemix,#karaf,#camel,#cxf on Freenode

Leave a Reply