[jboss-cvs] JBossAS SVN: r84021 - projects/server-manager/trunk/src/main/java/org/jboss/jbossas/servermanager.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Feb 9 16:57:48 EST 2009


Author: rachmatowicz at jboss.com
Date: 2009-02-09 16:57:48 -0500 (Mon, 09 Feb 2009)
New Revision: 84021

Added:
   projects/server-manager/trunk/src/main/java/org/jboss/jbossas/servermanager/ServerController.java
Log:
Restore (accidentally deleted) copy of ServerController.java

Added: projects/server-manager/trunk/src/main/java/org/jboss/jbossas/servermanager/ServerController.java
===================================================================
--- projects/server-manager/trunk/src/main/java/org/jboss/jbossas/servermanager/ServerController.java	                        (rev 0)
+++ projects/server-manager/trunk/src/main/java/org/jboss/jbossas/servermanager/ServerController.java	2009-02-09 21:57:48 UTC (rev 84021)
@@ -0,0 +1,571 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.jbossas.servermanager;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.io.StringWriter;
+import java.net.HttpURLConnection;
+import java.net.Socket;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.StringTokenizer;
+
+/**
+ * Starts, stops, and (eventually) reboots server instances.
+ * 
+ * @author <a href="ryan.campbell at jboss.com">Ryan Campbell</a>
+ * @version $Revision: 82586 $
+ */
+public abstract class ServerController
+{
+   private static final String SHUTDOWN_CLASS = "org.jboss.Shutdown";
+
+   private static final String MAIN = "org.jboss.Main"; 
+   
+   private ServerController()
+   {
+   }
+
+   /**
+    * Start the server and pump its output and error streams.
+    * 
+    * @param server
+    * @param manager
+    * @throws IOException
+    */
+   public static void startServer(Server server, ServerManager manager) throws IOException
+   {
+      if (server.isRunning())
+      {
+         throw new IllegalArgumentException("The " + server.getName() + " server is already running.");
+      }
+
+      if (isServerStarted(server))
+      {
+         throw new IOException("Found a process already listening on:" + server.getHttpUrl() + " or "+ server.getRmiUrl());
+      }
+
+      // make sure these are initialized
+      server.setNamingContext(null);
+      server.setServerConnection(null);
+
+      String execCmd = getStartCommandLine(server, manager);
+
+      System.out.println("Starting server \"" + server.getName() + "\", with command (start timeout is " + manager.getStartupTimeout() + " seconds ): \n" + execCmd);
+
+      File binDir = new File(manager.getJBossHome(), "/bin");
+      final Process process = Runtime.getRuntime().exec(execCmd, null, binDir);
+
+      final BufferedReader errStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+      final BufferedReader inStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
+
+      final File outFile = server.getOutputLog();
+      initalizeLog(outFile);
+      final PrintWriter outlog = new PrintWriter(new FileWriter(outFile));
+      server.setOutWriter(outlog);
+
+      Thread outPump = new OutputPumper(inStream, outlog);
+      outPump.start();
+
+      final File errorFile = server.getErrorLog();
+      initalizeLog(errorFile);
+      final PrintWriter errorlog = new PrintWriter(new FileWriter(errorFile));
+      server.setErrorWriter(errorlog);
+
+      Thread errorPump = new OutputPumper(errStream, errorlog);
+      errorPump.start();
+
+      /*
+       * TODO: -TME This is a real problem.  If maintain reference
+       * to the process, even for a short period of time, willl
+       * cause the spawned process' threads to block when this process
+       * blocks.  So if uncomment following line, then the ServerTestHarness
+       * will block abnormally, thus causing the tests not to run correctly.
+       * 
+       * Is this true for our environment? - rcampbell
+       */
+      server.setProcess(process);
+
+      try
+      {
+         waitForServer(server, manager);
+      }
+      catch (IOException e)
+      {
+     	 // this affects the value of Server.isStopped()
+         server.setProcess(null);
+         throw e;
+      }
+      
+      System.out.println("Server started.") ;
+   }
+
+   /** 
+    * Delete & create log files
+    * @param logFile
+    * @throws IOException
+    */
+   private static void initalizeLog(final File logFile) throws IOException
+   {
+      if (logFile.exists())
+      {
+         logFile.delete();
+      }
+      if (!logFile.getParentFile().exists())
+      {
+         logFile.getParentFile().mkdir();
+      }
+
+      logFile.createNewFile();
+   }
+
+   /** 
+    * Create the command line to execute
+    * 
+    * @param server the server
+    * @param manager the manager
+    * @return the command line
+    * @throws IOException for any error
+    */
+   private static String getStartCommandLine(Server server, ServerManager manager) throws IOException
+   {
+      String execCmd = manager.getJavaExecutable() + " -cp " + manager.getStartClasspath() + " ";
+      execCmd = execCmd + server.getJvmArgs() + server.getSysProperties();
+      execCmd = execCmd + " " + MAIN + " -c " + server.getConfig() + " -b " + server.getHost() + " -g " + server.getPartition();
+      
+      if (manager.getUdpGroup() != null && ! manager.getUdpGroup().equals(""))
+      {
+         execCmd = execCmd + " -u " + manager.getUdpGroup();   
+      }
+      execCmd = execCmd + " " + server.getArgs();
+      return execCmd;
+   }
+
+   /**
+    * Get the server shutdown command line.
+    *
+    * @param server the server
+    * @param manager the manager
+    * @return the shutdown command
+    * @throws IOException for any error
+    */
+   private static String getStopCommandLine(Server server, ServerManager manager) throws IOException
+   {
+      String strAuth="";
+      String username = server.getUsername();
+      String password = server.getPassword();
+      if ( username != null && password != null )
+      {
+         strAuth = " -u " + username + " -p " + password;
+      }
+
+      String execCmd = manager.getJavaExecutable() + " -cp " + manager.getStopClasspath() + " ";
+      execCmd = execCmd + SHUTDOWN_CLASS + " --server " + server.getServerUrl();
+      execCmd = execCmd + strAuth +" --shutdown";
+      return execCmd;
+   }
+
+   /**
+    * Shutdown server with shutdown.jar
+    *
+    * @param server the server
+    * @param manager the manager
+    * @return the command output
+    * @throws IOException for any error
+    * @throws InterruptedException if interrupted while waiting for shutdown.jar
+    */
+   private static boolean stopServerCli(Server server, ServerManager manager, Writer log) throws IOException, InterruptedException
+   {
+      String shutdownCmd = getStopCommandLine(server, manager);
+      System.out.println("Shutting down server: " + shutdownCmd);
+
+      StringTokenizer cmdArrayTokenizer = new StringTokenizer(shutdownCmd);
+      String[] cmdArray = new String[cmdArrayTokenizer.countTokens()];
+      for (int i=0; i<cmdArray.length; i++)
+      {
+         cmdArray[i]=cmdArrayTokenizer.nextToken();
+      }
+
+      ProcessBuilder builder = new ProcessBuilder(cmdArray);
+      builder.redirectErrorStream(true);
+      Process proc = builder.start();
+
+      try
+      {
+         proc.getOutputStream().close();
+         BufferedReader stdout = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+         PrintWriter output = new PrintWriter(log);
+
+         OutputPumper pumper = new OutputPumper(stdout, output);
+         pumper.start();
+
+         // Wait 20.5 seconds for shutdown.jar to complete
+         pumper.join(20000);
+         Thread.sleep(500);
+
+         if (proc.exitValue() != 0) {
+            return false;
+         }
+      }
+      catch (IllegalThreadStateException itse)
+      {
+         return false;
+      }
+      finally
+      {
+         proc.destroy();
+         closeAllStreams(proc);
+      }
+
+      return true;
+   }
+
+   /** 
+    * Wait until the jboss instance is full initialized
+    * @param server
+    * @param manager 
+    * @throws IOException
+    */
+   private static void waitForServer(Server server, ServerManager manager) throws IOException
+   {
+
+      int tries = 0;
+      while (tries++ < manager.getStartupTimeout())
+      {
+         if (!server.isRunning())
+         {
+         	// save output and error streams before raising exception (and terminating ant task)
+         	closeAllStreams(server.getProcess()) ;
+         	server.getErrorWriter().close() ;
+         	server.getOutWriter().close() ;
+         	
+            throw new IOException("Server failed to start; see logs. exit code: " + server.getProcess().exitValue());
+         }
+
+         try
+         {
+            Thread.sleep(1000);
+         }
+         catch (InterruptedException e)
+         {
+         }
+         if (isServerStarted(server))
+         {
+            return;
+         }
+      }
+
+      Process process = server.getProcess();
+      
+  	  // save output and error streams before raising exception (and terminating ant task)
+  	  closeAllStreams(server.getProcess()) ;
+  	  server.getErrorWriter().close() ;
+  	  server.getOutWriter().close() ;
+      
+      System.err.println("Failed to start server \"" + server.getName()
+            + "\" before timeout. Destroying the process.");
+      process.destroy();
+
+      throw new IOException("Server failed to start in time; see logs.");
+
+   }
+
+   /**
+    * Check if the server is fully intialized by trying to 
+    * open a connection to tomcat.
+    * 
+    * @param server the server
+    * @return whether it is started
+    * @throws IOException for any error
+    */
+   public static boolean isServerStarted(Server server) throws IOException
+   {
+      URL url = server.getHttpUrl();
+      if (server.hasWebServer())
+      {
+         try
+         {
+            URLConnection conn = url.openConnection();
+            if (conn instanceof HttpURLConnection)
+            {
+               HttpURLConnection http = (HttpURLConnection) conn;
+               int responseCode = http.getResponseCode();
+
+               if (responseCode > 0 && responseCode < 400)
+               {
+                  return true;
+               }
+            }
+         }
+         catch (IOException e)
+         {
+            return false;
+         }
+         return false;
+      }
+      else
+      {
+         //see if the rmi port is active
+         Socket socket = null;
+         try
+         {
+            socket = new Socket(server.getHost(), server.getRmiPort().intValue());
+            return true;
+         }
+         catch (IOException e)
+         {
+            return false;
+         }
+         finally
+         {
+            if (socket != null)
+            {
+               socket.close();
+            }
+         }
+      }
+   }
+
+   /**
+    * Stop the server.
+    * Get thread dump and Process.destroy() the server 
+    * if it fails to shutdown.
+    * 
+    * @param server
+    * @param manager
+    * @throws IOException
+    */
+   public static void stopServer(Server server, ServerManager manager) throws IOException
+   {
+      boolean useShutdownJar = Boolean.getBoolean("sm.legacy.shutdown");
+      StringWriter shutdownJarOutput = null;
+
+      boolean cleanShutdown = true;
+      Throwable shutdownException = null;
+		
+      if (!server.isRunning())
+      {
+         throw new IllegalArgumentException("The " + server.getName() + " is not running; it cannot be stopped.");
+      }
+
+      System.out.println("Shutting down server: " + server.getName());
+
+      /** Catch everything as we want the server killed unconditionally **/
+      try
+      {
+         if (useShutdownJar)
+         {
+            shutdownJarOutput = new StringWriter(512);
+            cleanShutdown = stopServerCli(server, manager, shutdownJarOutput);
+         }
+         else
+         {
+            server.doShutdown();
+         }
+      }
+      catch (Throwable e)
+      {
+         shutdownException = e;
+         cleanShutdown = false;
+      }
+
+      Process process = server.getProcess();
+      if (cleanShutdown && !waitOnShutdown(server, manager))
+      {
+         cleanShutdown = false;
+      }
+
+      if (!cleanShutdown)
+      {
+         // try to provide some debug info
+         try
+         {
+            if (useShutdownJar)
+               System.err.println(shutdownJarOutput.toString());
+            else
+               writeServerDump(server);
+         }
+         catch (Throwable e)
+         {
+            e.printStackTrace();
+         }
+
+         // destroy process and print an error messsage
+         process.destroy();
+         System.err.println("Failed to shutdown server \"" + server.getName()
+            + "\"" + (shutdownException == null ? " before timeout." : ".")
+               + " Destroying the process.");
+      }
+
+      closeAllStreams(process);
+      server.getErrorWriter().close();
+      server.getOutWriter().close();
+
+  	  // this affects the value of Server.isStopped()
+      server.setProcess(null);
+
+      if (!cleanShutdown)
+      {
+         throw (ServerShutdownException) new ServerShutdownException(
+            "Failed to shutdown server"
+            + (shutdownException == null ? " before timeout." : ".")
+            + "Process was destroyed."
+            ).initCause(shutdownException);
+      }
+      
+      System.out.println("Server stopped.") ;
+   }
+
+   /**
+    * Dump Server trace to file 
+    * @param server
+    * @throws IOException on faled dump file write
+    */
+   private static void writeServerDump(final Server server) throws IOException
+   {
+         String threadDump = null;
+         Exception dumpException = null;
+         try
+         {
+            threadDump = server.listThreadDump();
+         }
+         catch (Exception e)
+         {
+            dumpException = e;
+         }
+         if ( threadDump == null )
+         {
+            threadDump = "Unable to get server thread dump: ";
+            if ( dumpException == null )
+            {
+               dumpException = (Exception) new RuntimeException("threadDump and dumpException null - something broken").fillInStackTrace();
+               
+            }
+            StringWriter dumpExceptionWriter = new StringWriter(512);
+            dumpException.printStackTrace(new PrintWriter(dumpExceptionWriter));
+            threadDump = threadDump + dumpExceptionWriter.toString();
+         }
+         File dumpFile = server.getDumpFile();
+         System.out.println("Writing server thread dump to "
+            + dumpFile.getAbsolutePath());
+
+         try
+         {
+            FileWriter dumpFW = new FileWriter(dumpFile);
+            dumpFW.write(threadDump);
+            dumpFW.flush();
+            dumpFW.close();
+         }
+         catch (Exception e)
+         {
+            System.err.println("Cannot write to "
+               + dumpFile.getAbsolutePath());
+            e.printStackTrace();
+         }
+   }
+
+   /**
+    * Wait for the server to shutdown. 
+    * @param server
+    * @param manager 
+    * @return true if server process ends before timeout
+    */
+   private static boolean waitOnShutdown(Server server, ServerManager manager)
+   {
+      int shutdownTimeout = manager.getShutdownTimeout();
+      System.out.println("shutdownTimeout will be="+shutdownTimeout);
+      for (int tries = 0; tries < shutdownTimeout; tries++)
+      {  
+         try
+         {
+            if (!server.isRunning())
+            {
+               return true;
+            }
+            Thread.sleep(1000);
+         }
+         catch (InterruptedException e)
+         {
+         }
+      }
+
+      return false;
+   }
+
+   /**
+    * Close the streams of a process.
+    * 
+    * @param process
+    */
+   private static void closeAllStreams(Process process)
+   {
+      try
+      {
+         process.getInputStream().close();
+         process.getOutputStream().close();
+         process.getErrorStream().close();
+      }
+      catch (IOException e)
+      {
+      }
+   }
+
+   /**
+    * A OutputPumper.  Redirect std err & out to log files.
+    * 
+    * @author <a href="ryan.campbell at jboss.com">Ryan Campbell</a>
+    * @version $Revision: 82586 $
+    */
+   private static class OutputPumper extends Thread
+   {
+      private BufferedReader outputReader;
+
+      private PrintWriter logWriter;
+
+      public OutputPumper(BufferedReader outputReader, PrintWriter logWriter)
+      {
+         this.outputReader = outputReader;
+         this.logWriter = logWriter;
+      }
+
+      public void run()
+      {
+         try
+         {
+            String line = null;
+            while ((line = outputReader.readLine()) != null)
+            {
+               logWriter.println(line);
+            }
+         }
+         catch (IOException e)
+         {
+         }
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list