View Javadoc

1   /*
2    * $Header$
3    * $Revision: 175 $
4    * $Date: 2004-07-31 11:40:36 +0200 (sáb 31 de jul de 2004) $
5    *
6    * ====================================================================
7    *
8    * The Apache Software License, Version 1.1
9    *
10   * Copyright (c) 1999 The Apache Software Foundation.  All rights
11   * reserved.
12   *
13   * Redistribution and use in source and binary forms, with or without
14   * modification, are permitted provided that the following conditions
15   * are met:
16   *
17   * 1. Redistributions of source code must retain the above copyright
18   *    notice, this list of conditions and the following disclaimer.
19   *
20   * 2. Redistributions in binary form must reproduce the above copyright
21   *    notice, this list of conditions and the following disclaimer in
22   *    the documentation and/or other materials provided with the
23   *    distribution.
24   *
25   * 3. The end-user documentation included with the redistribution, if
26   *    any, must include the following acknowlegement:
27   *       "This product includes software developed by the
28   *        Apache Software Foundation (http://www.apache.org/)."
29   *    Alternately, this acknowlegement may appear in the software itself,
30   *    if and wherever such third-party acknowlegements normally appear.
31   *
32   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
33   *    Foundation" must not be used to endorse or promote products derived
34   *    from this software without prior written permission. For written
35   *    permission, please contact apache@apache.org.
36   *
37   * 5. Products derived from this software may not be called "Apache"
38   *    nor may "Apache" appear in their names without prior written
39   *    permission of the Apache Group.
40   *
41   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52   * SUCH DAMAGE.
53   * ====================================================================
54   *
55   * This software consists of voluntary contributions made by many
56   * individuals on behalf of the Apache Software Foundation.  For more
57   * information on the Apache Software Foundation, please see
58   * <http://www.apache.org/>.
59   *
60   * [Additional notices, if required by prior licensing conditions]
61   *
62   */
63  
64  
65  package org.apache.catalina.servlets;
66  
67  import java.io.IOException;
68  import java.io.PrintWriter;
69  import javax.servlet.ServletException;
70  import javax.servlet.http.HttpServletRequest;
71  import javax.servlet.http.HttpServletResponse;
72  import org.apache.catalina.Context;
73  
74  import org.apache.catalina.Container;
75  import org.apache.catalina.Host;
76  import org.apache.catalina.Deployer;
77  import org.talika.tms.Constants;
78  
79  /**
80   * Servlet that enables remote management of the web applications installed
81   * within the same virtual host as this web application is.  Normally, this
82   * functionality will be protected by a security constraint in the web
83   * application deployment descriptor.  However, this requirement can be
84   * relaxed during testing.
85   * <p>
86   * The difference between this <code>ManagerServlet</code> and this
87   * Servlet is that this Servlet prints out a HTML interface which
88   * makes it easier to administrate.
89   * <p>
90   * However if you use a software that parses the output of
91   * <code>ManagerServlet</code you won't be able to upgrade
92   * to this Servlet since the output are not in the
93   * same format ar from <code>ManagerServlet</code>
94   *
95   * @author Bip Thelin
96   * @author Jose M. Palomar
97   * @version $Revision: 175 $, $Date: 2004-07-31 11:40:36 +0200 (sáb 31 de jul de 2004) $
98   * @see ManagerServlet
99   */
100 
101 public final class HTMLManagerXServlet extends ManagerXServlet {
102 
103     // --------------------------------------------------------- Public Methods
104 
105     /**
106      * Process a GET request for the specified resource.
107      *
108      * @param request The servlet request we are processing
109      * @param response The servlet response we are creating
110      *
111      * @exception IOException if an input/output error occurs
112      * @exception ServletException if a servlet-specified error occurs
113      */
114     public void doGet(HttpServletRequest request,
115                       HttpServletResponse response)
116         throws IOException, ServletException {
117 
118         // Identify the request parameters that we need
119         String command = request.getPathInfo();
120 
121         String vhost = request.getParameter("vhost");
122         String path = request.getParameter("path");
123         String war = request.getParameter("war");
124 
125         // Prepare our output writer to generate the response message
126         response.setContentType("text/html");
127         PrintWriter writer = response.getWriter();
128 
129         // Process the requested command
130         if (command == null) {
131             response.sendRedirect(request.getRequestURI()+"/vhosts");
132         } else if (command.equals("/vhosts")) {
133             vhosts(writer);
134         } else if (command.equals("/install")) {
135             install(writer, vhost, path, war);
136         } else if (command.equals("/list")) {
137             list(writer, vhost);
138         } else if (command.equals("/reload")) {
139             reload(writer, vhost, path);
140         } else if (command.equals("/remove")) {
141             remove(writer, vhost, path);
142         } else if (command.equals("/sessions")) {
143             sessions(writer, vhost, path);
144         } else if (command.equals("/start")) {
145             start(writer, vhost, path);
146         } else if (command.equals("/stop")) {
147             stop(writer, vhost, path);
148         } else {
149             writer.println(sm.getString("managerServlet.unknownCommand",
150                                         command));
151         }
152 
153         // Finish up the response
154         writer.flush();
155         writer.close();
156     }
157 
158     /**
159      * Render a HTML list of the currently
160      * active virtual hosts.
161      *
162      * @param writer Writer to render to
163      */
164     public void vhosts(PrintWriter writer) {
165 
166         if (debug >= 1)
167             log("list: Listing virtual hosts for engine '" +
168                 engine.getName() + "'");
169 
170         writer.print("<html>\n<head>\n<title>");
171         writer.print("Listed virtual hosts for engine ");
172         writer.print(engine.getName()+"</title>\n</head>\n");
173         writer.print("<body bgcolor=\"#FFFFFF\">\n");
174         writer.print("<table cellspacing=\"0\"");
175         writer.print("cellpadding=\"3\" align=\"center\">\n");
176         writer.print("<tr><td colspan=\"1\"><font size=\"+2\"");
177         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
178         writer.print("<strong>Listed virtual hosts for engine ");
179         writer.print(engine.getName()+"</strong>\n</font></td>\n</tr>\n");
180         writer.print("<tr bgcolor=\"#CCCCCC\">\n");
181         writer.print("<td align=\"left\"><font size=\"+1\"");
182         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
183         writer.print("<strong>Name</strong></font>\n</td>");
184         writer.print("<td align=\"center\"><font size=\"+1\"");
185         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
186         writer.print("<strong>Aliases</strong></font></td>\n");
187         writer.print("<td align=\"right\"><font size=\"+1\"");
188         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
189         writer.print("<strong>Contexts</strong></font></td>\n");
190 
191         Container hosts[] = engine.findChildren();
192         for(int i = 0; i < hosts.length; i++) {
193             
194             String [] aliases = ((Host) hosts[i]).findAliases();
195             String contextPaths[] = ((Deployer) hosts[i]).findDeployedApps();
196             
197             writer.print("<tr bgcolor=\"#FFFFFF\">\n");
198             writer.print("<td align=\"left\"><font size=\"1\"");
199             writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
200             writer.print("<a href=\"list?vhost=" + hosts[i].getName());
201             writer.print("\">" + hosts[i].getName() + "</a></font>\n</td>");
202 
203             writer.print("<td align=\"left\"><font size=\"1\"");
204             writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
205             for(int j = 0; j < aliases.length; j++)
206                 writer.print(aliases[j] + "<br>\n");
207             writer.print("</font>\n</td>");
208 
209             writer.print("<td align=\"left\"><font size=\"1\"");
210             writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
211             for(int j = 0; j < contextPaths.length; j++) {
212                 if(contextPaths[j].equals(""))
213                     writer.print("/<br>\n");
214                 else
215                     writer.print(contextPaths[j] + "<br>\n");
216             }
217             writer.print("</font>\n</td>\n</tr>");
218 
219         }
220 
221         writer.print("<tr><td colspan=\"3\">&nbsp;</td></tr>");
222         writer.print("<tr><td colspan=\"3\" bgcolor=\"#CCCCCC\"><font size=\"-1\" ");
223         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
224         writer.print(Constants.MANAGER_INFO+"</font></td>\n</tr>\n");
225         writer.print("</table>\n</body>\n</html>");
226 
227     }
228     
229     /**
230      * Render a HTML list of the currently
231      * active Contexts in selected virtual host.
232      *
233      * @param writer Writer to render to
234      * @param vhost Virtual host of the application to be listed
235      */
236     public void list(PrintWriter writer, String vhost) {
237 
238         if (debug >= 1)
239             log("list: Listing contexts for virtual host '" +
240                 vhost + "'");
241 
242         if((vhost == null) || (vhost.equals(""))) {
243             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
244             vhosts(writer);
245             return;
246         }
247         Deployer deployer = (Deployer) engine.findChild(vhost);
248         if (deployer == null) {
249             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
250             vhosts(writer);
251             
252             return;                
253         }
254         
255         writer.print("<html>\n<head>\n<title>");
256         writer.print("Listed applications for virtual host ");
257         writer.print(deployer.getName()+"</title>\n</head>\n");
258         writer.print("<body bgcolor=\"#FFFFFF\">\n");
259         writer.print("<form method=\"get\" action=\"install\">");
260         writer.print("<table cellspacing=\"0\"");
261         writer.print("cellpadding=\"3\" align=\"center\">\n");
262         writer.print("<tr><td colspan=\"3\"><font size=\"+2\"");
263         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
264         writer.print("<strong>Listed applications for virtual host ");
265         writer.print(deployer.getName()+"</strong>\n</font></td>\n</tr>\n");
266         writer.print("<tr bgcolor=\"#CCCCCC\">\n");
267         writer.print("<td align=\"left\"><font size=\"+1\"");
268         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
269         writer.print("<strong>Path</strong></font>\n</td>");
270         writer.print("<td align=\"center\"><font size=\"+1\"");
271         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
272         writer.print("<strong>Status</strong></font></td>\n");
273         writer.print("<td align=\"right\"><font size=\"+1\"");
274         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
275         writer.print("<strong>Sessions</strong></font></td>\n");
276         writer.print("<td align=\"right\"><font size=\"+1\"");
277         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
278         writer.print("<strong>Reload</strong></font></td>\n");
279         writer.print("<td align=\"right\"><font size=\"+1\"");
280         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
281         writer.print("<strong>Remove</strong></font></td>\n</tr>\n");
282 
283         String contextPaths[] = deployer.findDeployedApps();
284 
285         for (int i = 0; i < contextPaths.length; i++) {
286             Context context = deployer.findDeployedApp(contextPaths[i]);
287             String displayPath = contextPaths[i];
288             if( displayPath.equals("") )
289                 displayPath = "/";
290             if (context != null ) {
291                 writer.print("<tr bgcolor=\"#FFFFFF\">\n");
292                 writer.print("<td align=\"left\"><font size=\"1\"");
293                 writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
294                 writer.print(displayPath+"</font>\n</td>");
295                 writer.print("<td align=\"center\"><font size=\"1\"");
296                 writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
297 
298                 if (context.getAvailable()) {
299                     writer.print("running / <a href=\"stop?vhost="+vhost+"&path="+displayPath);
300                     writer.print("\">stop</a>");
301                 } else {
302                     writer.print("<a href=\"start?vhost="+vhost+"&path="+displayPath);
303                     writer.print("\">start</a> / stopped");
304                 }
305 
306                 writer.print("</font></td>\n");
307                 writer.print("<td align=\"right\"><font size=\"1\"");
308                 writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
309                 writer.print("<a href=\"sessions?vhost="+vhost+"&path="+displayPath+"\">");
310                 writer.print(context.getManager().findSessions().length);
311                 writer.print("</a></font></td>\n");
312                 writer.print("<td align=\"right\"><font size=\"1\"");
313                 writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
314 
315                 if (context.getAvailable()) {
316                     writer.print("<a href=\"reload?vhost="+vhost+"&path="+displayPath+"\">");
317                     writer.print("Reload &#187;");
318                     writer.print("</a></font></td>\n");
319                 } else {
320                     writer.print("-</font></td>");
321                 }
322 
323                 writer.print("<td align=\"right\"><font size=\"1\"");
324                 writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
325                 writer.print("<a href=\"remove?vhost="+vhost+"&path="+displayPath+"\">");
326                 writer.print("Remove &#187;");
327                 writer.print("</a></font></td>\n</tr>\n");
328             }
329         }
330 
331         writer.print("<tr><td colspan=\"5\">&nbsp;</td></tr>");
332         writer.print("<tr><td>");
333         writer.print("<font size=\"2\"");
334         writer.print(" face=\"Arial, Helvetica, sans-serif\">");
335         writer.print("<b>Install a webapp</b></font></td>\n");
336         writer.print("<td><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">");
337         writer.print("Path:&nbsp;</font>");
338         writer.print("<input type=\"text\" name=\"path\" size=\"25\"></td>");
339         writer.print("<td><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">");
340         writer.print("War-URL:&nbsp;</font>");
341         writer.print("<input type=\"text\" name=\"war\" size=\"25\"></td>");
342         writer.print("<td colspan=\"2\">");
343         writer.print("&nbsp;<input type=\"submit\" value=\"install\"></td></tr>\n");
344         writer.print("<tr><td colspan=\"5\" bgcolor=\"#CCCCCC\"><font size=\"-1\" ");
345         writer.print(" face=\"Arial, Helvetica, sans-serif\">\n");
346         writer.print(Constants.MANAGER_INFO+"</font></td>\n</tr>\n");
347         writer.print("</table>\n</form>\n</body>\n</html>");
348     }
349 
350     /**
351      * Reload the web application at the specified context path.
352      *
353      * @param writer Writer to render to
354      * @param vhost Virtual host of the application to be restarted
355      * @param path Context path of the application to be restarted
356      */
357     protected void reload(PrintWriter writer, String vhost, String path) {
358 
359         if (debug >= 1)
360             log("restart: Reloading web application at '" + vhost + ":" + path + "'");
361 
362         if((vhost == null) || (vhost.equals(""))) {
363             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
364             vhosts(writer);
365             return;
366         }
367         Deployer deployer = (Deployer) engine.findChild(vhost);
368         if (deployer == null) {
369             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
370             vhosts(writer);
371             
372             return;                
373         }
374 
375         if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
376             writer.println(sm.getString("managerServlet.invalidPath", path));
377             list(writer, vhost);
378 
379             return;
380         }
381 
382         String displayPath = path;
383 
384         if( path.equals("/") )
385             path = "";
386 
387         try {
388             Context context = deployer.findDeployedApp(path);
389 
390             if (context == null) {
391                 writer.println(sm.getString("managerServlet.noContext", displayPath));
392                 list(writer, vhost);
393 
394                 return;
395             }
396 
397             context.reload();
398             list(writer, vhost);
399         } catch (Throwable t) {
400             getServletContext().log("ManagerServlet.reload[" + displayPath + "]", t);
401             writer.println(sm.getString("managerServlet.exception",
402                                         t.toString()));
403         }
404     }
405 
406     /**
407      * Remove the web application at the specified context path.
408      *
409      * @param writer Writer to render to
410      * @param vhost Virtual host of the application to be removed
411      * @param path Context path of the application to be removed
412      */
413     protected void remove(PrintWriter writer, String vhost, String path) {
414 
415         if (debug >= 1)
416             log("remove: Removing web application at '" + vhost + ":" + path + "'");
417 
418         if((vhost == null) || (vhost.equals(""))) {
419             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
420             vhosts(writer);
421             return;
422         }
423         Deployer deployer = (Deployer) engine.findChild(vhost);
424         if (deployer == null) {
425             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
426             vhosts(writer);
427             
428             return;                
429         }
430 
431         if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
432             writer.println(sm.getString("managerServlet.invalidPath", path));
433             list(writer, vhost);
434 
435             return;
436         }
437 
438         String displayPath = path;
439 
440         if( path.equals("/") )
441             path = "";
442 
443         try {
444             Context context = deployer.findDeployedApp(path);
445 
446             if (context == null) {
447                 writer.println(sm.getString("managerServlet.noContext", displayPath));
448                 list(writer, vhost);
449 
450                 return;
451             }
452 
453             deployer.remove(path);
454             list(writer, vhost);
455         } catch (Throwable t) {
456             getServletContext().log("ManagerServlet.remove[" + displayPath + "]",
457                                     t);
458             writer.println(sm.getString("managerServlet.exception",
459                                         t.toString()));
460         }
461     }
462 
463     /**
464      * Start the web application at the specified context path.
465      *
466      * @param writer Writer to render to
467      * @param vhost Virtual host of the application to be started
468      * @param path Context path of the application to be started
469      */
470     public void start(PrintWriter writer, String vhost, String path) {
471 
472         if (debug >= 1)
473             log("start: Starting web application at '" + vhost + ":" + path + "'");
474 
475         if((vhost == null) || (vhost.equals(""))) {
476             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
477             vhosts(writer);
478             return;
479         }
480         Deployer deployer = (Deployer) engine.findChild(vhost);
481         if (deployer == null) {
482             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
483             vhosts(writer);
484             
485             return;                
486         }
487 
488         if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
489             writer.println(sm.getString("managerServlet.invalidPath", path));
490             list(writer, vhost);
491 
492             return;
493         }
494 
495         String displayPath = path;
496 
497         if( path.equals("/") )
498             path = "";
499 
500         try {
501             Context context = deployer.findDeployedApp(path);
502 
503             if (context == null) {
504                 writer.println(sm.getString("managerServlet.noContext", displayPath));
505                 list(writer, vhost);
506 
507                 return;
508             }
509 
510             deployer.start(path);
511             list(writer, vhost);
512         } catch (Throwable t) {
513             getServletContext().log("ManagerServlet.start[" + displayPath + "]",
514                                     t);
515             writer.println(sm.getString("managerServlet.exception",
516                                         t.toString()));
517         }
518     }
519 
520     /**
521      * Stop the web application at the specified context path.
522      *
523      * @param writer Writer to render to
524      * @param vhost Virtual host of the application to be stopped
525      * @param path Context path of the application to be stopped
526      */
527     protected void stop(PrintWriter writer, String vhost, String path) {
528 
529         if (debug >= 1)
530             log("stop: Stopping web application at '" + vhost + ":" + path + "'");
531 
532         if((vhost == null) || (vhost.equals(""))) {
533             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
534             vhosts(writer);
535             return;
536         }
537         Deployer deployer = (Deployer) engine.findChild(vhost);
538         if (deployer == null) {
539             writer.println(sm.getString("managerServlet.invalidVirtualHost", vhost));
540             vhosts(writer);
541             
542             return;                
543         }
544 
545         if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
546             writer.println(sm.getString("managerServlet.invalidPath", path));
547             list(writer, vhost);
548 
549             return;
550         }
551 
552         String displayPath = path;
553 
554         if( path.equals("/") )
555             path = "";
556 
557         try {
558             Context context = deployer.findDeployedApp(path);
559 
560             if (context == null) {
561                 writer.println(sm.getString("managerServlet.noContext", displayPath));
562                 list(writer, vhost);
563 
564                 return;
565             }
566 
567             deployer.stop(path);
568             list(writer, vhost);
569         } catch (Throwable t) {
570             getServletContext().log("ManagerServlet.stop[" + displayPath + "]",
571                                     t);
572             writer.println(sm.getString("managerServlet.exception",
573                                         t.toString()));
574         }
575     }
576 }