Using Lookup Services - PowerPoint PPT Presentation

About This Presentation
Title:

Using Lookup Services

Description:

{ protected Hashtable registrars = new Hashtable(); protected Hashtable services = new Hashtable ... registrars.put(reg.getServiceID(), reg); findServices(reg) ... – PowerPoint PPT presentation

Number of Views:24
Avg rating:3.0/5.0
Slides: 43
Provided by: oren2
Category:

less

Transcript and Presenter's Notes

Title: Using Lookup Services


1
Using Lookup Services
  • What are Lookup Services
  • How Clients use lookup services
  • How Services use lookup services
  • Using events

2
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

3
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?

4
Why does the LUS hold a proxy to itself?
  • It is possible to add attributes to the proxy so
    clients can find them by attributes
  • It provides a uniform and elegant way to access
    resources in the Jini network
  • It gives the ability to create a kind of nested
    LUS by holding the proxies of other LUS in every
    LUS
  • Now lets see how to use the lookup service

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

6
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
    LUSAfter 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 .

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

8
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 dont have orders or instructions how to
    interact with the LUS ( they dont have the
    equivalent to the join protocol)
  • Why is that?
  • Services are longer-lived entities than clients!

9
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.

10
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



11
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

12
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 services list of att contains at least one
attribute that matches every entry in the
template , or if this field is null.
13
// Find and print services that have ServiceInfo
// attributes.  import net.jini.discovery.LookupD
iscovery import net.jini.discovery.DiscoveryEvent
import net.jini.discovery.DiscoveryListener imp
ort 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.RemoteExcepti
on 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
14
class Discoverer implements DiscoveryListener
public void discovered(DiscoveryEvent ev)
ServiceRegistrar newregs
ev.getRegistrars() for (int i0
iltnewregs.length i)
addRegistrar(newregsi)
public void discarded(DiscoveryEvent
ev) ServiceRegistrar newregs
ev.getRegistrars() for (int i0
iltnewregs.length i)
removeRegistrar(newregsi)
public ServiceInfoSearcher()
throws IOException if (System.getSecurityManage
r() null) System.setSecurityManager(
new RMISecurityManager())
15
// build our template Entry
attrTemplates new Entry1
attrTemplates0 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.getServiceI
D(), reg) findServices(reg)
protected synchronized void removeRegistrar(Servic
eRegistrar reg) if (!registrars.contains
(reg.getServiceID())) return
16
registrars.remove(reg.getServiceID())
void findServices(ServiceRegistrar
reg) try ServiceMatches
matches reg.lookup(tmpl, Integer.MAX_VALUE)
for (int i0
iltmatches.totalMatches i)
if (services.contains(matches.itemsi.serviceID))
continue
addService(matches.itemsi)
catch (RemoteException ex)
System.err.println("Couldn't search for services
"
ex.getMessage())
17
protected void addService(ServiceItem item)
services.put(item.serviceID, item)
System.out.println("New service found "
item.serviceID) printServiceInfo(item)
protected void printServiceInfo(Serv
iceItem item) for (int i0
iltitem.attributeSets.length i)
if (item.attributeSetsi instanceof ServiceInfo)
ServiceInfo info
(ServiceInfo) item.attributeSetsi
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)

18
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("E
rror starting service info searcher "
ex.getMessage())
ex.printStackTrace()
19
service
  • The Join protocol
  • Basic wrapper uses JoinManager (code)

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

21
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.

22
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.

23
// 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.He
lloWorldServiceInterface public
MyProxy() public String getMessage()
return "Bonjour, my little turnip..."

24
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()
25
// 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)
26
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)
27
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.")
28
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()
29
protected PersistentData readState()
throws IOException, ClassNotFoundException
ObjectInputStream in new ObjectInputStream(Ne
w 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)
30
public static void main(String args)
boolean firsttime false String
serFileName null File serFile null
if (args.length lt 1 args.length gt 2)
usage() if
(args.length 2) if
(args0.equals("-f"))
firsttime true serFileName
args1 else
usage() else
serFileName args0
serFile new File(serFileName)
31
try ServiceWrapper
wrapper new ServiceWrapper(serFile,
firsttime) new Thread(wrapper).start(
) catch (Exception ex)
ex.printStackTrace()
32
events
  • Soliciting events from LUS
  • Receiving events
  • Using events (code)

33
Soliciting events from lookup service
  • Why would a client be interesting in events?
  • How client ask to be notified on event?
  • What kinds of events can happened ?
  • How lookup service notifies the client ?

34
  • 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 ltlt 1 //
    template doesnt match a given service
  • int TRANSITION_NOMATCH_MATCH 1 ltlt 1 //
    template begins to match the service
  • int TRANSITION_MATCH_MATCH 1 ltlt 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 ?

35
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 .

36
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
37
// 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
38
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
39
ServiceEvent serviceEvent (ServiceEvent) ev
switch (serviceEvent.getTransition())
case ServiceRegistrar.TRANSITION_NOMATC
H_MATCH addService(serviceEvent.g
etServiceItem()) break
case ServiceRegistrar.TRANSITION_MATCH_NOMATCH
removeService(serviceEvent.getSer
viceItem()) break
case ServiceRegistrar.TRANSITION_MATCH_MATCH
serviceChanged(serviceEvent.getService
Item()) break
public ServiceInfoWatcher()
throws IOException, RemoteException
mgr new LeaseRenewalManager() listener
new Listener()
40
protected void removeService(ServiceItem item)
services.remove(item.serviceID)
System.out.println("Service no longer available
" item.serviceID) printServiceInfo(item
) protected void serviceChanged(Service
Item 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)
41
// 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(Servi
ceRegistrar 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())
42
// 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("E
rror starting watcher "
ex.getMessage())
Write a Comment
User Comments (0)
About PowerShow.com