CptBartender
CptBartender

Reputation: 1220

How to get all services implementing given interface, not just active ones?

I have a business requirement that as part of some processing, we enable a "plugin" functionality for an externally-managed code.

It was decided that the best approach would be to @Reference a list of "ranked" (ordered according to an irrelevant algorithm) services. More or less like this:

public interface ExternalProcessor {
    void doSomething();
}

@Component
@Service(ImportantTaskManager.class)
public class ImportantTaskManager{

    @Reference(cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, referenceInterface = ExternalProcessor.class)
    protected List<ExternalProcessor> processors;

    public void doImportantStuff(){
        for(ExternalProcessor processor: processors){
            processor.doSomething();
        }
    }
}

To keep it short, I've ommitted as much boilerplate as I could, including the bind/unbind method pair.

Now, another business requirement is that we don't perform any kind of processing whatsoever if there are services that implement the ExternalProcessor interface that are not bound to our main processor (for any reason: not resolved dependencies, crashed during activation, missing required configuration etc.). I have a feeling it's kind of against OSGi principle (where OSGi provides only available services as opposed to info about the unavailable ones), but how can I achieve that?

So far I've come up with the following candidates for solutions:

  1. Ask the external team to provide a count of services we're supposed to be expecting, then compare that against what we get from OSGi - it's unreliable

  2. Crawl through all the installed bundles and their meta xmls taken from bundle's headers looking for service definitions - it's... well, it's time-consuming, for a start.

  3. grep through the logs looking for service registrations and/or failures - this one seems just... wrong.

Is any of the above a proper solution to this? Are there better solutions? How else can I tacke this problem? What am I missing here?

Upvotes: 2

Views: 565

Answers (1)

Christian Schneider
Christian Schneider

Reputation: 19626

I had a similar requirement for security plugins. The code calling the plugins should not run when the necessary security plugins were missing.

I solved it by defining a service property like id. Each plugin would have a unique id. In the config of your main code you specify a list of security plugins by id that you need.

The code then checks each service for the ids and only activates the main component when all mandatory plugins are present.

Upvotes: 2

Related Questions