You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

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 DOSGi Discovery.
@@@ this is work in progress @@@

Demo design

This demo contains 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 DisplayService, 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 like this:

public interface DisplayService {
    boolean displayText(String text);
    String getID();
}

The Display Service Controller

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 uses a Scheduled Executor to periodically send test messages to all registered displays.

public class Activator implements BundleActivator {
    private ServiceTracker tracker;
    private Map<DisplayService, String> displays = new ConcurrentHashMap<DisplayService, String>();

    public void start(BundleContext bc) throws Exception {
        tracker = new ServiceTracker(bc, DisplayService.class.getName(), null) {
            public Object addingService(ServiceReference reference) {
                Object svc = super.addingService(reference);
                if (svc instanceof DisplayService) {
                    DisplayService d = (DisplayService) svc;
                    System.out.println("Adding display: " + d.getID() + " (" + d + ")");
                    displays.put(d, d.getID());
                }
                return svc;
            }

            public void removedService(ServiceReference reference, Object service) {
                String value = displays.remove(service);
                System.out.println("Removed display: " + value);
                super.removedService(reference, service);
            }            
        };        
        tracker.open();
        // ... scheduler stuff that sends messages to all registered displays ommitted
    }

    public void stop(BundleContext bc) throws Exception {
        tracker.close();
    }
}

No remote-services.xml file!

As we are using Discovery here, there is 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. So 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.

The remote Displays

Every Display in the system registers a Display Service implementation in the local Service Registry. This happens in the Activator of the provider side of the demo. It adds the properties to make the service available remotely as well:

public class Activator implements BundleActivator {
    private ServiceRegistration reg;

    public void start(BundleContext bc) throws Exception {        
        Dictionary props = new Hashtable();
        
        String host = getHostName(); // obtain the current host name
        int port = getPort();        // find a free port
        
        props.put("osgi.remote.interfaces", "*");
        props.put("osgi.remote.configuration.type", "pojo");
        props.put("osgi.remote.configuration.pojo.address", "http://" + host + ":" + port + "/display");

        reg = bc.registerService(DisplayService.class.getName(), 
                new DisplayServiceImpl(host + ":" + port), props);
    }

    public void stop(BundleContext bc) throws Exception {
        reg.unregister();
    }
}

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 important. Registering the service as in the previous code snippet will make it available remotely and publish it to the installed Discovery system.

  • No labels