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(); } } }