Saturday, December 12, 2009

Using OSGi Service Registration & Consumption with Service Properties

When I was looking in to resource which tells about OSGi Service Properties I found very little useful articles. Most of the resource just describe how to write services and consume them and they just mention we can use properties to varies different services. You might not know what OSGi properties yet,first I will show you how to write a typical OSGi service and register it in to the framework, then let's look in to how do we have to deal with Service Properties.

  • Before writing a real service we always have to have an interface of that particular service, then we have to implement our interface.Let's assume the Interface name is Calculator and implementation class name is CalculatorImpl.
  • Then we have to register our service using a class which implements BundleActivator class. Normally when our bundle get resolved start method of that class get called. So normally we have to register our services during the activation of our bundle. So we have to do the registration inside the start method of the Activator class of our bundle.
public class CalculatorAcivator implements BundleActivator{
public void start(BundleContext context){
// Registering the Calculator Service as an OSGi Service
Calculator calc = new CalculatorImpl();
context.registerService(CalculatorService.class.getName(),calc,null);
}
public void stop(){
}
}

  • Then we have to write another class which is in another bundle and get the service reference. In order to do that OSGi API provide number of ways, here I will be showing the very basic way of consuming a known service.

public class CalculatorConsumer implements BundleActivator{
public void start(BundleContext context){
// Registering the Calculator Service as an OSGi Service
ServiceReference ref = context.getServiceReference(Calculator.class.getName);
if(ref != null){
Calculator calc = (Calculator)ref.getService(ref)
// now you have a reference to the Calculator service
}
}
public void stop(){
}
}


Here the registration happens with registerService method of BundleContext object which is the object we always use to talk to the OSGi environment. In here you can see we are registering the service by giving the interface name, object of the service class and a null value. Second argument is the Service object which is going to use by the consumer. Before going in to the last argument I would like to remind you something which I have mentioned in my blog post about of Introduction to OSGi Services. Here I have mentioned that we can register different services which implement the same interface, as an example we can write another class which implements the same Calculator class. So during registration of process we give the same full qualified class name. So you may get confused how do we the exactly the same require object when we get the service because when we get a service we again pass the interface name rather parsing the exactly implementation class name. So that is the place where we have to use Service Properties to get the differentiation of the services which implement the same interface.

As the third argument for the registerService method we have to give a Dictionary type object and normally what we are doing is create a Properties object and put required values to identify our service from the services which implement the same interface.

Properties props = new Properties();
props.put("name","CalculatorImpl");
context.registerService(Calculator.class.getName(),calc,props);

So once you give the Service properties, during the consumption you can check these properties using Service Filters to get the the exactly the required Service object using getService method by passing the filter. As an example if we want to get the service object of the registered service above we have to give the filter string like this.

ServiceReference ref =context.getServiceReference(Calculator.class.getName(),"(name=Calculator)");
Calculator calc =(Calculator) ref.getService(ref);

This will simply return the actual CalculatorImpl object. When you give the filter Strings you have to obay certain rules whey you deal with complex filters and I will be writing more about OSGi Service Filters which will be helpful for you to use OGSi services in effective manner.







No comments :