Search code examples
javaosgideclarative-services

Multiple PIDs for one target service with ds annotations


I'm wondering if it is possible to leverage what is explaned at par.104.7.5 (Using Multi-Locations) of the osgi enterprise specs using declarative services annotations. Quoting the specs:

It is also possible that Bundles are interested in multiple PIDs for one target service, for this reason they can register multiple PIDs for one service. [...]

A Bundle interested in the host configuration would register a Managed Service with the following properties:

service.pid = [ "com.acme.host", "com.acme.system" ]

The Bundle would be called back for both the com.acme.host and com.acme.system PID and must therefore discriminate between these two cases. This Managed Service therefore would have a callback like:

volatile URL url;
public void updated( Dictionary d ) {
if ( d.get("service.pid").equals("com.acme.host"))
    this.url = new URL( d.get("host"));
if ( d.get("service.pid").equals("com.acme.system"))
   ...
}

I tried with the following syntax:

@Component(
    immediate = true,
    configurationPid = "[com.mycompany.ws.rest,com.mycompany.endpoints]",
    configurationPolicy = ConfigurationPolicy.REQUIRE
) 
public class TestImpl implements Test {
    // ...
}

but this fails. Of course one can get a reference to config admin and browse the configuration based on desired pids but this seems a little bit inelegant to me since in theory it would be possible to delegate that to ds annotations.

Is it possible? What is the correct syntax?

Thank you!


Solution

  • I don't believe it is possible by using configurationPid and configurationPolicy values. What I do is the following:

    • Define the service factory pid(s) as service property.
    • Implement the ManagedService interface.

    Example:

    @Component(property = {Constants.SERVICE_PID + "=com.acme.host", 
                           Constants.SERVICE_PID + "=com.acme.system"})
    public class TestComponent implements ManagedService {
    
        @Override
        public void updated(Dictionary<String, ?> dict) {
        ...
        }
    

    Of course this has the disadvantage that your component is activated even if there is no configuration for it, but you can use two PIDs.