<document>
<header>
<product>resin</product>
<title>Manual web-app restart</title>
<description>
<p>
Start and stop web-apps when called by an admin servlet.
</p>
</description>
</header>

<body>
<summary/>

<section title="resin.conf">

<p>Starts any .war files in the webapps directory automatically, but only
restarts on a JMX call.</p>

<example title="resin.conf">
...
&lt;host id="">
  &lt;web-app-deploy path="webapps">
    &lt;startup-mode>automatic&lt;startup-mode>
    &lt;redeploy-mode>manual&lt;redeploy-mode>

    ...
  &lt;/web-app-deploy>
</example>

</section>

<section title="Admin web.xml">

<p>The /admin web-app configures the restart servlet and
protects itself with basic authentication, using the XmlAuthenticator.</p>

<p>See the <a href="security|digest.xtp">digest</a> document for
information on generating the password.</p>

<example title="web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin">
  &lt;servlet servlet-name="restart"
           servlet-class="example.RestartServlet">
  &lt;/servlet>

  &lt;servlet-mapping url-pattern="/restart"  servlet-name="restart"/>

  &lt;!-- protect with basic auth. -->
  &lt;authenticator>
    &lt;type>com.caucho.server.security.XmlAuthenticator&lt;/type>
    &lt;init user="aladdin:Xmasdf80N3m:user"/>
  &lt;/authenticator>

  &lt;security-constraint url-pattern="/*" role-name="user"/>

  &lt;login-config auth-method='basic'/>
&lt;/web-app>
</example>

</section>

<section title="Restart Servlet">

<example title="example/RestartServlet.java">
package example;

import java.io.PrintWriter;
import java.io.IOException;

import java.util.logging.Logger;
import java.util.logging.Level;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ObjectInstance;
import javax.management.MBeanServerInvocationHandler;

import javax.naming.InitialContext;
import javax.naming.Context;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.caucho.server.webapp.mbean.WebAppMBean;

public class RestartServlet extends HttpServlet {
  private static final Logger log
    = Logger.getLogger(RestartServlet.class.getName());

  private MBeanServer _mbeanServer;

  public void setMBeanServer(MBeanServer mbeanServer)
  {
    _mbeanServer = mbeanServer;
  }

  public void init()
    throws ServletException
  {
    try {
      if (_mbeanServer == null) {
        Context ic = new InitialContext();

	String jndiName = "java:comp/env/jmx/GlobalMBeanServer";

        _mbeanServer = (MBeanServer) ic.lookup(jndiName);
      }
    } catch (Exception e) {
      throw new ServletException(e);
    }
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
    throws IOException, ServletException
  {
    PrintWriter out = response.getWriter();

    try {
      String webAppName = request.getParameter("webapp");

      String action = request.getParameter("action");

      WebAppMBean webApp = findWebApp(webAppName);

      if (webApp == null) {
        out.println("Can't find web-app " + webAppName);
        return;
      }

     if ("start".equals(action)) {
        webApp.start();
        out.println("started " + webAppName);
      }
      else if ("stop".equals(action)) {
        webApp.stop();
        out.println("stopped " + webAppName);
      }
      else if ("update".equals(action)) {
        webApp.update();
        out.println("updated " + webAppName);
      }
      else
        out.println(action + " is an unknown action.");
    } catch (Exception e) {
      throw new ServletException(e);
    }
  }

  private WebAppMBean findWebApp(String webAppName)
  {
    try {
      String name = ("resin:" +
                     "Server=default," +
                     "Host=default," +
                     "type=WebApp," +
                     "name=" + webAppName);

      ObjectName objectName = new ObjectName(name);

      ObjectInstance object = _mbeanServer.getObjectInstance(objectName);

      if (object == null)
	return null;

      WebAppMBean webApp;

      webApp = (WebAppMBean)
	MBeanServerInvocationHandler.newProxyInstance(_mbeanServer,
                                                      objectName,
                                                      WebAppMBean.class,
                                                      false);

      return webApp;
    } catch (Throwable e) {
      log.log(Level.WARNING, e.toString(), e);

      return null;
    }
  }
}
</example>

</section>

  </body>
</document>
