Using Lookup Services 1.What are Lookup Services 2.How Clients use lookup services 3.How Services use lookup services 4.Using events.

Slides:



Advertisements
Similar presentations
The Jini Technology Lookup Service. How Does It Work Services and clients find a lookup service using the discovery protocol Services advertise themselves.
Advertisements

1 Jini Tutorial, Part 3 Jini Programming. 2 Tutorial outline Part 1 Introduction Distributed systems Java basics Remote Method Invocation (RMI) Part 2.
COS 461 Fall 1997 Network Objects u first good implementation: DEC SRC Network Objects for Modula-3 u recent implementation: Java RMI (Remote Method Invocation)
Jini, third verse Richard Chapman October 13, 1999.
Mini project /2 Jini - a new computing paradigm.
Slides prepared by Rose Williams, Binghamton University ICS201 Exception Handling University of Hail College of Computer Science and Engineering Department.
15-May-15 RMI Remote Method Invocation. 2 “The network is the computer” Consider the following program organization: If the network is the computer, we.
Advanced Programming Rabie A. Ramadan Lecture 4. A Simple Use of Java Remote Method Invocation (RMI) 2.
Remote Method Invocation
Introduction to Jini & JavaSpaces
Remote Method Invocation Chin-Chih Chang. Java Remote Object Invocation In Java, the object is serialized before being passed as a parameter to an RMI.
Java RMI. What is RMI? RMI is an RPC system for an object based language. Objects provide a natural granularity for the binding of functions. –RMI allows.
EEC-681/781 Distributed Computing Systems Lecture 5 Wenbing Zhao Department of Electrical and Computer Engineering Cleveland State University
CS 603 Jini April 10, What is Jini? Java Middleware Tools to construct federation –Multiple devices, each with Java Virtual Machine –Multiple services.
Introduction to Remote Method Invocation (RMI)
Java Remote Object Invocation (RMI) Overview of RMI Java RMI allowed programmer to execute remote function class using the same semantics as local functions.
Parallel Computing using JavaSpaces -Presented by Shilpi Basak Advisor: Prof: Dick Steflik.
Jini Connection Technology Kaushik Lahoti. Jini: A Vision n Areas to focus on –Simplicity –Reliability –Scalability.
Threads II. Review A thread is a single flow of control through a program Java is multithreaded—several threads may be executing “simultaneously” If you.
Io package as Java’s basic I/O system continue’d.
220 FINAL TEST REVIEW SESSION Omar Abdelwahab. INHERITANCE AND POLYMORPHISM Suppose you have a class FunClass with public methods show, tell, and smile.
Java RMI Essentials Based on Mastering RMI Rickard Oberg.
1 Java Programming II Java Network II (Distributed Objects in Java)
Introduction - What is Jini Technology?
Nov 6, 2000CS851 Ubiquitous Computing1 The Jini Architecture Speaker: Weisheng Si Dept. of Computer Science University of Virginia.
January 26, Jim Waldo Copyright 1999 Sun Microsystems, Inc., all rights reserved.
CS 584 Lecture 18 l Assignment » Glenda assignment extended to the Java RMI Deadline » No Java RMI Assignment l Test » Friday, Saturday, Monday.
1 Outline Week 1: Survey on various distributed Systems Week 2: Web Services Using JEE 5 or Glassfish Week 3: Multicast Week 3: RMI Callback, Security.
January 26, Bob Scheifler Copyright 1999 Sun Microsystems, Inc., all rights reserved. Jini™ Lookup Service Bob Scheifler Senior Staff Engineer Sun.
Sun’s Jini Lab 2 Service Registration Client Lookup.
The Java Programming Language
A Look at Jini Jian He Roy Patrick Tan. Outline History Design Goals An Example Basic Components Top View Infrastructures --- Proxies, Discovery/join.
REVIEW On Friday we explored Client-Server Applications with Sockets. Servers must create a ServerSocket object on a specific Port #. They then can wait.
JavaSpaces TM By Stephan Roorda Source: JavaSpaces specification.
Netprog: Java Intro1 Crash Course in Java. Netprog: Java Intro2 Why Java? Network Programming in Java is very different than in C/C++ –much more language.
Lecture 2 Exception handling Advanced Java Programming 1 dr inż. Wojciech Bieniecki
1 Java RMI G53ACC Chris Greenhalgh. 2 Contents l Java RMI overview l A Java RMI example –Overview –Walk-through l Implementation notes –Argument passing.
IBM TSpaces Lab 1 Introduction. Summary TSpaces Overview Basic Definitions Basic primitive operations Reading/writing tuples in tuplespace HelloWorld.
Spring/2002 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads 1 RMI.
RMI remote method invocation. Traditional network programming The client program sends data to the server in some intermediary format and the server has.
RMI Remote Method Invocation Distributed Object-based System and RPC Together 2-Jun-16.
Presentation: RMI Continued 2 Using The Registry & Callbacks.
 Remote Method Invocation  A true distributed computing application interface for Java, written to provide easy access to objects existing on remote.
1 Lecture 16 Jini Technology Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung Institute of Technology
Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to.
JavaSpaces ™ Nati Shalom CTO GigaSpaces Technologies.
IBM TSpaces Lab 3 Transactions Event Registration.
1 JSK 1.1 A practical Approach Contents –Working with JSK 1.1 –Jini environments –Writing Jini software revisited –Important software packages in the JSK.
Liang, Introduction to Java Programming, Sixth Edition, (c) 2005 Pearson Education, Inc. All rights reserved Chapter 27 JavaBeans and.
Java Remote Method Invocation (RMI) Overview of RMI Java RMI allowed programmer to execute remote function class using the same semantics as local functions.
Jini Architecture Introduction System Overview An Example.
ICS3U_FileIO.ppt File Input/Output (I/O)‏ ICS3U_FileIO.ppt File I/O Declare a file object File myFile = new File("billy.txt"); a file object whose name.
Quick Review of OOP Constructs Classes:  Data types for structured data and behavior  fields and methods Objects:  Variables whose data type is a class.
 Java RMI Distributed Systems IT332. Outline  Introduction to RMI  RMI Architecture  RMI Programming and a Sample Example:  Server-Side RMI programming.
Remote Method Invocation A Client Server Approach.
Java RMI. RMI Any object whose methods can be invoked from another Java VM is called a remote object.
January 26, Ken Arnold Copyright 1999 Sun Microsystems, Inc., all rights reserved.
1 Lecture 15 Remote Method Invocation Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung Institute of Technology.
Jini Technology 제 1 회 한국 자바 개발자 컨퍼런스 발표자 : 강신동 Mobile : 소속 : ㈜ idosi.com 대표이사 주최 : JavaCommunity.Org.
Netprog Java RMI1 Remote Method Invocation.
RMI1 Remote Method Invocation Adapted from “Core Java 2” by Cay Horstmann.
RMI Packages Overview java.rmi java.rmi.server java.rmi.registry
Remote Method Invocation
Remote Method Invocation
Java RMI (more) CS-328 Internet Programming.
null, true, and false are also reserved.
Jini Instructors: Geoffrey Fox and Bryan Carpenter
JINI ICS 243F- Distributed Systems Middleware, Spring 2001
Java Remote Method Invocation
Java Chapter 5 (Estifanos Tilahun Mihret--Tech with Estif)
Presentation transcript:

Using Lookup Services 1.What are Lookup Services 2.How Clients use lookup services 3.How Services use lookup services 4.Using events

Lookup services are Jini services Every lookup service supports all the abilities & properties of other Jini services: Every lookup service has a unique ID Every lookup service manages leases Every lookup service publishes proxies & attributes

How Is a Lookup Service Different? The only difference between a lookup service proxy and other service proxies is that: Lookup services proxies can be found by discovery. Every lookup service holds a ref to its own proxy + proxies of other lookup services. Why?

Why does the LUS hold a proxy to itself? 1.It is possible to add attributes to the proxy so clients can find them by attributes 2.It provides a uniform and elegant way to access resources in the Jini network 3.It gives the ability to create a kind of “nested” LUS by holding the proxies of other LUS in every LUS Now let’s see how to use the lookup service

How clients use lookup service? Clients can use a lookup service in a number of ways: 1.They can ask for the service by ID from the LUS or by attributes. 2.They can ask the LUS to notify them every time a new service appears or any changes are made in the services.

How services use lookup service? First of all : every service has a unique ID. This id is given to it the very first time it runs and stays with it forever! Communicating between LUS and a service is via the join protocol which holds all the info that the service needs for communicating with the LUS After the discovery process finds an LUS, the service holds a lease to the LUS that should be renewed as long as the service is active.

client Client life cycle The lookup() functions How are templates matched ? ServiceInfo (code)

How clients use lookup service The client life cycle Clients begin their search for services by using discovery to find LUS, once they found one they interact directly with the ServiceRegistrar interface. Clients don’t have orders or instructions how to interact with the LUS ( they don’t have the equivalent to the “join protocol”) Why is that? Services are longer-lived entities than clients!

Searching for services The ServiceRegistrar interface supports two variants of the method called lookup(). 1.for clients that can completely specify the service they need by using the template mechanism 2.for client that cant specify the service they need, or for applications that need to find all the available services. In both versions of the lookup() the client a template called ServiceTemplate - In the first lookup version the the LUS will return null value to the client if no service matches the template, but if one or more services matches the template the LUS will select one and return its proxy object to the client. - In the second version the client also passes an integer describing the max number of matches it whishes to have, in this case the LUS returns an array of ServiceItems called ServiceMatches. Once the client has this array it can just look for service it needs by iterate over the array.

package net.jini.core.lookup; public class ServiceMatches implements Serializable { public ServiceMatches(ServiceItem[] items, int totalMatches); public ServiceItem items; public int totoalMatches ; } The ServiceItems returned from the lookup() are copies of the ServiceItems published by the services !! package net.jini.core.lookup; public class ServiceItem implements Serializable { public ServiceItem(ServiceID serrviceID, Object service, Entry[] attributeSets); public ServiceID serviceID; public Object service ; public Entry[] attributeSets; }

How are templates matched?? package net.jini.core.lookup; public class ServiceTemplate implements Serializable { public ServiceTemplate(ServiceID serviceID, Class[] serviceTypes, Entry[] attrSetTmpls); public ServiceID serviceID; public Class[] serviceTypes ; public Entry[] attrSetTempls; }

Matches if: *the service ID in the template matches the ID of the registered service or if the ID field is null. And *the registered service is an instance of every type in the serviceTypes or if this field is null. And *the service’s list of att contains at least one attribute that matches every entry in the template, or if this field is null.

// Find and print services that have ServiceInfo // attributes. import net.jini.discovery.LookupDiscovery; import net.jini.discovery.DiscoveryEvent; import net.jini.discovery.DiscoveryListener; import net.jini.core.lookup.ServiceMatches; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceTemplate; import net.jini.core.lookup.ServiceRegistrar; import net.jini.lookup.entry.ServiceInfo; import net.jini.core.entry.Entry; import java.util.Hashtable; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.io.IOException; public class ServiceInfoSearcher implements Runnable { protected Hashtable registrars = new Hashtable(); protected Hashtable services = new Hashtable(); protected ServiceTemplate tmpl;

class Discoverer implements DiscoveryListener { public void discovered(DiscoveryEvent ev) { ServiceRegistrar[] newregs = ev.getRegistrars(); for (int i=0 ; i<newregs.length ; i++) { addRegistrar(newregs[i]); } public void discarded(DiscoveryEvent ev) { ServiceRegistrar[] newregs = ev.getRegistrars(); for (int i=0 ; i<newregs.length ; i++) { removeRegistrar(newregs[i]); } public ServiceInfoSearcher() throws IOException { if (System.getSecurityManager() == null) { System.setSecurityManager( new RMISecurityManager()); }

// build our template Entry[] attrTemplates = new Entry[1]; attrTemplates[0] = new ServiceInfo(null, null, null, null, null, null); tmpl = new ServiceTemplate(null, null, attrTemplates); // set up for discovery LookupDiscovery disco = new LookupDiscovery(LookupDiscovery.ALL_GROUPS); disco.addDiscoveryListener(new Discoverer()); } protected synchronized void addRegistrar(ServiceRegistrar reg) { if (registrars.contains(reg.getServiceID())) return; registrars.put(reg.getServiceID(), reg); findServices(reg); } protected synchronized void removeRegistrar(ServiceRegistrar reg) { if (!registrars.contains(reg.getServiceID())) return;

registrars.remove(reg.getServiceID()); } void findServices(ServiceRegistrar reg) { try { ServiceMatches matches = reg.lookup(tmpl, Integer.MAX_VALUE); for (int i=0 ; i<matches.totalMatches ; i++) { if (services.contains(matches.items[i].serviceID)) continue; addService(matches.items[i]); } } catch (RemoteException ex) { System.err.println("Couldn't search for services: " + ex.getMessage()); } }

protected void addService(ServiceItem item) { services.put(item.serviceID, item); System.out.println("New service found: " + item.serviceID); printServiceInfo(item); } protected void printServiceInfo(ServiceItem item) { for (int i=0 ; i<item.attributeSets.length ; i++) { if (item.attributeSets[i] instanceof ServiceInfo) { ServiceInfo info = (ServiceInfo) item.attributeSets[i]; System.out.println(" Name = " + info.name); System.out.println(" Manufacturer = " + info.manufacturer); System.out.println(" Vendor = " + info.vendor); System.out.println(" Version = " + info.version); System.out.println(" Model = " + info.model); System.out.println(" Serial Number = " + info.serialNumber); }

public void run() { while (true) { try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException ex) { } public static void main(String args[]) { try { ServiceInfoSearcher searcher = new ServiceInfoSearcher(); new Thread(searcher).start(); } catch (Exception ex) { System.err.println("Error starting service info searcher: " + ex.getMessage()); ex.printStackTrace(); }

service The Join protocol Basic wrapper uses JoinManager (code)

The join protocol In order to “find “ a LUS, the service needs to perform the following steps: A.Create a ServiceItem that holds both the proxy & the attributes of the service B.Publish the service by calling register() on any ServiceRegistrars found in the discovery process C.Maintain the lease returned from the LUS

A good Jini citizen, joins… In addition there are some more things that the service should do in order to be considered as a nice Jini network member: The Service should use the same unique ID even across restart and fails. The Service should hold a list of LUS it expects to join, this list must survive across restart and fails When a service starts it should register itself with all the LUS in the list using unicast discovery.

Handling Leases, Attribute and group updates Services renew their leases on registrations, if at any point the communication with the LUS fails, the service acts depending on how the LUS was discovered: If the LUS discovered via multicast discovery the service should simply forget it by calling discard(). If the LUS was discovered by the unicast discovery, meaning that the LUS was on the service list, the service should try to reconnect. If the service changes the set of attributes, or is asked to do so, then it should make the change in all the LUS it registered with. If the service changes the set of groups it is member of, or is asked to do so, then it has to drop itself from all the LUS that are not in the new group, and start the discovery process on the LUS that are members in the new group.

// A basic wrapper that uses JoinManager package corejini.chapter8; import java.io.*; import net.jini.core.lookup.ServiceID; import net.jini.core.discovery.LookupLocator; import net.jini.core.entry.Entry; import com.sun.jini.lookup.JoinManager; import com.sun.jini.lookup.ServiceIDListener; import java.rmi.RMISecurityManager; class MyProxy implements Serializable, corejini.chapter5.HelloWorldServiceInterface { public MyProxy() { } public String getMessage() { return "Bonjour, my little turnip..."; }

public class ServiceWrapper implements Runnable { protected JoinManager join = null; protected File serFile = null; protected Object proxy = new MyProxy(); // note static! static class PersistentData implements Serializable { ServiceID serviceID; Entry[] attrs; String[] groups; LookupLocator[] locators; public PersistentData() { }

// An inner class to catch ID changes class IDListener implements ServiceIDListener { public void serviceIDNotify(ServiceID serviceID) { System.out.println("Got service ID " + serviceID); PersistentData state = new PersistentData(); state.serviceID = serviceID; state.attrs = join.getAttributes(); state.groups = join.getGroups(); state.locators = join.getLocators(); try { writeState(state); } catch (IOException ex) { System.err.println("Couldn't write to file: " + ex.getMessage()); ex.printStackTrace(); join.terminate(); System.exit(1); }}}

public ServiceWrapper(File serFile, boolean firsttime) throws IOException, ClassNotFoundException { this.serFile = serFile; if (System.getSecurityManager() == null) { System.setSecurityManager( new RMISecurityManager()); } if (firsttime) register(); else reregister(); } public void run() { while (true) { try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException ex) { }

protected void register() throws IOException { if (join != null) { throw new IllegalStateException("Wrapper already started."); } System.out.println("Starting..."); join = new JoinManager(proxy, null, new IDListener(), null); } protected void reregister() throws IOException, ClassNotFoundException { if (join != null) { throw new IllegalStateException("Wrapper already started."); }

PersistentData state = readState(); System.out.println("Restarting: old id is " + state.serviceID); join = new JoinManager(state.serviceID, proxy, state.attrs, state.groups, state.locators, null); } protected void writeState(PersistentData state) throws IOException { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(serFile)); out.writeObject(state); out.flush(); out.close(); }

protected PersistentData readState() throws IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(New FileInputStream(serFile)); PersistentData state = (PersistentData) in.readObject(); in.close(); return state; } static void usage() { System.err.println("Usage: ServiceWrapper " + "[-f] serialization_file"); System.exit(1); }

public static void main(String[] args) { boolean firsttime = false; String serFileName = null; File serFile = null; if (args.length 2) { usage(); } if (args.length == 2) { if (args[0].equals("-f")) { firsttime = true; serFileName = args[1]; } else { usage(); } } else { serFileName = args[0]; } serFile = new File(serFileName); }

try { ServiceWrapper wrapper = new ServiceWrapper(serFile, firsttime); new Thread(wrapper).start(); } catch (Exception ex) { ex.printStackTrace(); }

events Soliciting events from LUS Receiving events Using events (code)

Soliciting events from lookup service 1.Why would a client be interesting in events? 2.How client ask to be notified on event? 3.What kinds of events can happened ? 4.How lookup service notifies the client ?

When a client ask for events to be sent to him he provides a special flag that determines how the template is used The flag can have three possible values: 1.a service suddenly matches the provided template. 2.a service is no longer matches. 3.a service is still matching but is changing. Client is asking for events by calling notify() method on the ServiceRegistrar The flags are: int TRANSITION_MATCH_NOMATCH = 1 << 1; // template doesn’t match a given service int TRANSITION_NOMATCH_MATCH = 1 << 1; // template begins to match the service int TRANSITION_MATCH_MATCH = 1 << 2; // a service is changing in some way The notify() method returns an EventRegistration to the client.(a simple container class that contains the source of the event in this case the ServiceRegistrar that generate the event), and lease for the event registration. How the client receive the event ?

Receiving events ! Requesting for event the client provides an object that implements the RemoteEventLisener interface public interface RemoteEventLisener implements java.rmi.Remote, java.util.EventLisener { public void notify(RemoteEvent ev) throws java.rmi.RemoteExeption, UnknownEventExeption; } Whenever a LUS needs to send an event, it will construct one and deliver it by calling the notify(). The LUS delivers a subclass of RemoteEvent that provides extra info about the change.

This subclass is called ServiceEvent. In the ServiceEvent client can find info about the service by using the methods getServiceID(). -- that returns the service id. getServiceItem(). -- returns the complete service item that cause the event. a new item if the service has changed. returns null if the service was deleted. getTransition(). -- returns a flag value indicating what type of transition occurred

// like lookup searcher, only uses events package corejini.chapter8; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceEvent; import net.jini.core.lookup.ServiceItem; import net.jini.core.event.RemoteEvent; import net.jini.core.event.EventRegistration; import net.jini.core.event.RemoteEventListener; import net.jini.core.lease.Lease; import com.sun.jini.lease.LeaseRenewalManager; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.Hashtable; import java.io.IOException;

public class ServiceInfoWatcher extends ServiceInfoSearcher { protected Listener listener; protected LeaseRenewalManager mgr; protected Hashtable leases = new Hashtable(); protected int transitions = ServiceRegistrar.TRANSITION_MATCH_NOMATCH | ServiceRegistrar.TRANSITION_NOMATCH_MATCH | ServiceRegistrar.TRANSITION_MATCH_MATCH; class Listener extends UnicastRemoteObject implements RemoteEventListener { public Listener() throws RemoteException { } public void notify(RemoteEvent ev) throws RemoteException { if (!(ev instanceof ServiceEvent)) { System.err.println("Unexpected event: " + ev.getClass().getName()); return; }

ServiceEvent serviceEvent = (ServiceEvent) ev; switch (serviceEvent.getTransition()) { case ServiceRegistrar.TRANSITION_NOMATCH_MATCH: addService(serviceEvent.getServiceItem()); break; case ServiceRegistrar.TRANSITION_MATCH_NOMATCH: removeService(serviceEvent.getServiceItem()); break; case ServiceRegistrar.TRANSITION_MATCH_MATCH: serviceChanged(serviceEvent.getServiceItem()); break; } public ServiceInfoWatcher() throws IOException, RemoteException { mgr = new LeaseRenewalManager(); listener = new Listener(); }

protected void removeService(ServiceItem item) { services.remove(item.serviceID); System.out.println("Service no longer available: " + item.serviceID); printServiceInfo(item); } protected void serviceChanged(ServiceItem item) { services.put(item.serviceID, item); System.out.println("Service updated: " + item.serviceID); printServiceInfo(item); } // overrride addRegistrar and removeRegistrar to have them // ask for/terminate event solicitations whenever we find a // lookup service. protected void addRegistrar(ServiceRegistrar reg) { try { super.addRegistrar(reg); EventRegistration er = reg.notify(tmpl, transitions,listener, null,10 * 60 * 1000);

// do something with lease leases.put(reg.getServiceID(), er.getLease()); mgr.renewFor(er.getLease(), Long.MAX_VALUE, null); } catch (RemoteException ex) { System.err.println("Can't solicit event: " + ex.getMessage()); } protected void removeRegistrar(ServiceRegistrar reg) { try { super.removeRegistrar(reg); // terminate leases on this dude. Lease lease = (Lease) leases.get(reg.getServiceID()); if (lease == null) return; leases.remove(reg.getServiceID());

// May raise unknown lease exception or // remote exception. Should be ok to ignore // here... mgr.cancel(lease); } catch (Exception ex) { } public static void main(String[] args) { try { ServiceInfoWatcher watcher = new ServiceInfoWatcher(); new Thread(watcher).start(); } catch (Exception ex) { System.err.println("Error starting watcher: " + ex.getMessage()); }