KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > util > server > ServerController


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.test.util.server;
23
24 import java.io.BufferedReader JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileWriter JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.net.HttpURLConnection JavaDoc;
31 import java.net.Socket JavaDoc;
32 import java.net.URL JavaDoc;
33 import java.net.URLConnection JavaDoc;
34
35 /**
36  * Starts, stops, and (eventually) reboots server instances.
37  *
38  * @author <a HREF="ryan.campbell@jboss.com">Ryan Campbell</a>
39  * @version $Revision: 57471 $
40  */

41 public abstract class ServerController
42 {
43
44    private static final String JavaDoc SHUTDOWN_CLASS = "org.jboss.Shutdown";
45
46    private static final String JavaDoc MAIN = "org.jboss.Main";
47    
48    private ServerController()
49    {
50    }
51
52    /**
53     * Start the server and pump its output and error streams.
54     *
55     * @param server
56     * @param manager
57     * @throws IOException
58     */

59    public static void startServer(Server server, ServerManager manager) throws IOException JavaDoc
60    {
61       if (server.isRunning())
62       {
63          throw new IllegalArgumentException JavaDoc("The " + server.getName() + " server is already running.");
64       }
65
66       if (isServerStarted(server))
67       {
68          throw new IOException JavaDoc("Found a process already listening on:" + server.getHttpUrl() + " or "+ server.getRmiUrl());
69       }
70
71       String JavaDoc execCmd = getStartCommandLine(server, manager);
72
73       System.out.println("Starting server \"" + server.getName() + "\" with command: \n" + execCmd);
74
75       File JavaDoc binDir = new File JavaDoc(manager.getJBossHome(), "/bin");
76       final Process JavaDoc process = Runtime.getRuntime().exec(execCmd, null, binDir);
77
78       final BufferedReader JavaDoc errStream = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(process.getErrorStream()));
79       final BufferedReader JavaDoc inStream = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(process.getInputStream()));
80
81       final File JavaDoc outFile = server.getOutputLog();
82       initalizeLog(outFile);
83       final PrintWriter JavaDoc outlog = new PrintWriter JavaDoc(new FileWriter JavaDoc(outFile));
84       server.setOutWriter(outlog);
85
86       Thread JavaDoc outPump = new OutputPumper(inStream, outlog);
87       outPump.start();
88
89       final File JavaDoc errorFile = server.getErrorLog();
90       initalizeLog(errorFile);
91       final PrintWriter JavaDoc errorlog = new PrintWriter JavaDoc(new FileWriter JavaDoc(errorFile));
92       server.setErrorWriter(errorlog);
93
94       Thread JavaDoc errorPump = new OutputPumper(errStream, errorlog);
95       errorPump.start();
96
97       /*
98        * TODO: -TME This is a real problem. If maintain reference
99        * to the process, even for a short period of time, willl
100        * cause the spawned process' threads to block when this process
101        * blocks. So if uncomment following line, then the ServerTestHarness
102        * will block abnormally, thus causing the tests not to run correctly.
103        *
104        * Is this true for our environment? - rcampbell
105        */

106       server.setProcess(process);
107
108       try
109       {
110          waitForServer(server, manager);
111       }
112       catch (IOException JavaDoc e)
113       {
114          server.setProcess(null);
115          throw e;
116       }
117
118    }
119
120    /**
121     * Delete & create log files
122     * @param logFile
123     * @throws IOException
124     */

125    private static void initalizeLog(final File JavaDoc logFile) throws IOException JavaDoc
126    {
127       if (logFile.exists())
128       {
129          logFile.delete();
130       }
131       if (!logFile.getParentFile().exists())
132       {
133          logFile.getParentFile().mkdir();
134       }
135
136       logFile.createNewFile();
137    }
138
139    /**
140     * Create the command line to execute
141     *
142     * @param server the server
143     * @param manager the manager
144     * @return the command line
145     * @throws IOException for any error
146     */

147    private static String JavaDoc getStartCommandLine(Server server, ServerManager manager) throws IOException JavaDoc
148    {
149       String JavaDoc execCmd = manager.getJavaExecutable() + " -cp " + manager.getStartClasspath() + " ";
150       execCmd = execCmd + server.getJvmArgs() + server.getSysProperties();
151       execCmd = execCmd + " " + MAIN + " -c " + server.getConfig() + " -b " + server.getHost();
152       
153       if (manager.getUdpGroup() != null && ! manager.getUdpGroup().equals(""))
154       {
155          execCmd = execCmd + " -u " + manager.getUdpGroup();
156       }
157       execCmd = execCmd + " " + server.getArgs();
158       return execCmd;
159    }
160
161    /**
162     * Wait until the jboss instance is full initialized
163     * @param server
164     * @param manager
165     * @throws IOException
166     */

167    private static void waitForServer(Server server, ServerManager manager) throws IOException JavaDoc
168    {
169
170       int tries = 0;
171       while (tries++ < manager.getStartupTimeout())
172       {
173          if (!server.isRunning())
174          {
175             throw new IOException JavaDoc("Server failed to start; see logs. exit code: " + server.getProcess().exitValue());
176          }
177
178          try
179          {
180             Thread.sleep(1000);
181          }
182          catch (InterruptedException JavaDoc e)
183          {
184          }
185          if (isServerStarted(server))
186          {
187             return;
188          }
189       }
190       throw new IOException JavaDoc("Server failed to start; see logs.");
191
192    }
193
194    /**
195     * Check if the server is fully intialized by trying to
196     * open a connection to tomcat.
197     *
198     * @param server the server
199     * @return whether it is started
200     * @throws IOException for any error
201     */

202    private static boolean isServerStarted(Server server) throws IOException JavaDoc
203    {
204       URL JavaDoc url = server.getHttpUrl();
205       if (server.hasWebServer())
206       {
207          try
208          {
209             URLConnection JavaDoc conn = url.openConnection();
210             if (conn instanceof HttpURLConnection JavaDoc)
211             {
212                HttpURLConnection JavaDoc http = (HttpURLConnection JavaDoc) conn;
213                int responseCode = http.getResponseCode();
214
215                if (responseCode > 0 && responseCode < 400)
216                {
217                   return true;
218                }
219             }
220          }
221          catch (java.io.IOException JavaDoc e)
222          {
223             return false;
224          }
225          return false;
226       }
227       else
228       {
229          //see if the rmi port is active
230
Socket JavaDoc socket = null;
231          try
232          {
233             socket = new Socket JavaDoc(server.getHost(), server.getRmiPort().intValue());
234             return true;
235          }
236          catch (IOException JavaDoc e)
237          {
238             return false;
239          }
240          finally
241          {
242             if (socket != null)
243             {
244                socket.close();
245             }
246          }
247       }
248    }
249
250    /**
251     * Stop the server using shutdown.jar.
252     * Process.destroy() the server if it fails to shutdown.
253     *
254     * @param server
255     * @param manager
256     * @throws IOException
257     */

258    public static void stopServer(Server server, ServerManager manager) throws IOException JavaDoc
259    {
260       if (!server.isRunning())
261       {
262          throw new IllegalArgumentException JavaDoc("The " + server.getName() + " is not running; it cannot be stopped.");
263       }
264
265       System.out.println("Shutting down server: " + server.getName());
266
267       String JavaDoc shutdownCmd = getStopCommandLine(server, manager);
268       System.out.println("Shutting down server: " + shutdownCmd);
269
270       Runtime.getRuntime().exec(shutdownCmd);
271
272       Process JavaDoc process = server.getProcess();
273       if (!waitOnShutdown(server, manager))
274       {
275          System.err.println("Failed to shutdown server \"" + server.getName()
276                + "\" before timeout. Destroying the process.");
277          process.destroy();
278       }
279
280       closeAllStreams(process);
281       server.getErrorWriter().close();
282       server.getOutWriter().close();
283
284       server.setProcess(null);
285       try
286       {
287          Thread.sleep(45000);
288       }
289       catch (InterruptedException JavaDoc e)
290       {
291       }
292    }
293
294    /**
295     * Wait for the server to shutdown.
296     * @param server
297     * @param manager
298     * @return true if server process ends before timeout
299     */

300    private static boolean waitOnShutdown(Server server, ServerManager manager)
301    {
302       int shutdownTimeout = manager.getShutdownTimeout();
303       System.out.println("shutdownTimeout will be="+shutdownTimeout);
304       for (int tries = 0; tries < shutdownTimeout; tries++)
305       {
306          try
307          {
308             if (!server.isRunning())
309             {
310                return true;
311             }
312             Thread.sleep(1000);
313          }
314          catch (InterruptedException JavaDoc e)
315          {
316          }
317       }
318
319       return false;
320    }
321
322    /**
323     * Get the server shutdown command line.
324     *
325     * @param server the server
326     * @param manager the manager
327     * @return the shutdown command
328     * @throws IOException for any error
329     */

330    private static String JavaDoc getStopCommandLine(Server server, ServerManager manager) throws IOException JavaDoc
331    {
332       String JavaDoc execCmd = manager.getJavaExecutable() + " -cp " + manager.getStopClasspath() + " ";
333       execCmd = execCmd + SHUTDOWN_CLASS + " --server " + server.getRmiUrl();
334       execCmd = execCmd + " --shutdown";
335       return execCmd;
336    }
337
338    /**
339     * Close the streams of a process.
340     *
341     * @param process
342     */

343    private static void closeAllStreams(Process JavaDoc process)
344    {
345       try
346       {
347          process.getInputStream().close();
348          process.getOutputStream().close();
349          process.getErrorStream().close();
350       }
351       catch (IOException JavaDoc e)
352       {
353       }
354    }
355
356    /**
357     * A OutputPumper. Redirect std err & out to log files.
358     *
359     * @author <a HREF="ryan.campbell@jboss.com">Ryan Campbell</a>
360     * @version $Revision: 57471 $
361     */

362    private static class OutputPumper extends Thread JavaDoc
363    {
364       private BufferedReader JavaDoc outputReader;
365
366       private PrintWriter JavaDoc logWriter;
367
368       public OutputPumper(BufferedReader JavaDoc outputReader, PrintWriter JavaDoc logWriter)
369       {
370          this.outputReader = outputReader;
371          this.logWriter = logWriter;
372       }
373
374       public void run()
375       {
376          try
377          {
378             String JavaDoc line = null;
379             while ((line = outputReader.readLine()) != null)
380             {
381                logWriter.println(line);
382             }
383          }
384          catch (IOException JavaDoc e)
385          {
386          }
387       }
388    }
389
390 }
391
Popular Tags