arlut.csd.ganymede
Class GanymedeServer

java.lang.Object
  |
  +--java.rmi.server.RemoteObject
        |
        +--java.rmi.server.RemoteServer
              |
              +--java.rmi.server.UnicastRemoteObject
                    |
                    +--arlut.csd.ganymede.GanymedeServer
All Implemented Interfaces:
java.rmi.Remote, java.io.Serializable, Server

public class GanymedeServer
extends java.rmi.server.UnicastRemoteObject
implements Server

The GanymedeServer object is created by the Ganymede class at start-up time and published to the net for client logins via RMI. As such, the GanymedeServer object is the first Ganymede code that a client will directly interact with.

See Also:
Serialized Form

Field Summary
(package private) static java.util.Hashtable activeUsers
          A hashtable mapping session names to identity.
private  arlut.csd.ganymede.GanymedeSession loginSession
          During the login process, we need to get exclusive access over an extended time to synchronized methods in a privileged GanymedeSession to do the query operations for login.
(package private) static arlut.csd.ganymede.loginSemaphore lSemaphore
          Our handy, all purpose login semaphore
(package private) static arlut.csd.ganymede.GanymedeServer server
          Singleton server object.
private static java.util.Vector sessions
          Vector of GanymedeSession objects for users that are logged into the Ganymede server remotely.
(package private) static boolean shutdown
          If true, the server is waiting for all users to disconnect so that it can shut itself down.
(package private) static arlut.csd.ganymede.loginSemaphore shutdownSemaphore
          Another handy semaphore, this time used to defer shutdowns from build processes
(package private) static java.util.Hashtable userLogOuts
          A hashtable mapping user Invids to a java.lang.Date object representing the last time that user logged into Ganymede.
 
Fields inherited from class java.rmi.server.UnicastRemoteObject
 
Fields inherited from class java.rmi.server.RemoteServer
 
Fields inherited from class java.rmi.server.RemoteObject
ref
 
Constructor Summary
GanymedeServer()
          GanymedeServer constructor.
 
Method Summary
static void addRemoteUser(arlut.csd.ganymede.GanymedeSession session)
          This method is called to add a remote user's GanymedeSession object to the GanymedeServer's static sessions field, which is used by the admin console code to iterate over connected users when logging user actions to the Ganymede admin console.
 arlut.csd.ganymede.adminSession admin(arlut.csd.ganymede.Admin admin)
          This public remotely accessible method is called by the Ganymede admin console and/or the Ganymede stopServer script to establish a new admin console connection to the server.
 boolean checkEmbeddedObjects()
          This method is used for testing.
static java.lang.String checkEnabled()
          Gated enabled test.
 boolean checkInvids()
          This method is used for testing.
(package private) static void clearActiveUser(java.lang.String username)
          This method is to handle user logout.
 void clearIdleSessions()
          This method is called by the timeOutTask scheduled task, and forces an idle time check on any users logged in.
 void dump()
          This method is used by directLoader code to dump the database to disk at the end of the bulk-loading process.
static arlut.csd.ganymede.loginSemaphore getLoginSemaphore()
          Handy public accessor for the login semaphore, for possible use by plug-in task code.
static java.lang.StringBuffer getTextMessage(java.lang.String key, arlut.csd.ganymede.Invid userToDateCompare, boolean html)
          This method retrieves a message from a specified directory in the Ganymede installation and passes it back as a StringBuffer.
static java.util.Vector getUserTable()
          This method is used by the GanymedeAdmin refreshUsers() method to get a summary of the state of the remotely connected users.
 void killAllUsers(java.lang.String reason)
           
 boolean killUser(java.lang.String username, java.lang.String reason)
          This method is called by the admin console via the GanymedeAdmin class to kick a specific user off of the server.
 arlut.csd.ganymede.Session login(arlut.csd.ganymede.Client client)
          Client login method.
private  arlut.csd.ganymede.GanymedeSession processLogin(java.lang.String clientName, java.lang.String clientPass, arlut.csd.ganymede.Client client, boolean directSession)
          This internal method handles the client login logic for both the normal interactive client and the xml batch client.
(package private) static java.lang.String registerActiveUser(java.lang.String username)
          This method is used by GanymedeSession.login() to find a unique name for a session.
static void removeRemoteUser(arlut.csd.ganymede.GanymedeSession session)
          This method is called to remove a remote user's GanymedeSession object from the GanymedeServer's static sessions field, which is used by the admin console code to iterate over connected users when logging user actions to the Ganymede admin console.
static void sendMessageToRemoteSessions(int type, java.lang.String message)
          Used by the Ganymede server to transmit build status notifications to connected clients.
static void setShutdown()
          This method is used by the shutdown() method to put the server into 'shutdown soon' mode.
static arlut.csd.ganymede.ReturnVal shutdown()
          This method actually does the shutdown.
 arlut.csd.ganymede.ReturnVal sweepEmbeddedObjects()
          This method is used for fixing the server if it somehow leaks embedded objects..
 boolean sweepInvids()
          This method is used when the Ganymede server module is being driven by a direct-linked main method.
 boolean up()
          Simple RMI test method..
 arlut.csd.ganymede.XMLSession xmlLogin(arlut.csd.ganymede.Client client)
          XML Client login method.
 
Methods inherited from class java.rmi.server.UnicastRemoteObject
clone, exportObject, exportObject, exportObject, unexportObject
 
Methods inherited from class java.rmi.server.RemoteServer
getClientHost, getLog, setLog
 
Methods inherited from class java.rmi.server.RemoteObject
equals, getRef, hashCode, toString, toStub
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

server

static arlut.csd.ganymede.GanymedeServer server

Singleton server object. A running Ganymede Server will have one instance of GanymedeServer active and bound into the RMI registry, and this field will point to it.


sessions

private static java.util.Vector sessions

Vector of GanymedeSession objects for users that are logged into the Ganymede server remotely.

Note that there may be GanymedeSession objects active that are not listed in this sessions Vector; GanymedeSession objects used for server-side internal operations are not counted here. This Vector is primarily used to keep track of things for the admin console code in GanymedeAdmin.


activeUsers

static java.util.Hashtable activeUsers

A hashtable mapping session names to identity. Used by the login process to insure that each active remote session will be given a unique identifying name.


userLogOuts

static java.util.Hashtable userLogOuts

A hashtable mapping user Invids to a java.lang.Date object representing the last time that user logged into Ganymede. This data structure is used to check to see if the server's motd.html file has changed since the user last logged in. This hash of timestamps is not preserved in the ganymede.db file, so whenever the server is restarted, all users are presumed to need to see the motd.html file on their next login.


shutdown

static boolean shutdown

If true, the server is waiting for all users to disconnect so that it can shut itself down.


lSemaphore

static arlut.csd.ganymede.loginSemaphore lSemaphore

Our handy, all purpose login semaphore


shutdownSemaphore

static arlut.csd.ganymede.loginSemaphore shutdownSemaphore

Another handy semaphore, this time used to defer shutdowns from build processes


loginSession

private arlut.csd.ganymede.GanymedeSession loginSession

During the login process, we need to get exclusive access over an extended time to synchronized methods in a privileged GanymedeSession to do the query operations for login. If we used the generic Ganymede.internalSession for this, we might lock the server up, as Ganymede.internalSession is also used for Invid label look up operations in the transaction commit process, which involves a writeLock that will block the login's read lock from being granted.

By having our own private GanymedeSession for logins, we avoid this deadlock possibility.

Constructor Detail

GanymedeServer

public GanymedeServer()
               throws java.rmi.RemoteException
GanymedeServer constructor. We only want one server running per invocation of Ganymede, so we'll check that here.

Method Detail

up

public boolean up()
           throws java.rmi.RemoteException

Simple RMI test method.. this method is here so that the ClientBase class can test to see whether it has truly gotten a valid RMI reference to the server.

Specified by:
up in interface Server
java.rmi.RemoteException

login

public arlut.csd.ganymede.Session login(arlut.csd.ganymede.Client client)
                                 throws java.rmi.RemoteException

Client login method. Establishes a GanymedeSession object in the server for the client, and returns a Session remote reference to the client. The GanymedeSession object contains all of the server's knowledge about a given client's status., and is tracked by the GanymedeServer object for statistics and for the admin console's monitoring support.

Specified by:
login in interface Server
java.rmi.RemoteException
See Also:
Server

xmlLogin

public arlut.csd.ganymede.XMLSession xmlLogin(arlut.csd.ganymede.Client client)
                                       throws java.rmi.RemoteException

XML Client login method. Establishes a GanymedeXMLSession object in the server for the client, and returns a XMLSession remote reference to the XML client. The GanymedeXMLSession object in turn contains a GanymedeSession object, which contains all of the server's knowledge about a given client's status., and is tracked by the GanymedeServer object for statistics and for the admin console's monitoring support.

Specified by:
xmlLogin in interface Server
java.rmi.RemoteException
See Also:
Server

processLogin

private arlut.csd.ganymede.GanymedeSession processLogin(java.lang.String clientName,
                                                        java.lang.String clientPass,
                                                        arlut.csd.ganymede.Client client,
                                                        boolean directSession)
                                                 throws java.rmi.RemoteException

This internal method handles the client login logic for both the normal interactive client and the xml batch client.

Parameters:
clientName - The user/persona name to be logged in
clientPass - The password (in plaintext) to authenticate with
client - If we're using the interactive client, the processLogin() method will use the client reference to send a disconnect message explaining the login refusal
directSession - If true, the GanymedeSession returned will export objects created or referenced by the GanymedeSession for direct RMI access
java.rmi.RemoteException

getLoginSemaphore

public static arlut.csd.ganymede.loginSemaphore getLoginSemaphore()

Handy public accessor for the login semaphore, for possible use by plug-in task code.


checkEnabled

public static java.lang.String checkEnabled()

Gated enabled test. If this method returns null, logins are allowed at the time checkEnabled() is called. This method is to be used by admin consoles, which should not connect to the server during schema editing or server shut down, but which should not affect the login count for reasons of blocking a schema edit disable, say.

Returns:
null if logins are currently enabled, or a message string if they are disabled.

addRemoteUser

public static void addRemoteUser(arlut.csd.ganymede.GanymedeSession session)

This method is called to add a remote user's GanymedeSession object to the GanymedeServer's static sessions field, which is used by the admin console code to iterate over connected users when logging user actions to the Ganymede admin console.


removeRemoteUser

public static void removeRemoteUser(arlut.csd.ganymede.GanymedeSession session)

This method is called to remove a remote user's GanymedeSession object from the GanymedeServer's static sessions field, which is used by the admin console code to iterate over connected users when logging user actions to the Ganymede admin console.


getUserTable

public static java.util.Vector getUserTable()

This method is used by the GanymedeAdmin refreshUsers() method to get a summary of the state of the remotely connected users.


sendMessageToRemoteSessions

public static void sendMessageToRemoteSessions(int type,
                                               java.lang.String message)

Used by the Ganymede server to transmit build status notifications to connected clients.


clearIdleSessions

public void clearIdleSessions()
This method is called by the timeOutTask scheduled task, and forces an idle time check on any users logged in.


killAllUsers

public void killAllUsers(java.lang.String reason)

killUser

public boolean killUser(java.lang.String username,
                        java.lang.String reason)
This method is called by the admin console via the GanymedeAdmin class to kick a specific user off of the server.


registerActiveUser

static java.lang.String registerActiveUser(java.lang.String username)
This method is used by GanymedeSession.login() to find a unique name for a session. It is matched with clearActiveUser(), below.


clearActiveUser

static void clearActiveUser(java.lang.String username)
This method is to handle user logout. It is matched with registerActiveUser(), above.


getTextMessage

public static java.lang.StringBuffer getTextMessage(java.lang.String key,
                                                    arlut.csd.ganymede.Invid userToDateCompare,
                                                    boolean html)

This method retrieves a message from a specified directory in the Ganymede installation and passes it back as a StringBuffer. Used by the Ganymede server to pass motd information to the client.

Parameters:
key - A text key indicating the file to be retrieved, minus the .txt or .html extension
userToDateCompare - If not null, the Invid of a user on whose behalf we want to retrieve the message. If the user has logged in more recently than the timestamp of the file has changed, we will return a null result
html - If true, return the .html version. If false, return the .txt version.

admin

public arlut.csd.ganymede.adminSession admin(arlut.csd.ganymede.Admin admin)
                                      throws java.rmi.RemoteException

This public remotely accessible method is called by the Ganymede admin console and/or the Ganymede stopServer script to establish a new admin console connection to the server. Establishes an GanymedeAdmin object in the server.

Adds <admin> as a monitoring admin console.

Specified by:
admin in interface Server
java.rmi.RemoteException
See Also:
Server

setShutdown

public static void setShutdown()

This method is used by the shutdown() method to put the server into 'shutdown soon' mode.


shutdown

public static arlut.csd.ganymede.ReturnVal shutdown()

This method actually does the shutdown.


dump

public void dump()
This method is used by directLoader code to dump the database to disk at the end of the bulk-loading process.


sweepInvids

public boolean sweepInvids()
This method is used when the Ganymede server module is being driven by a direct-linked main method. This method sweeps through all invid's listed in the (loaded) database, and removes any invid's that point to objects not in the database.

Returns:
true if there were any invalid invids in the database

checkInvids

public boolean checkInvids()

This method is used for testing. This method sweeps through all invid's listed in the (loaded) database, and checks to make sure that they all have valid back pointers.

Since the backlinks field (SchemaConstants.BackLinksField) is a general sink for invid's with no homes, we won't explicitly check to see if an invid in a backlink field has a field pointing to it in the target object.. we'll just verify the existence of the object listed.

Returns:
true if there were any invids without back-pointers in the database

checkEmbeddedObjects

public boolean checkEmbeddedObjects()

This method is used for testing. This method sweeps through all embedded objects in the (loaded) database, and checks to make sure that they all have valid containing objects.

Returns:
true if there were any embedded objects without containers in the database

sweepEmbeddedObjects

public arlut.csd.ganymede.ReturnVal sweepEmbeddedObjects()

This method is used for fixing the server if it somehow leaks embedded objects.. This method sweeps through all embedded objects in the (loaded) database, and deletes any that do not have valid containing objects.