com.bigdata.service.jini
Class AbstractServer

java.lang.Object
  extended by com.bigdata.service.jini.AbstractServer
All Implemented Interfaces:
Runnable, EventListener, net.jini.lease.LeaseListener, net.jini.lookup.ServiceIDListener
Direct Known Subclasses:
ClientServer, DataServer, LoadBalancerServer, MapServer, ReduceServer, ServicesManagerServer, TransactionServer

public abstract class AbstractServer
extends Object
implements Runnable, net.jini.lease.LeaseListener, net.jini.lookup.ServiceIDListener

Abstract base class for configurable services discoverable using JINI. The recommended way to start a server is using the ServiceStarter. However, they may also be started from the command line using main(String[]). You must specify a policy file granting sufficient permissions for the server to start.

 java -Djava.security.policy=policy.all ....
 
You must specify the JVM property -Dcom.sun.jini.jeri.tcp.useNIO=true to enable NIO.

Other command line options MAY be recommended depending on the JVM and the service that you are starting, e.g., -server.

The service may be terminated by terminating the server process. Termination implies that the server stops execution but that it MAY be restarted. A shutdown hook is installed by the server so that you can also stop the server using ^C (Windows) and kill pid (Un*x). You can record the PID of the process running the server when you start it under Un*x using a shell script. Note that if you are starting multiple services at once with the ServiceStarter then these methods (^C or kill pid) will take down all servers running in the same VM.

Services may be destroyed using DestroyAdmin, e.g., through the Jini service browser. Note that all persistent data associated with that service is also destroyed!

Version:
$Id$
Author:
Bryan Thompson
See Also:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6380355, which describes a bug in the service browser that will display a "NullPointerException" dialog box if you destroy a service which implements {@link DestroyAdmin} but not {@link JoinAdmin}., ://java.sun.com/products/jini/2.0/doc/api/com/sun/jini/start/ServiceStarter .html for documentation on how to use the ServiceStarter.
TODO:
delete the lock file, config file, etc. and the service directory if the service is destroyed., document exit status codes and unify their use in this and derived classes., add StatusType and link its values to the running state of the service., add ServiceType with suitable pretty icons.

Nested Class Summary
static interface AbstractServer.ConfigurationOptions
           
protected  class AbstractServer.MasterElectionTask
          Task runs forever competing to become the master.
 
Field Summary
protected  net.jini.config.Configuration config
          The Configuration read based on the args[] provided when the server is started.
protected  Remote impl
          The service implementation object.
protected static org.apache.log4j.Logger log
           
protected  String logicalServiceZPath
          The zpath (zookeeper path) to the znode for the logical service of which this service is an instance.
protected  String physicalServiceZPath
          The path to the ephemeral znode (zookeeper node) for this service instance.
protected  Remote proxy
          The exported proxy for the service implementation object.
 
Constructor Summary
protected AbstractServer(String[] args, com.sun.jini.start.LifeCycle lifeCycle)
          Server startup reads Configuration data from the file or URL named by args and applies any optional overrides, starts the service, and advertises the service for discovery.
 
Method Summary
 void destroy()
          Contract is to shutdown the services and destroy its persistent state.
protected  void fatal(String msg, Throwable t)
          This method handles fatal exceptions for the server.
 JiniClient getClient()
          The object used to connect to and access the other services in the IBigdataFederation.
protected  FileFilter getFileFilter()
          Method may be overriden to recognize files in the service directory so they may be automatically deleted by destroy() after the IService.destroy() has been invoked to destroy any files claimed by the service implementation.
protected  String getHostName()
          The name of the host on which the server is running.
protected  net.jini.lookup.JoinManager getJoinManager()
           
 Remote getProxy()
          The exported proxy for the service implementation object.
 net.jini.core.lookup.ServiceID getServiceID()
          Return the assigned ServiceID.
 String getServiceName()
          The configured name for the service a generated service name if no Name was found in the Configuration.
protected  boolean isPersistent()
          true iff this is a persistent service (one that you can shutdown and restart).
 boolean isShuttingDown()
          Return true iff the service is shutting down.
protected abstract  Remote newService(Properties properties)
          This method is responsible for creating the remote service implementation object.
 void notify(net.jini.lease.LeaseRenewalEvent event)
          Logs a message.
protected  void notifyServiceUUID(net.jini.core.lookup.ServiceID serviceID)
          Notify the AbstractService that it's service UUID has been set.
static net.jini.core.lookup.ServiceID readServiceId(File file)
          Read and return the ServiceID from an existing local file.
 void run()
          Run the server (this should be invoked from main.
 void runDestroy()
          Runs destroy() and logs start and end events.
 void serviceIDNotify(net.jini.core.lookup.ServiceID serviceID)
          This method is responsible for saving the ServiceID on stable storage when it is invoked.
static void setSecurityManager()
          Conditionally install a suitable security manager if there is none in place.
 void shutdownNow(boolean destroy)
          Shutdown the server, including the service and any jini processing.
protected  void terminate()
          Terminates service management threads.
 String toString()
          Simple representation of state (non-blocking, safe).
protected  boolean unexport(boolean force)
          Unexports the proxy - this is a NOP if the proxy is null.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

log

protected static final org.apache.log4j.Logger log

logicalServiceZPath

protected String logicalServiceZPath
The zpath (zookeeper path) to the znode for the logical service of which this service is an instance. This is read from the Configuration.


physicalServiceZPath

protected String physicalServiceZPath
The path to the ephemeral znode (zookeeper node) for this service instance. This path is assigned when the service creates a CreateMode.EPHEMERAL_SEQUENTIAL child of logicalServiceZPath.


config

protected net.jini.config.Configuration config
The Configuration read based on the args[] provided when the server is started.


impl

protected Remote impl
The service implementation object.


proxy

protected Remote proxy
The exported proxy for the service implementation object.

Constructor Detail

AbstractServer

protected AbstractServer(String[] args,
                         com.sun.jini.start.LifeCycle lifeCycle)
Server startup reads Configuration data from the file or URL named by args and applies any optional overrides, starts the service, and advertises the service for discovery. Aside from the server class to start, the behavior is more or less entirely parameterized by the Configuration.

Parameters:
args - Either the command line arguments or the arguments from the ServiceDescriptor. Either way they identify the jini Configuration (you may specify either a file or URL) and optional overrides for that Configuration.
lifeCycle - The life cycle object. This is used if the server is started by the jini ServiceStarter. Otherwise specify a FakeLifeCycle.
See Also:
NonActivatableServiceDescriptor
Method Detail

getServiceName

public final String getServiceName()
The configured name for the service a generated service name if no Name was found in the Configuration.

Note: Concrete implementations MUST prefer to report this name in the AbstractService.getServiceName() of their service implementation class. E.g., DataServer.AdministrableDataService.getServiceName().


getHostName

protected String getHostName()
The name of the host on which the server is running.


getProxy

public Remote getProxy()
The exported proxy for the service implementation object.


getServiceID

public net.jini.core.lookup.ServiceID getServiceID()
Return the assigned ServiceID. If this is a new service and the ServiceUUID was not specified in the Configuration then the ServiceID will be null until it has been assigned by a ServiceRegistrar.


isPersistent

protected boolean isPersistent()
true iff this is a persistent service (one that you can shutdown and restart).

TODO:
should be false for things like the MapServer and the ReduceServer if we keep those classes.

getJoinManager

protected net.jini.lookup.JoinManager getJoinManager()

getClient

public JiniClient getClient()
The object used to connect to and access the other services in the IBigdataFederation.


setSecurityManager

public static final void setSecurityManager()
Conditionally install a suitable security manager if there is none in place. This is required before the server can download code. The code will be downloaded from the HTTP server identified by the java.rmi.server.codebase property specified for the VM running the service.


fatal

protected void fatal(String msg,
                     Throwable t)
This method handles fatal exceptions for the server.

The default implementation logs the throwable, invokes #shutdownNow() to terminate any processing and release all resources, wraps the throwable as a runtime exception and rethrows the wrapped exception.

This implementation MAY be overridden to invoke System.exit(int) IFF it is known that the server is being invoked from a command line context. However in no case should execution be allowed to return to the caller.


toString

public String toString()
Simple representation of state (non-blocking, safe). Some fields reported in the representation may be null depending on the server state.

Overrides:
toString in class Object

unexport

protected boolean unexport(boolean force)
Unexports the proxy - this is a NOP if the proxy is null.

Parameters:
force - When true, the object is unexported even if there are pending or in progress service requests.
Returns:
true iff the object is (or was) unexported.
See Also:
Exporter.unexport(boolean)

readServiceId

public static net.jini.core.lookup.ServiceID readServiceId(File file)
                                                    throws IOException
Read and return the ServiceID from an existing local file.

Parameters:
file - The file whose contents are the serialized ServiceID.
Returns:
The ServiceID read from that file.
Throws:
IOException - if the ServiceID could not be read from the file.

serviceIDNotify

public void serviceIDNotify(net.jini.core.lookup.ServiceID serviceID)
This method is responsible for saving the ServiceID on stable storage when it is invoked. It will be invoked iff the ServiceID was not defined and one was therefore assigned.

Specified by:
serviceIDNotify in interface net.jini.lookup.ServiceIDListener
Parameters:
serviceID - The assigned ServiceID.

notifyServiceUUID

protected void notifyServiceUUID(net.jini.core.lookup.ServiceID serviceID)
Notify the AbstractService that it's service UUID has been set.


notify

public void notify(net.jini.lease.LeaseRenewalEvent event)
Logs a message. If the service is no longer registered with any ServiceRegistrars then logs an error message.

Note: a service that is no longer registered with any ServiceRegistrars is no longer discoverable but it remains accessible to clients which already have its proxy. If a new ServiceRegistrar accepts registration by the service then it will become discoverable again as well.

Note: This is only invoked if the automatic lease renewal by the lease manager is denied by the service registrar.

Specified by:
notify in interface net.jini.lease.LeaseListener

shutdownNow

public void shutdownNow(boolean destroy)
Shutdown the server, including the service and any jini processing. It SHOULD always be safe to invoke this method. The implementation SHOULD be synchronized and SHOULD conditionally handle each class of asynchronous processing or resource, terminating or releasing it iff it has not already been terminated or released.

This implementation:

Note: All errors are trapped, logged, and ignored.

Note: Normally, extended shutdown behavior is handled by the service implementation, not the server. However, subclasses MAY extend this method to terminate any additional processing and release any additional resources, taking care to (a) declare the method as synchronized, conditionally halt any asynchonrous processing not already halted, conditionally release any resources not already released, and trap, log, and ignored all errors.

Note: This is run from within the ShutdownThread in response to a request to destroy the service.

Parameters:
destroy - When true the persistent state associated with the service is also destroyed.

isShuttingDown

public boolean isShuttingDown()
Return true iff the service is shutting down.


terminate

protected void terminate()
Terminates service management threads.

Subclasses which start additional service managment threads SHOULD extend this method to terminate those threads. The implementation should be synchronized, should conditionally terminate each thread, and should trap, log, and ignore all errors.


run

public void run()
Run the server (this should be invoked from main.

Specified by:
run in interface Runnable

destroy

public final void destroy()
Contract is to shutdown the services and destroy its persistent state. This implementation calls shutdownNow(boolean) with destroy := true.


getFileFilter

protected FileFilter getFileFilter()
Method may be overriden to recognize files in the service directory so they may be automatically deleted by destroy() after the IService.destroy() has been invoked to destroy any files claimed by the service implementation. The default implementation of this method does not recognize any files.


runDestroy

public void runDestroy()
Runs destroy() and logs start and end events.


newService

protected abstract Remote newService(Properties properties)
This method is responsible for creating the remote service implementation object. This object MUST declare one or more interfaces that extent the Remote interface. The server will use JERI to create a proxy for the remote object and configure and manage the protocol for communications between the client (service proxy) and the remote object (the service implementation).

Note: You have to implement JoinAdmin in order to show up as an administerable service (blue folder) in the jini Service Browser.

Parameters:
properties - The contents of the Properties file whose name was given by the propertyFile value in the Configuration identified to main by its command line arguments.


Copyright © 2006-2009 SYSTAP, LLC. All Rights Reserved.