300 likes | 494 Views
Jini Tutorial, Part 3. Jini Programming. Tutorial outline. Part 1 Introduction Distributed systems Java basics Remote Method Invocation (RMI) Part 2 Overview of Jini Goals Architecture Basic concepts, protocols Part 3 Jini Programming Part 4 Advanced topics Mobile Jini access
E N D
Jini Tutorial, Part 3 Jini Programming
Tutorial outline • Part 1 Introduction • Distributed systems • Java basics • Remote Method Invocation (RMI) • Part 2 Overview of Jini • Goals • Architecture • Basic concepts, protocols • Part 3 • Jini Programming • Part 4 Advanced topics • Mobile Jini access • Adaptive user interfaces • Security
Contents • Software overview – architecture, packages • Programming the basic steps • discovery, • join (service registration) and • lookup (finding services) • Deployment – where to put what
The key steps of operation • Every service and client will have to discover one or more lookup services • Every service will have to register with (join) the discovered lookup service(s) • Every client will have to search for (look up) services in the lookup service(s) • First we look at the programming of these fundamental steps of operation
Jini package structure • The naming of Jini packages follow the inverted domain name naming convention • jini.net.xxx • The core classes are in packages • jini.net.core.*, stored in jini-core.jar • Classes building on core classes are in • jini.net.*, stored in file jini-ext.jar • Non-standard utility, helper classes are in • com.sun.jini.*, stored in file sun-util.jar
The programmer’s view of Jini • The essential steps of creating a system of Jini services and clients • Create well-known interfaces (if required) • Create services that implement the interfaces • Provide discovery in services and clients • Services: Program service registration • Clients: Program service lookup
How we should proceed • Simple service example to show these steps • Defining service interface • Creating the service • Programming the Unicast Discovery • Service registration • Service lookup • Multicast discovery • The interesting parts
Creating the interface • First we define the well-known interface for our sample service public interface GreetingInterface { public void hello(); }
Creating the Service Proxy • Then we create the proxy class the client will see public class GreetingServiceProxy implements Serializable, GreetingInterface { public GreetingServiceProxy (){ }; public void hello(){ System.out.println(“Welcome to Jini World!”); } }
What we want to achieve Lookup Service Service A register( ) registrar Service Proxy registration
Unicast discovery LookupLocator lookup = null; ServiceRegistrar registrar = null; lookup = new LookupLocator(“jini://hostname”); registrar = lookup.getRegistrar();
Service registration • Once we have a proxy to the lookup service, we can register the service ServiceRegistration registration = null; //create serviceItem (no ID, no attributes) try{ // register for 100 seconds registration = registrar.register(serviceItem, 100000L); } catch (java.rmi.RemoteException e){ } ServiceItem serviceItem = new ServiceItem(null, new GreetingServiceProxy(), null);
Putting the service together import net.jini.core.discovery.*; import net.jini.core.lookup.*; public class GreetingService { static public void main(String argv[]) { LookupLocator lookup = null; //object for discovery ServiceRegistrar registrar = null; //lookup serv. proxy try { lookup = new LookupLocator("jini://hostname"); } catch(java.net.MalformedURLException e) {...} // perform unicast discovery try { registrar = lookup.getRegistrar(100000); }catch ... }
Putting the service together ... ServiceRegistration registration = null; //create serviceItem (no ID, no attributes) ServiceItem serviceItem = new ServiceItem(null, new GreetingServiceProxy(), null); try{ // register for 100 seconds registration = registrar.register(serviceItem, 100000L); }catch (java.rmi.RemoteException e){ } } // GreetingService
The client side Lookup Service Client 1 Unicast discovery Interface Template Template registrar lookup( ) Found proxy
Programming the service lookup System.setSecurityManager( new RMISecurityManager() ); // create template for service search ... GreetingServiceInterface returnedService = null; try{ returnedService = (GreetingServiceInterface) registrar.lookup(template); }catch (java.rmi.RemoteException e){ ... } returnedService.hello(); }
Creating the template Class[] serviceTypes = new Class[1]; try { serviceTypes[0] = Class.forName( "GreetingServiceInterface"); }catch (ClassNotFoundException e){ ... } ServiceTemplate template = new ServiceTemplate(null, serviceTypes, null);
Using Attibutes • Why use attributes • The type (interface) of a service will only say ‘what’ we can do with a service. • We also need information on the properties of the service (eg type and speed of a printer, supercomputer specialising in climate modelling, storage capacity, location of service) • You can use standard Jini attributes • Address, Comment, Location, Name, ServiceInfo, ServiceType, Status • And/or create your own particular ones
Attributes Entry[] attribSet = new Entry[3]; attribSet[0] = new Location(“G", “002", “South Building"); attribSet[1] = new Location(“1st", “107", "North Building"); attribSet[2] = new Name(“Greeting Service for Euro-Par participants"); ServiceTemplate newTemplate = new ServiceTemplate(null, serviceTypes, attribSet); • Since attributes are Java objects and downloaded with the service, they can be used for transferring any type of static or dynamic information from the service to the client
Is that all? What’s missing? • We know how to discover a lookup service, register and lookup services • BUT, we can only discover a known lookup service, which is not discovery at all, only connecting to it • Multicast discovery to deal with unknown lookup services
LookupDiscovery discover = null; try{ discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS); }catch ... This implements the process shown in the next figure. Programming the multicast discovery – Step 1 multicast request Lookup Service N Lookup Service … Discovering entity Lookup Service 2 Lookup Service 1
Asynchronous responses are handled by a listener object (implementing the DiscoveryListener interface) discover.addDiscoveryListener(listener); try{ Thread.currentThread().sleep(10000L); } catch ... } Programming the multicast discovery – Step 2
Handling responses in the listener • Two methods for joining and leaving public void discovered(DiscoveryEvent e){ //Lookup service discovered } public void discarded(DiscoveryEvent e){ //Clean up after lookup service discarded"); }
Step 3 -- Handling registration • Multicast version of the registration process • Note the use of event and the number of lookup services public void discovered(DiscoveryEvent event){ ServiceRegistrar[] registrars = event.getRegistrars(); ServiceRegistration[] registration = null; ServiceItem serviceItem = new ServiceItem(null, new GreetingServiceProxy(), null); for (int i = 0; i < registrars.length; i++){ try { registration[i] = registrars[i].register(serviceItem, 100000L); } catch ... } } }
Creating a ‘real’ service proxy • Creating a new proxy that talks to the backend service public class GreetingServiceProxy implements Serializable, GreetingInterface { protected GreetingBackEnd be; public GreetingServiceProxy ( be ){ this.be = be; }; public void hello(){ String str = be.getString(); System.out.println(str); } }
Modifying the service • The interface for the remote proxy public interface GreetingBackEnd extends Remote{ public String getString(); } • We also need to create the Backend Remote object that will receive RMI calls from the proxy public class BackEnd extends UnicastRemoteObject implements GreetingBackEnd{ public String getString(){ return “Welcome to Euro-Par”; } }
Modifying registration • The service will publish a proxy initialised with a reference to the back end service (the remote object) BackEnd be = new BackEnd(); GreetingServiceProxy proxy = new GreetingServiceProxy(be); ... ServiceItem serviceItem = new ServiceItem(null, proxy, null);
Where are we now? • We have seen the programming of the discovery, join, lookup protocols • Shortcomings: • We have no leasing for our service • Only up and running services will be located – latecomers (both lookup and other services) are missed. We need notification (events) when this happen
Deployment Lookup service computer HTTP Server for exporting LS classes Service computer RMI Daemon RMI Daemon Client device Lookup Service HTTP Server for exporting client classes HTTP Server for exporting service classes Client Service
Summary • Overviewed the programming steps of the Discovery, Join and Lookup protocols • Have used a simple and real proxy to a Jini service • Looked at the use of attributes • Overviewed deployment issues • We look at the more advanced issues in the next part