I am currently facing a problem of how to dynamically "wire" OSGi Services depending on their configuration properties. I want to do that with Declarative Services.
To give a concrete example: I have two different OSGi Services A and B which both are ManagedServiceFactories and require configuration. So I can have multiple instances of A and multiple instances of B each with separate configurations.
I use Felix FileInstall, DS/SCR and BNDTools and my configs look like this (simplified):
a-one.cfg: b.id = foo
a-two.cfg: b.id = bar
b-one.cfg: id = foo
b-two.cfg: id = bar
Now I want to wire/bind service b-one to a-one and service b-two to a-two (depending on their matching configuration properties b.id = id).
Currently I can see two approaches on how to achieve this:
- Bind all available instances of Service B to the instances of Service A and select the proper Service B depending on its id.
- Implement an own ManagedServiceFactory for Service A which creates an LDAP filter to find the proper instance of Service B.
For solution 1.) I do not like that I need to bind all instances of Service B to every instance of Service A. I like to only bind the instance of Service B which meets my configuration property constraint.
For solution 2.) I do not like that I need to dig to the lower levels: own ManagedServiceFactory and bypassing DS by manually find the proper (LDAP filtered) Service instance.
Do anyone know a better solution or "best practice" how to achieve that? I am not sure if maybe the WireAdmin spec can help me here?
Solution with BNDTools/BND Annotation would be welcomed ;)
DS always puts all configuration information as service properties if it registers a service for a Component. You should do the same in your A and B ManagedServiceFactory so the services will be searchable.
On the other hand, if you specify a property for your reference with the ".target" suffix, you can specify via configuration which service to pick up.
With your example:
- You create a component for B
- You specify a reference in component B for services A with the name a
- You specify a property in component B with the name a.target
- You configure a.target with LDAP search filters. If you do not specify a value for this property, a random A service will be picked up