Internally a client will look like
prepare for discovery
|
discover a lookup service
|
prepare a template for lookup search
|
lookup a service
|
call the service
|
The following code is simplified from the real case.
It attempts to find a FileClassifier
service, calling the method
getMIMEType()
on this service.
public class TestUnicastFileClassifier {
public static void main(String argv[]) {
new TestUnicastFileClassifier();
}
public TestUnicastFileClassifier() {
LookupLocator lookup = null;
ServiceRegistrar registrar = null;
FileClassifier classifier = null;
// Prepare for discovery
lookup = new LookupLocator("jini://www.all_about_files.com");
// Discover a lookup service
// This uses the synchronous unicast protocol
registrar = lookup.getRegistrar();
// Prepare a template for lookup search
Class[] classes = new Class[] {FileClassifier.class};
ServiceTemplate template = new ServiceTemplate(null, classes, null);
// Lookup a service
classifier = (FileClassifier) registrar.lookup(template);
// Call the service
MIMEType type;
type = classifier.getMIMEType("file1.txt");
System.out.println("Type is " + type.toString());
}
} // TestUnicastFileClassifier
prepare for discovery
|
discover a lookup service
|
create information about a service
|
export a service
|
renew leasing periodically
|
The following code is simplified from the real case.
It exports an implementation of a file classifier service, as a
FileClassifierImpl
object.
public class FileClassifierServer implements DiscoveryListener {
protected LeaseRenewalManager leaseManager = new LeaseRenewalManager();
public static void main(String argv[]) {
new FileClassifierServer();
// keep server running forever to
// - allow time for locator discovery and
// - keep re-registering the lease
Thread.currentThread().sleep(Lease.FOREVER);
}
public FileClassifierServer() {
LookupDiscovery discover = null;
// Prepare for discovery - empty here
// Discover a lookup service
// This uses the asynchronous multicast protocol,
// which calls back into the discovered() method
discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
discover.addDiscoveryListener(this);
}
public void discovered(DiscoveryEvent evt) {
ServiceRegistrar registrar = evt.getRegistrars()[0];
// At this point we have discovered a lookup service
// Create information about a service
ServiceItem item = new ServiceItem(null,
new FileClassifierImpl(),
null);
// Export a service
ServiceRegistration reg = registrar.register(item, Lease.FOREVER);
// Renew leasing
leaseManager.renewUntil(reg.getLease(), Lease.FOREVER, this);
}
} // FileClassifierServer
reggie
LookupLocator
handles unicast discovery
public class LookupLocator {
public LookupLocator(String url);
public LookupLocator(String host, int port);
String getHost();
int getPort();
ServiceRegistrar getRegistrar() throws ...;
}
LookupDiscovery
specifies the url. Its getRegistrar()
method returns a proxy for the lookup service
import net.jini.core.discovery.LookupLocator;
import net.jini.core.lookup.ServiceRegistrar;
public class UnicastRegister {
static public void main(String argv[]) {
new UnicastRegister();
}
public UnicastRegister() {
LookupLocator lookup = null;
ServiceRegistrar registrar = null;
try {
lookup = new LookupLocator("jini://localhost");
} catch(java.net.MalformedURLException e) {
System.err.println("Lookup failed: " + e.toString());
System.exit(1);
}
try {
registrar = lookup.getRegistrar();
} catch (java.io.IOException e) {
System.err.println("Registrar search failed: " + e.toString());
System.exit(1);
} catch (java.lang.ClassNotFoundException e) {
System.err.println("Registrar search failed: " + e.toString());
System.exit(1);
}
System.out.println("Registrar found");
// the code takes separate routes from here for client or service
}
} // UnicastRegister
LookupDiscovery
public class LookupDiscovery {
public LookupDiscovery(String[] groups);
addDiscoveryListener(LookupDiscoveryListener l);
}
interface LookupDiscoveryListener {
public void discovered(DiscoveryEvent e);
public void discarded(DiscoveryEvent e);
}
public class DiscoveryEvent {
Registrar[] getRegistrars();
}
import net.jini.discovery.LookupDiscovery;
import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.core.lookup.ServiceRegistrar;
public class MulticastRegister implements DiscoveryListener {
static public void main(String argv[]) {
new MulticastRegister();
// stay around long enough to receive replies
try {
Thread.currentThread().sleep(10000L);
} catch(java.lang.InterruptedException e) {
// do nothing
}
}
public MulticastRegister() {
LookupDiscovery discover = null;
try {
discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
} catch(Exception e) {
System.err.println(e.toString());
e.printStackTrace();
System.exit(1);
}
discover.addDiscoveryListener(this);
}
public void discovered(DiscoveryEvent evt) {
ServiceRegistrar[] registrars = evt.getRegistrars();
for (int n = 0; n < registrars.length; n++) {
ServiceRegistrar registrar = registrars[n];
// the code takes separate routes from here for client or service
System.out.println("found a service locator");
}
}
public void discarded(DiscoveryEvent evt) {
}
} // MulticastRegister
ServiceRegistrar
.
This is a proxy for the lookup service
public interface ServiceRegistrar {
public ServiceRegistration register(ServiceItem i,
long leaseDuration);
public Object lookup(ServiceTemplate tmpl);
public ServiceMatches lookup(ServiceTemplate tmpl, int maxMatches);
LookupLocator getLocator();
}
register()
method is used by a service
lookup()
methods are used by a client.
The first returns a single service, the second a set of services
getLocator()
method can say where the lookup service is
Entry
public interface Entry {}
Address
Comment
Name
ServiceInfo
Entry[] entries = new Entry[] {new Comment("best toaster made"),
new Name("Classy Toaster")};
public class MIMEType implements java.io.Serializable {
protected String contentType;
protected String subType;
public MIMEType(String contentTpe, String subType) {...}
public String toString() {...}
}
(It may need to be serialized, to move it from one machine to another)
public interface FileClassifier {
MIMEType getMIMEType(String fileName)
throws java.rmi.RemoteException;
}
(The method may be executing remotely, so can throw a remote exception)
package client;
import common.FileClassifier;
import common.MIMEType;
import net.jini.core.discovery.LookupLocator;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceRegistration;
import java.rmi.RMISecurityManager;
import net.jini.core.lookup.ServiceTemplate;
public class TestUnicastFileClassifier {
public static void main(String argv[]) {
new TestUnicastFileClassifier();
}
public TestUnicastFileClassifier() {
LookupLocator lookup = null;
ServiceRegistrar registrar = null;
FileClassifier classifier = null;
try {
lookup = new LookupLocator("jini://www.all_about_files.com");
} catch(java.net.MalformedURLException e) {
System.err.println("Lookup failed: " + e.toString());
System.exit(1);
}
System.setSecurityManager(new RMISecurityManager());
try {
registrar = lookup.getRegistrar();
} catch (java.io.IOException e) {
System.err.println("Registrar search failed: " + e.toString());
System.exit(1);
} catch (java.lang.ClassNotFoundException e) {
System.err.println("Registrar search failed: " + e.toString());
System.exit(1);
}
Class[] classes = new Class[] {FileClassifier.class};
ServiceTemplate template = new ServiceTemplate(null, classes, null);
try {
classifier = (FileClassifier) registrar.lookup(template);
} catch(java.rmi.RemoteException e) {
e.printStackTrace();
System.exit(1);
}
if (classifier == null) {
System.out.println("Classifier null");
System.exit(2);
}
MIMEType type;
try {
type = classifier.getMIMEType("file1.txt");
System.out.println("Type is " + type.toString());
} catch(java.rmi.RemoteException e) {
System.err.println(e.toString());
}
// System.exit(0);
}
} // TestUnicastFileClassifier
package client;
import common.FileClassifier;
import common.MIMEType;
import java.rmi.RMISecurityManager;
import net.jini.discovery.LookupDiscovery;
import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
public class TestFileClassifier implements DiscoveryListener {
public static void main(String argv[]) {
new TestFileClassifier();
// stay around long enough to receive replies
try {
Thread.currentThread().sleep(100000L);
} catch(java.lang.InterruptedException e) {
// do nothing
}
}
public TestFileClassifier() {
System.setSecurityManager(new RMISecurityManager());
LookupDiscovery discover = null;
try {
discover = new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
} catch(Exception e) {
System.err.println(e.toString());
System.exit(1);
}
discover.addDiscoveryListener(this);
}
public void discovered(DiscoveryEvent evt) {
ServiceRegistrar[] registrars = evt.getRegistrars();
Class [] classes = new Class[] {FileClassifier.class};
FileClassifier classifier = null;
ServiceTemplate template = new ServiceTemplate(null, classes,
null);
for (int n = 0; n < registrars.length; n++) {
System.out.println("Service found");
ServiceRegistrar registrar = registrars[n];
try {
classifier = (FileClassifier) registrar.lookup(template);
} catch(java.rmi.RemoteException e) {
e.printStackTrace();
System.exit(2);
}
if (classifier == null) {
System.out.println("Classifier null");
continue;
}
MIMEType type;
try {
type = classifier.getMIMEType("file1.txt");
System.out.println("Type is " + type.toString());
} catch(java.rmi.RemoteException e) {
System.err.println(e.toString());
}
// System.exit(0);
}
}
public void discarded(DiscoveryEvent evt) {
// empty
}
} // TestFileClassifier
FileClassifier
FileClassifierImpl
FileClassifierImpl
FileClassifier
FileClassifierImpl
FileClassifierimpl_Stub
is exported to the service locator
FileClassifier
(like before - it
doesn't care what the proxy is)
FileClassifierImpl
and a FileClassifierProxy
FileClassifierProxy
FileClassifier
FileClassifierImpl
and a FileClassifierProxy
FileClassifierProxy
and a FileClassifierImpl_Stub