Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blueprint: how do I check if an optional dependency is satisfied?

In blueprint.xml, I declare an optional dependency this way:

<reference id="RepositoryListener"
    interface="ru.focusmedia.odp.server.datastore.api.RepositoryListener"
    availability="optional" />

<bean id="Repository"
    class="ru.focusmedia.odp.server.datastore.jpa.repository.RepositoryImpl">
    <jpa:context property="entityManager" unitname="ODP_Server" />
    <tx:transaction method="*" value="Required" />
    <property name="repositoryListener" ref="RepositoryListener" />
</bean>

and in RepositoryImpl, I have

public void setRepositoryListener(RepositoryListener repositoryListener) {
    logger.info("Repository listener set");
    this.repositoryListener = repositoryListener;
}

This method is called by Blueprint even when there is no RepositoryListener service available, as expected. The problem is, how can I check later whether there is a service?

    if (repositoryListener != null) {
        repositoryListener.notifyDelete(node);
    } else {
        logger.warn("No repository listener set!");
    }

doesn't work, since repositoryListener isn't null, but a Blueprint proxy.

like image 718
Alexey Romanov Avatar asked May 29 '12 06:05

Alexey Romanov


1 Answers

There are three options.

  • Normally, if try and use the (missing) optional service, you'll get a five minute delay while blueprint waits for a backing service to appear, followed by a ServiceUnavailableException. So one option is to set a very short blueprint timeout, and catch the ServiceUnavailableException.
  • An arguably cleaner option is to use a reference listener to monitor the lifecycle of the service. This has the disadvantage of needing extra code.
  • The simplest - and therefore laziest - option of all is to use an optional reference list instead of an optional reference. If no satisfying services are present, the list will be empty. Of course, you'll have to think about what you want to happen if multiple satisfying services are present.

To set a shorter timeout, just add an attribute to your optional service reference:

<reference
    id="someReference"
    interface="org.some.service.ServiceInterface"
    availability="optional"
    timeout="100" />

To use a reference listener, you'd add something like the following to your blueprint xml (there's a more detailed example and discussion in chapter 6 of Enterprise OSGi in Action):

<reference
        id="someReference"
        interface="org.some.service.ServiceInterface">
        <reference-listener
            ref="someBean"
            bind-method="bind"
            unbind-method="unbind" />
    </reference>

The bind and unbind methods are called as your service appears and disappears (or as services get added and removed to your reference list, if you're using a reference list).

Using a reference list doesn't really need a code example - just use a <reference-list element and ensure your setter method takes a List.

like image 136
Holly Cummins Avatar answered Nov 11 '22 21:11

Holly Cummins