import com.sun.jini.lease.LeaseRenewalManager; import com.sun.jini.lookup.JoinManager; import com.sun.jini.lookup.ServiceIDListener; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.rmi.activation.Activatable; import java.rmi.activation.ActivationID; import java.rmi.MarshalledObject; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.rmi.server.UnicastRemoteObject; import java.util.HashMap; import java.util.Properties; import java.util.Random; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceID; import net.jini.lookup.entry.Name; import sdsu.logging.FileLogger; import sdsu.logging.Logger; import sdsu.logging.LoggerCreationException; import sdsu.logging.NullLogger; import sdsu.logging.ScreenLogger; import sdsu.logging.SelectiveLogger; public class HelloServer extends Activatable implements HelloInterface, ServiceIDListener { //MarshalledObject hash keys public static final String GROUP_KEY = "reggieGroups"; public static final String DATA_DIR_KEY = "dataStore"; public static final String SERVICE_LABEL_KEY = "name"; private static final String SERVICE_ID_FILE = "serviceID"; // Logging keys and default values private static final String LOG_SETTING_FILE = "log.properties"; private static final String LOG_FILE = "ServerLog"; private static final String LOG_FILE_KEY = "file"; private static final String LOG_TYPE_KEY = "type"; private static final String LOG_TYPE_FILE = "file"; private static final String LOG_TYPE_SCREEN = "screen"; private static final String DEBUG_KEY = "debug"; private static final String DEBUG_ON = "on"; private File storageLocation; private String serviceName; public HelloServer( ActivationID id, MarshalledObject data) throws RemoteException { super(id, 0); try { HashMap initialData = (HashMap) data.get(); String[] groups = (String[]) initialData.get( GROUP_KEY ); String dataLocation = (String )initialData.get( DATA_DIR_KEY ); serviceName = (String )initialData.get( SERVICE_LABEL_KEY ); storageLocation = new File( dataLocation ); storageLocation.mkdirs(); initializeLogging(); Logger.log( "HelloServer Started" ); joinReggie( groups); } catch (Exception startupError) { Logger.error( "Start up error" ); Logger.error( startupError ); } } public void serviceIDNotify (ServiceID uniqueID) { Logger.log( "Obtained serviceID " + uniqueID ); saveServiceID( uniqueID ); } public String sayHello () throws RemoteException { try { Logger.log( "Connection from " + getClientHost() ); } catch (java.rmi.server.ServerNotActiveException error) { Logger.log( "Connection, client data not available" ); } return ("Hello World from Jini Hello server!"); } /** * Delay execution for random time between 0 and maxDelay * milliseconds */ private void randomPause(int maxDelay) { try { Random delayGenerator = new Random(); long delay = delayGenerator.nextInt( maxDelay ); Logger.debug( "Pause for " + delay + " milliseconds" ); Thread.sleep( delay ); } catch (InterruptedException interuptedError ) {//just proceed, as this is just a pause method } } private void joinReggie( String[] groups ) throws IOException { Logger.debug( "Join" ); ServiceID helloID = getServiceID(); Entry[] labels = getServiceLabels(); // Avoid all Jini services registering at same time when // machine is brought up - use random delay randomPause( 1000 * 15 ); if (helloID == null ) { Logger.debug( "Join, no ID" ); new JoinManager (this, labels, groups, null, this, new LeaseRenewalManager () ); } else { Logger.debug( "Join with ID" ); new JoinManager ( helloID, this,labels, groups, null, new LeaseRenewalManager () ); } } private Entry[] getServiceLabels() { Entry[] labels = new Entry[1]; labels[0] = new Name(serviceName); return labels; } /** * Initailize the logger, which is from the SDSU Java Lib. Log settings * are stored statically in the logger. So once the settings are established * the are in effect for the current JVM */ private void initializeLogging( ) { Properties logSettings = getLogProperties( ); String logType = logSettings.getProperty( LOG_TYPE_KEY, LOG_TYPE_FILE ); String debug = logSettings.getProperty( DEBUG_KEY, DEBUG_ON ); String logFileName = logSettings.getProperty( LOG_FILE_KEY, LOG_FILE ); SelectiveLogger serverLogger; try { if ( logType.equals( LOG_TYPE_SCREEN ) ) serverLogger = (SelectiveLogger) ScreenLogger.register( ); else { File logFile = new File( storageLocation, logFileName ); serverLogger = (SelectiveLogger) FileLogger.register( logFile.getPath() ); } if (debug.equals(DEBUG_ON) ) serverLogger.debugOn(); else serverLogger.debugOff(); } catch (LoggerCreationException logFileProblem ) { // Can't create Filelogger so use screenlogger. ScreenLogger.register( ); } } /** * Read log properties file, which contains settings for logging. * File format:
	 *  type=file | screen
	 *  debug=on | off
	 *  file=fileName
	 * 
* All keys are optional */ private Properties getLogProperties() { Properties logSettings = new Properties(); File logSettingFile = new File( storageLocation, LOG_SETTING_FILE); try { if ( logSettingFile.exists() ) { FileInputStream in = new FileInputStream( logSettingFile ); BufferedInputStream buffered = new BufferedInputStream( in); logSettings.load( buffered ); } return logSettings; } catch (Exception readLoadError) { return new Properties(); } } /** * Recover ServiceID from file. Return null if ServiceID does not exist * or can not be recovered */ private ServiceID getServiceID() { File serviceIDFile = new File( storageLocation, SERVICE_ID_FILE ); if ( !serviceIDFile.exists() ) return null; try { FileInputStream in = new FileInputStream( serviceIDFile ); BufferedInputStream buffered = new BufferedInputStream( in); DataInputStream cin = new DataInputStream( buffered); ServiceID id = new ServiceID( cin ); cin.close(); return id; } catch (IOException readProblem) { Logger.error( "Error in reading service id file" ); Logger.error( readProblem ); return null; } } /** * Save the service id in a file. If save does not succeed, no file * will be created. */ private void saveServiceID( ServiceID uniqueID ) { File serviceIDFile = new File( storageLocation, SERVICE_ID_FILE ); try { FileOutputStream out = new FileOutputStream( serviceIDFile ); BufferedOutputStream buffered = new BufferedOutputStream( out); DataOutputStream cout = new DataOutputStream( buffered); uniqueID.writeBytes( cout ); cout.close(); } catch (IOException writeProblem) { Logger.error( "Error in writing service id file" ); Logger.error( writeProblem ); serviceIDFile.delete(); } } }