You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@aries.apache.org by Tom Mercelis <to...@gmail.com> on 2012/09/10 12:02:43 UTC

Re: How to unregister an OSGI/Blueprint Service from within the Service?

2012/8/16 Tom Mercelis <to...@gmail.com>
>
> Hello,
>
> In my application I have a Service ChatProtocolClient. The implementation is a tcp client which connects to a remote server in the blueprint "init-method" and disconnects in the "destroy-method".
>
> I also have another bundle that uses this ChatProtocolClient's connection to read and post messages from a channel, ChatChannel. Currently I have an xml file that creates a bean of the ChatProtocolClient, and creates a bean ChatChannel in which a reference to the created ChatProtocolClient service is injected.
>
> But how can I handle disconnects from the server? I'd want to tell the Blueprint framework that my ChatProtocolClient instance is unusable now and it should unregister this instance.
>
> Preferably Blueprint would then automatically call the destroy-method on all dependent beans (beans in which Blueprint injected this service reference) and initialize a new ChatProtocolClient bean and all beans that were destroyed because the dependency was replaced.
>
> How can this be achieved?
>
> Kind regards,
>
> Tom Mercelis


Hello,

It's a bit weird to answer my own question, but this is what I came up
with so far:
(I posted this on StackOverflow
http://stackoverflow.com/questions/11984218/how-to-unregister-an-osgi-blueprint-service-from-within-the-service/12349096#12349096)

I found a way to implement this. In this solutions it's not Blueprint
that recreates instances of all dependent services. It goes like this:

Connection "Watchdog" beans.

Instead of creating "ChatProtocolClient" Beans, I created
ConnectionWatchDog beans from xml. In these beans the BundleContext is
injected and the connection properties are set from the .xml file. The
ConnectionWatchDog then tries to create/connect a ChatProtocolClient
instance. If connection succeeds, it registers a service in the
BundleContext (with bundleContext.registerService(..)). The
ServiceRegistration is kept in the watchdog. The watchdog tests the
connection on set interval (it runs it's own Thread). If the
connection appears to have failed; the watchdog calls the
serviceRegistration.unregister() and cleans up the remainders of the
client connection instance, ands starts the whole proces of creating,
connecting and registering an new ChatProtocolClient instance.

The ChatChannel

The ChatChannel is now configured in Blueprint with a . The xml looks like this:

<blueprint xmlns=...>
    <reference-list id="chat-connection" member-type="service-object"
interface="com.example.ChatProtocolClientInterface">
      <reference-listener bind-method="onBind"
unbind-method="onUnbind" ref="Channel1"/>
    </reference-list>
    <bean id="Channel1" class="ChatChannel" init-method="startUp">
       <property name="chatProtocolClient" ref="chat-connection">
       ... some other properties ...
    </bean>
</blueprint>

The member-type set to service-object, means that when a service is
registered or unregistered, the ChatChannel will be informed with the
"onBind" and "onUnbind" methods. As parameter, they'll get a
ChatProtocolClientInterface instance.

I'm not sure whether this is the only or best solution, but it works
for me. Note that with this example xml, you'll also need a setter for
"chatProtocolClient"; currently I don't use the list that is set by
blueprint and I only use the onBind and onUnbind methods.

Maybe there are other suggestions?

Kind regards,

Tom Mercelis