Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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.

Code Block
java
java
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:

Code Block
java
java
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.