183.

previous chapter table of contents next chapter
  

Using the LookupDiscoveryService

An activatable service can make use of a lease renewal service to look after the leases for discovered lookup services. It can find these lookup services by means of a lookup discovery service. The logic that manages these two services is a little tricky.

While lease management can be done by the lease renewal service, the lease renewal set will also be leased and will need to be renewed on occasion. The lease renewal service can call an activatable RenewLease object to do this, as shown in the preceding section of this chapter.

The lookup discovery service is also a leased service ”it will only report changes to lookup services while its own lease is current. Therefore, the lease from this service will have to be managed by the lease renewal service, in addition to the leases for any lookup services discovered.

The primary purpose of the lookup discovery service is to call the notify() method of some object when information about lookup services changes. This object should also be an activatable object. We define a DiscoveryChange object with a notify() method to handle changes in lookup services. If a lookup service has disappeared, we don't worry about it. If a lookup service has been discovered, we want to register the service with it and then manage the resultant lease. This means that the DiscoveryChange object must know both the service to be registered and the lease renewal service. This is static data, so these two objects can be passed in an array of two objects as the MarshalledObject to the activation constructor.

The class itself can be implemented as shown here:

 package activation; import java.rmi.activation.Activatable; import java.rmi.activation.ActivationID; import java.rmi.MarshalledObject; import net.jini.core.event.RemoteEvent; import net.jini.core.event.RemoteEventListener; import net.jini.core.lease.Lease; import net.jini.lease.ExpirationWarningEvent; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceRegistration; import net.jini.lease.LeaseRenewalSet; import net.jini.discovery.RemoteDiscoveryEvent; import java.rmi.RemoteException; import net.jini.discovery.LookupUnmarshalException; import rmi.RemoteFileClassifier; public class DiscoveryChange extends Activatable     implements RemoteEventListener {     protected LeaseRenewalSet leaseRenewalSet;     protected RemoteFileClassifier service;     public DiscoveryChange(ActivationID id, MarshalledObject data)         throws java.rmi.RemoteException {         super(id, 0);         Object[] objs = null;         try {             objs = (Object []) data.get();         } catch(ClassNotFoundException e) {             e.printStackTrace();         } catch(java.io.IOException e) {             e.printStackTrace();         }         service = (RemoteFileClassifier) objs[0];         leaseRenewalSet= (LeaseRenewalSet) objs[1];     }     public void notify(RemoteEvent evt) {         System.out.println("lookups changing... " + evt.toString());         RemoteDiscoveryEvent revt = (RemoteDiscoveryEvent) evt;         if (! revt.isDiscarded()) {             // The event is a discovery event             ServiceItem item = new ServiceItem(null, service, null);             ServiceRegistrar[] registrars = null;             try {                 registrars = revt.getRegistrars();             } catch(LookupUnmarshalException e) {                 e.printStackTrace();                 return;             }             for (int n = 0; n < registrars.length; n++) {                 ServiceRegistrar registrar = registrars[n];                 ServiceRegistration reg = null;                 try {                     reg = registrar.register(item, Lease.FOREVER);                     leaseRenewalSet.renewFor(reg.getLease(), Lease.FOREVER);                 } catch(java.rmi.RemoteException e) {                     System.err.println("Register exception: " + e.toString());                 }             }         }     } } 

The server must install an activation group and then find activation proxies for the service itself and also for the lease renewal object. After this, it can use a ClientLookupManager to find the lease service and register the lease renewal object with it. Now that it has a proxy for the service object, and also a lease renewal service, it can create the marshalled data for the lookup discovery service and register this with rmid . Then we can find the lookup discovery service and register our discovery change listener DiscoveryChange with it. At the same time, we have to register the service with all the lookup services the lookup discovery service finds on initialization.

This all leads to the following server:

 package activation; import rmi.RemoteFileClassifier; import net.jini.discovery.LookupDiscovery; import net.jini.discovery.LookupDiscoveryService; import net.jini.discovery.DiscoveryListener; import net.jini.discovery.DiscoveryEvent; import net.jini.discovery.LookupDiscoveryManager; import net.jini.discovery.LookupDiscoveryRegistration; import net.jini.discovery.LookupUnmarshalException; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceRegistration; import net.jini.core.lookup.ServiceTemplate; import net.jini.core.event.RemoteEvent; import net.jini.core.event.RemoteEventListener; import net.jini.core.lease.Lease; import net.jini.lease.LeaseRenewalService; import net.jini.lease.LeaseRenewalSet; import net.jini.lease.LeaseRenewalManager; import net.jini.lookup.ClientLookupManager; import java.rmi.RMISecurityManager; import java.rmi.activation.ActivationDesc; import java.rmi.activation.ActivationGroupDesc; import java.rmi.activation.ActivationGroupDesc.CommandEnvironment; import java.rmi.activation.Activatable; import java.rmi.activation.ActivationGroup; import java.rmi.activation.ActivationGroupID; import java.rmi.activation.ActivationID; import java.rmi.MarshalledObject; import java.rmi.activation.UnknownGroupException; import java.rmi.activation.ActivationException; import java.rmi.RemoteException; import java.util.Properties; import java.util.Vector; /**  * FileClassifierServerDiscovery.java  */ public class FileClassifierServerDiscovery     /* implements DiscoveryListener */ { private static final long WAITFOR = 10000L; static final protected String SECURITY_POLICY_FILE =     "/home/jan/projects/jini/doc/policy.all"; // Don't forget the trailing '/'! static final protected String CODEBASE = "http://localhost/classes/"; protected RemoteFileClassifier serviceStub; protected RemoteEventListener leaseStub,                               discoveryStub; // Services protected LookupDiscoveryService discoveryService = null; protected LeaseRenewalService leaseService = null; // Lease renewal management protected LeaseRenewalSet leaseRenewalSet = null; // List of leases not yet managed by a LeaseRenewalService protected Vector leases = new Vector(); protected ClientLookupManager clientMgr = null; public static void main(String argv[]) {     new FileClassifierServerDiscovery();     // stick around while lookup services are found     try {         Thread.sleep(20000L);     } catch(InterruptedException e) {         // do nothing     }     // the server doesn't need to exist anymore     System.exit(0); } public FileClassifierServerDiscovery() {     // install suitable security manager     System.setSecurityManager(new RMISecurityManager());     installActivationGroup();     serviceStub = (RemoteFileClassifier)                 registerWithActivation("activation.FileClassifierImpl", null);     leaseStub = (RemoteEventListener)                   registerWithActivation("activation.RenewLease", null);     initClientLookupManager();     findLeaseService();     // the discovery change listener needs to know     // the service and the lease service     Object[] discoveryInfo = {serviceStub, leaseRenewalSet};     MarshalledObject discoveryData = null;     try {         discoveryData = new MarshalledObject(discoveryInfo);     } catch(java.io.IOException e) {         e.printStackTrace();     }     discoveryStub = (RemoteEventListener)                      registerWithActivation("activation.DiscoveryChange",                                             discoveryData);     findDiscoveryService(); } public void installActivationGroup() {     Properties props = new Properties();     props.put("java.security.policy",               SECURITY_POLICY_FILE);     ActivationGroupDesc.CommandEnvironment ace = null;     ActivationGroupDesc group = new ActivationGroupDesc(props, ace);     ActivationGroupID groupID = null;     try {         groupID = ActivationGroup.getSystem().registerGroup(group);     } catch(RemoteException e) {         e.printStackTrace();         System.exit(1);     } catch(ActivationException e) {         e.printStackTrace();         System.exit(1);     }     try {         ActivationGroup.createGroup(groupID, group, 0);     } catch(ActivationException e) {         e.printStackTrace();         System.exit(1);     } } public Object registerWithActivation(String className, MarshalledObject data) {     String codebase = CODEBASE;     ActivationDesc desc = null;     Object stub = null;     try {         desc = new ActivationDesc(className,                                        codebase, data);     } catch(ActivationException e) {         e.printStackTrace();         System.exit(1);     }     try {         stub = Activatable.register(desc);     } catch(UnknownGroupException e) {         e.printStackTrace();         System.exit(1);     } catch(ActivationException e) {         e.printStackTrace();         System.exit(1);     } catch(RemoteException e) {         e.printStackTrace();         System.exit(1);     }     return stub;  } public void initClientLookupManager() {     LookupDiscoveryManager lookupDiscoveryMgr = null;     try {         lookupDiscoveryMgr =             new LookupDiscoveryManager(LookupDiscovery.ALL_GROUPS,                                        null /* unicast locators */,                                        null /* DiscoveryListener */);         clientMgr = new ClientLookupManager(lookupDiscoveryMgr,                                             new LeaseRenewalManager());         } catch(Exception e) {             e.printStackTrace();             System.exit(1);         }     }     public void findLeaseService() {         leaseService = (LeaseRenewalService) findService(LeaseRenewalService.class);         if (leaseService == null) {             System.out.println("Lease service null");         }         try {             leaseRenewalSet = leaseService.createLeaseRenewalSet(20000);             leaseRenewalSet.setExpirationWarningListener(leaseStub, 5000,                                                  null);         } catch(RemoteException e) {             e.printStackTrace();         }     }     public void findDiscoveryService() {         discoveryService = (LookupDiscoveryService)                            findService(LookupDiscoveryService.class);         if (discoveryService == null) {             System.out.println("Discovery service null");         }         LookupDiscoveryRegistration registration = null;         try {             registration =                 discoveryService.register(LookupDiscovery.ALL_GROUPS,                                           null,                                           discoveryStub,                                           null,                                           Lease.FOREVER);         } catch(RemoteException e) {             e.printStackTrace();         }         // manage the lease for the lookup discovery service         try {             leaseRenewalSet.renewFor(registration.getLease(), Lease.FOREVER);         } catch(RemoteException e) {             e.printStackTrace();         }         // register with the lookup services already found         ServiceItem item = new ServiceItem(null, serviceStub, null)         ServiceRegistrar[] registrars = null;         try {             registrars = registration.getRegistrars()         } catch(RemoteException e) {             e.printStackTrace();             return;         } catch(LookupUnmarshalException e) {             e.printStackTrace();             return;         }         for (int n = 0; n < registrars.length; n++) {             ServiceRegistrar registrar = registrars[n];             ServiceRegistration reg = null;             try {                 reg = registrar.register(item, Lease.FOREVER);                 leaseRenewalSet.renewFor(reg.getLease(), Lease.FOREVER);             } catch(java.rmi.RemoteException e) {                 System.err.println("Register exception: " + e.toString());             }         }     }     public Object findService(Class cls) {         Class [] classes = new Class[] {cls};         ServiceTemplate template = new ServiceTemplate(null, classes,                                                        null);         ServiceItem item = null;         try {             item = clientMgr.lookup(template,                                     null, /* no filter */                                     WAITFOR /* timeout */);         } catch(Exception e) {             e.printStackTrace();             System.exit(1);         }         if (item == null) {             // couldn't find a service in time             System.out.println("No service found for " + cls.toString());             return null;         }         return item.service;     } } // FileClassifierServerDiscovery 
  


A Programmer[ap]s Guide to Jini Technology
A Programmer[ap]s Guide to Jini Technology
ISBN: 1893115801
EAN: N/A
Year: 2000
Pages: 189

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net