You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/01/28 23:40:36 UTC
svn commit: r373254 - in /directory/trunks/apacheds/standalone:
daemon/src/main/java/org/apache/directory/server/standalone/daemon/
simple/main/src/main/java/org/apache/ldap/server/
Author: akarasulu
Date: Sat Jan 28 14:40:26 2006
New Revision: 373254
URL: http://svn.apache.org/viewcvs?rev=373254&view=rev
Log:
got shutdown socket working with procrun
Modified:
directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/Bootstrapper.java
directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/ProcrunBootstrapper.java
directory/trunks/apacheds/standalone/simple/main/src/main/java/org/apache/ldap/server/DirectoryServer.java
Modified: directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/Bootstrapper.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/Bootstrapper.java?rev=373254&r1=373253&r2=373254&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/Bootstrapper.java (original)
+++ directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/Bootstrapper.java Sat Jan 28 14:40:26 2006
@@ -17,10 +17,22 @@
package org.apache.directory.server.standalone.daemon;
+import java.io.BufferedReader;
+import java.io.File;
import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
import java.net.URL;
import java.net.URLClassLoader;
+import java.security.AccessControlException;
import java.util.Properties;
+import java.util.Random;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
@@ -39,6 +51,16 @@
private static final Logger log = LoggerFactory.getLogger( Bootstrapper.class );
private static final String START_CLASS_PROP = "bootstrap.start.class";
private static final String STOP_CLASS_PROP = "bootstrap.stop.class";
+
+ /** Shutdown command to use for await() */
+ private static final String SHUTDOWN = "SHUTDOWN";
+
+ private static final String SHUTDOWN_FILE = "shutdownPort";
+ /** The Port to Listen on for Shutdown commands */
+ private int shutdownPort = -1;
+ /** Random number generator */
+ private Random random;
+
private InstallationLayout layout;
private ClassLoader application;
@@ -222,5 +244,179 @@
}
return EMPTY_STRARRAY;
+ }
+
+
+ public void sendShutdownCommand() throws IOException
+ {
+ Socket socket = null;
+ OutputStream stream = null;
+
+ if ( shutdownPort == -1 )
+ {
+ File shutdownPortFile = new File( layout.getRunDirectory(), SHUTDOWN_FILE );
+ if ( shutdownPortFile.exists() )
+ {
+ BufferedReader in = new BufferedReader( new FileReader( shutdownPortFile ) );
+ shutdownPort = Integer.parseInt( in.readLine() );
+ in.close();
+ }
+ }
+
+ // this stops the main thread listening for shutdown requests
+ try {
+ socket = new Socket( "127.0.0.1", shutdownPort );
+ stream = socket.getOutputStream();
+
+ for (int i = 0; i < SHUTDOWN.length(); i++ )
+ {
+ stream.write( SHUTDOWN.charAt(i) );
+ }
+
+ stream.flush();
+ }
+ finally
+ {
+ if ( stream != null ) stream.close();
+ if ( socket != null ) socket.close();
+ }
+ }
+
+
+ /**
+ * Wait until a proper shutdown command is received, then return.
+ */
+ public void waitForShutdown()
+ {
+ try
+ {
+ shutdownPort = AvailablePortFinder.getNextAvailable( 30003 );
+ File shutdownPortFile = new File( layout.getRunDirectory(), SHUTDOWN_FILE );
+ if ( shutdownPortFile.exists() )
+ {
+ String msg = "Shutdown port file " + shutdownPortFile + " exists. ";
+ msg += "\nEither the server is already running or a previous run existed abruptly.";
+ msg += "\nIf the server is not running remove this file and try again.";
+ log.error( msg );
+ throw new IllegalStateException( msg );
+ }
+ FileWriter writer = new FileWriter( shutdownPortFile );
+ writer.write( shutdownPort + "\n" );
+ writer.close();
+ }
+ catch ( IOException e )
+ {
+ log.error( "Failed to setup shutdown port", e );
+ System.exit( ExitCodes.START );
+ }
+
+ // Set up a server socket to wait on
+ ServerSocket serverSocket = null;
+ try
+ {
+ serverSocket = new ServerSocket( shutdownPort, 1, InetAddress.getByName( "127.0.0.1" ) );
+ log.debug( "waiting for shutdown command on port = " + shutdownPort );
+ }
+ catch ( IOException e )
+ {
+ log.error( "server waitForShutdown: create[" + shutdownPort + "]: ", e );
+ System.exit( 1 );
+ }
+
+ // Loop waiting for a connection and a valid command
+ while ( true )
+ {
+ // Wait for the next connection
+ Socket socket = null;
+ InputStream stream = null;
+
+ try
+ {
+ socket = serverSocket.accept();
+ socket.setSoTimeout(10 * 1000); // Ten seconds
+ stream = socket.getInputStream();
+ }
+ catch ( AccessControlException ace )
+ {
+ log.warn( "Standard Server.accept security exception: " + ace.getMessage(), ace );
+ continue;
+ }
+ catch ( IOException e )
+ {
+ log.error( "Server.await: accept: ", e );
+ System.exit( 5 );
+ }
+
+ // Read a set of characters from the socket
+ StringBuffer command = new StringBuffer();
+ int expected = 1024; // Cut off to avoid DoS attack
+
+ while ( expected < SHUTDOWN.length() )
+ {
+ if ( random == null )
+ {
+ random = new Random(System.currentTimeMillis());
+ }
+ expected += ( random.nextInt() % 1024 );
+ }
+ while ( expected > 0 )
+ {
+ int ch;
+ try
+ {
+ ch = stream.read();
+ }
+ catch ( IOException e )
+ {
+ log.warn( "StandardServer.await: read: ", e );
+ ch = -1;
+ }
+
+ if ( ch < 32 ) // Control character or EOF terminates loop
+ {
+ break;
+ }
+
+ command.append( ( char ) ch );
+ expected--;
+ }
+
+ // Close the socket now that we are done with it
+ try
+ {
+ socket.close();
+ }
+ catch ( IOException e )
+ {
+ log.debug( "Failed on socket close", e );
+ }
+
+ // Match against our command string
+ boolean match = command.toString().equals( SHUTDOWN );
+ if ( match )
+ {
+ break;
+ }
+ else
+ {
+ log.warn( "Server.await: Invalid command '" + command.toString() + "' received" );
+ }
+ }
+
+ // Close the server socket and return
+ try
+ {
+ serverSocket.close();
+ }
+ catch ( IOException e )
+ {
+ log.debug( "Failed on socket close", e );
+ }
+
+ File shutdownPortFile = new File( layout.getRunDirectory(), SHUTDOWN_FILE );
+ if ( shutdownPortFile.exists() )
+ {
+ shutdownPortFile.delete();
+ }
}
}
Modified: directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/ProcrunBootstrapper.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/ProcrunBootstrapper.java?rev=373254&r1=373253&r2=373254&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/ProcrunBootstrapper.java (original)
+++ directory/trunks/apacheds/standalone/daemon/src/main/java/org/apache/directory/server/standalone/daemon/ProcrunBootstrapper.java Sat Jan 28 14:40:26 2006
@@ -25,6 +25,7 @@
* The bootstrapper used for procrun services on windows platforms. This
* class contains static methods invoked by the prunsrv service manager.
*
+ * @todo explain procrun behavoir
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
@@ -63,23 +64,19 @@
log.debug( "prunsrvStart(String[]) calling callStart()" );
instance.callStart( false );
- // This is only needed for procrun
- while( true )
- {
- try
- {
- Thread.sleep( 2000 );
- }
- catch ( InterruptedException e )
- {
- e.printStackTrace();
- }
- }
+ log.debug( "prunsrvStart(String[]) block waitForShutdown()" );
+ instance.waitForShutdown();
+ log.debug( "prunsrvStart(String[]) returned from waitForShutdown()" );
+
+ log.debug( "prunsrvStart(String[]) calling callStop()" );
+ instance.callStop( shift( args, 1 ) );
+ log.debug( "prunsrvStart(String[]) calling callDestroy()" );
+ instance.callDestroy();
}
catch ( Throwable t )
{
log.error( "Encountered error in prunsrvStart(String[])", t );
- System.exit( 4 );
+ System.exit( ExitCodes.UNKNOWN );
}
}
@@ -102,16 +99,12 @@
ProcrunBootstrapper instance = new ProcrunBootstrapper();
instance.setInstallationLayout( args[0] );
instance.setParentLoader( Bootstrapper.class.getClassLoader() );
-
- log.debug( "prunsrvStop(String[]) calling callStop()" );
- instance.callStop( shift( args, 1 ) );
- log.debug( "prunsrvStop(String[]) calling callDestroy()" );
- instance.callDestroy();
+ instance.sendShutdownCommand();
}
catch ( Throwable t )
{
log.error( "Encountered error in prunsrvStop(String[])", t );
- System.exit( 4 );
+ System.exit( ExitCodes.UNKNOWN );
}
}
}
Modified: directory/trunks/apacheds/standalone/simple/main/src/main/java/org/apache/ldap/server/DirectoryServer.java
URL: http://svn.apache.org/viewcvs/directory/trunks/apacheds/standalone/simple/main/src/main/java/org/apache/ldap/server/DirectoryServer.java?rev=373254&r1=373253&r2=373254&view=diff
==============================================================================
--- directory/trunks/apacheds/standalone/simple/main/src/main/java/org/apache/ldap/server/DirectoryServer.java (original)
+++ directory/trunks/apacheds/standalone/simple/main/src/main/java/org/apache/ldap/server/DirectoryServer.java Sat Jan 28 14:40:26 2006
@@ -97,6 +97,8 @@
}
+ // @todo don't think this nowait is needed here if the procrun bootstrapper
+ // handles the creation of the socket and the blocking.
public void start( boolean nowait )
{
startNoWait = nowait;
@@ -109,7 +111,7 @@
}
started = true;
- worker.run(); // - blocks here
+// worker.run(); // - blocks here
}