Search code examples
serviceruntimeosgikaraf

OSGi Declarative services filter references at runtime


I've been trying some examples with OSGi Declarative Services (among other things, such as Blueprint) on Karaf. The problem I am trying to solve now, is how to get references to certain services at runtime (so annotations and/or XML are not really an option here)

I will explain my use case:

I am trying to design (so far only in my head, that's why I am still only experimenting with OSGi :) ) a system to control certain automation processes in industry. To communicate with devices, a special set of protocols is being used. To make the components as reusable as possible, I designed a communication model based on layers (such as ISO/OSI model for networking, but much more simple)

To transform this into OSGi, each layer of my system would be composed of a set of bundles. One for interfaces of that layer, and then one plugin for each implementation of that layer (imagine this as TCP vs. UDP on the Transport layer of OSI).

To reference any device in such network, a custom address format will be used (two examples of such addresses can be xpa://12.5/03FE or xpb://12.5/03FE). Such address contains all information about layers and their values needed in order to access the requested device. As you can guess, each part of this address represents one layer of my networking model.

These addresses will be stored in some configuration database (so, again, simple .cfg or .properties files are not an option) so that they can be changed at runtime remotely.

I am thinking about creating a Factory, that will parse this address and, according to all its components, will create a chain of objects (get appropriate services from OSGi) that implement all layers and configure them accordingly.

As there can be more implementations of a single layer (therefore, more services implementing a single interface), this factory will need to decide, at runtime (when it gets the device address passed as string), which particular implementation to choose (according to additional properties the services will declare).

How could this be implemented in OSGi? What approach is better for this, DS, Blueprint or something else?


Solution

  • I realise that this is now a very late answer to this question, but both answers miss the obvious built-in support for filtering in Declarative Services.

    A target filter can be defined for a DS reference using the @Reference annotation:

    @Component
    public class ExampleComponent {
        @Reference(target="(foo=bar)")
        MyService myService;
    }
    

    This target filter can also be added (or overriden) using configuration. For the component:

    @Component(configurationPid="fizz.buzz")
    public class ExampleComponent {
        @Reference
        MyService myService;
    }
    

    A configuration dictionary for the pid fizz.buzz can then set a new filter using the key myService.target.

    This is a much better option than jumping down to the raw OSGi API, and has been available for several specification releases.