This page describes the demo that shows the Discovery functionality of Distributed OSGi.
It assumes that you have set up your DOSGi/ZooKeeper based Discovery system as outlined in the DOSGi Discovery page.
This demo consists of a display controller node that writes messages on all the available display instances. Display instances are realized as remote OSGi services, which are registered with the ZooKeeper-based Discovery system. The discovery system informs the controller, which is a consumer of the DisplayServices, of any available remote instances of this service.
@@@ add an image here @@@
As with most of the other demos, the actual implementation consists of 3 bundles.
- A DisplayService interface bundle.
- A DisplayService implementation bundle.
- A DisplayService client bundle, which takes the role of the display controller.
The Display Service interface is as follows:
The Display Controller (service consumer)
Let's start with the controller, which is a consumer to the the DisplayService. It's simply using an OSGi ServiceTracker to consume all DisplayService services. It also uses a Scheduled Executor to periodically send test messages to all registered displays. Here's the Activator:
No remote-services.xml file!
As we are using Discovery here, there is no static remote service metadata required. So no remote-services.xml file. Discovery will dynamically inform the DOSGi implementation of the locations of available remote services. The DOSGi implemenation will in turn register proxies for the remote services in the local service registry. As a service consumer you simply depend on the service - e.g. by using a ServiceTracker as above, or through a component framework such as Blueprint or DS.
Running the controller
After a brief moment, you will see messages appearing on the controller side. These are the messages sent to all registered displays. Since there are none, they won't show up anywhere just yet.
The Remote Displays (service implementation)
Every Display in the system registers a Display Service implementation in the local Service Registry. This happens in the Activator of the service implementation bundle. It adds the properties to make the service available remotely as well:
Note that the port where the service is made available is dynamically set to be any free port in the system. So you can safely run any number of remote Display Services on the same machine. Because we're using Discovery here, a well-known port is not needed. Registering the service as in the previous code snippet will make it available remotely and
publish it to the installed Discovery system.
Once the provider side bundles are started:
You will start seeing the messages appear on the remote display:
You can add more Display Services and they will also receive the messages.
Under the hood in the ZooKeeper server
The Discovery system uses standard OSGi mechanisms to publish the metadata of the services that are exposed remotely in a centralized server, a ZooKeeper server. On the consumer side, the services are looked up in Discovery through standard OSGi mechanisms as well. These mechanisms are independent of ZooKeeper, so they will work with any Distributed OSGi standards-compliant Dicovery implementation.
ZooKeeper comes with a client program (zkCli) that allows you to look in the ZooKeeper virtual filesystem. All of the OSGi-registered services are stored in a virtual directory under the node /osgi/service_registry. The virtual directory name is based on the fully qualified name of the interface that is implemented by the remote service. So in the case of the DisplayService the remote service metadata is stored under /osgi/service_registry/org/apache/cxf/dosgi/samples/discovery/DisplayService:
Every instance of a remote service that implements the org.apache.cxf.dosgi.samples.discovery.DisplayService interface will get a virtual file in this location. The virtual file is only there for the lifetime of the service. If you stop the service, or kill the OSGi container that hosts it, its associated file in this directory will disappear.
You can obtain the information stored in the node, to get an idea of the metadata that's being communicated using the Discovery system:
Introducing Dynamic Discovery into OSGi Distributed Applications - http://blog.akquinet.de/2009/09/23/introducing-dynamic-discovery-into-osgi-distributed-applications/