avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pro...@apache.org
Subject cvs commit: avalon-sandbox/sevak/src/java/org/apache/avalon/apps/sevak/blocks/jetty WebApplicationContextHolder.java JettySevak.java
Date Tue, 19 Aug 2003 14:55:49 GMT
proyal      2003/08/19 07:55:49

  Modified:    sevak/src/java/org/apache/avalon/apps/sevak/blocks/jetty
                        JettySevak.java
  Added:       sevak/src/java/org/apache/avalon/apps/sevak/blocks/jetty
                        WebApplicationContextHolder.java
  Log:
  * Factor out Server creation so component subclasses can customize it as-needed
  * Add Phoenix MXINFO tags to support webapp stop/start/reload. (Cannot be done
    with Jetty's support as a reload would lose the Avalon lifecycle on the Servlet)
  
  Revision  Changes    Path
  1.22      +220 -36   avalon-sandbox/sevak/src/java/org/apache/avalon/apps/sevak/blocks/jetty/JettySevak.java
  
  Index: JettySevak.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/sevak/src/java/org/apache/avalon/apps/sevak/blocks/jetty/JettySevak.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- JettySevak.java	11 Apr 2003 00:29:11 -0000	1.21
  +++ JettySevak.java	19 Aug 2003 14:55:49 -0000	1.22
  @@ -51,6 +51,10 @@
   
   import java.io.File;
   import java.util.HashMap;
  +import java.util.Set;
  +import java.util.Collections;
  +import java.net.UnknownHostException;
  +
   import org.apache.avalon.apps.sevak.Sevak;
   import org.apache.avalon.apps.sevak.SevakContext;
   import org.apache.avalon.apps.sevak.SevakException;
  @@ -67,15 +71,16 @@
   import org.apache.avalon.framework.service.ServiceException;
   import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.avalon.framework.service.Serviceable;
  +
   import org.mortbay.http.SocketListener;
   import org.mortbay.jetty.Server;
  -import org.mortbay.jetty.servlet.WebApplicationContext;
   import org.mortbay.util.Log;
   import org.mortbay.util.MultiException;
   
   /**
    * @phoenix:block
    * @phoenix:service name="org.apache.avalon.apps.sevak.Sevak"
  + * @phoenix:mx-topic name="ServletContainer"
    *
    * Jetty Wrapper.
    *
  @@ -84,18 +89,18 @@
    *
    * @author  Paul Hammant
    * @author  Ulrich Mayring
  + * @author  Peter Royal
    * @version 1.0
    */
   public class JettySevak extends AbstractLogEnabled
       implements Sevak, Startable, Contextualizable, Configurable, Initializable, Serviceable
   {
  -
       private Server m_server;
   
       /** Virtual host to bind the Jetty to.  null implies all hosts are in context. */
       private String m_hostName;
   
  -    private HashMap m_webapps = new HashMap();
  +    private HashMap m_webcontexts = new HashMap();
       private int m_port;
       private int m_minThreads;
       private int m_maxThreads;
  @@ -152,7 +157,25 @@
        */
       public void initialize() throws Exception
       {
  -        m_server = new Server();
  +        m_server = createHttpServer();
  +        m_server.addListener( createSocketListener() );
  +
  +        PhoenixLogSink phoenixLogSink = new PhoenixLogSink();
  +        phoenixLogSink.enableLogging( getLogger() );
  +        Log.instance().add( phoenixLogSink );
  +
  +        RequestLogger logger = (RequestLogger)
  +            m_sevakContext.getServiceManager().lookup( RequestLogger.ROLE );
  +        m_server.setRequestLog( new JettyRequestLogAdapter( logger ) );
  +    }
  +
  +    protected Server createHttpServer()
  +    {
  +        return new Server();
  +    }
  +
  +    private SocketListener createSocketListener() throws UnknownHostException
  +    {
           SocketListener listener = new SocketListener();
   
           if( null != m_hostName )
  @@ -163,14 +186,7 @@
           listener.setPort( m_port );
           listener.setMinThreads( m_minThreads );
           listener.setMaxThreads( m_maxThreads );
  -        m_server.addListener( listener );
  -        PhoenixLogSink phoenixLogSink = new PhoenixLogSink();
  -        phoenixLogSink.enableLogging( getLogger() );
  -        Log.instance().add( phoenixLogSink );
  -
  -        RequestLogger logger = (RequestLogger)
  -            m_sevakContext.getServiceManager().lookup( RequestLogger.ROLE );
  -        m_server.setRequestLog( new JettyRequestLogAdapter( logger ) );
  +        return listener;
       }
   
       /**
  @@ -218,63 +234,231 @@
        * Deploy a webapp
        * @param context the contxct for the webapp
        * @param pathToWebAppFolder the path to it
  -     * @param avalonContext The optional context to apply to servlets (LogEnabled, Serviceable).
  +     * @param sevakContext The optional context to apply to servlets (LogEnabled, Serviceable).
        * @throws SevakException if a problem
        */
       public void deploy( String context, File pathToWebAppFolder, SevakContext sevakContext
)
           throws SevakException
       {
  -        String webAppURL = null;
  +        if( m_webcontexts.containsKey( context ) )
  +        {
  +            throw new SevakException( "Context '" + context + "' has already been deployed"
);
  +        }
  +
  +        WebApplicationContextHolder holder;
   
           try
           {
  -            webAppURL = pathToWebAppFolder.toURL().toString();
  -            // This still does not work.
  +            holder = new WebApplicationContextHolder( context,
  +                                                      pathToWebAppFolder,
  +                                                      sevakContext,
  +                                                      m_sarRootDir,
  +                                                      m_extractWebArchive );
  +            m_webcontexts.put( context, holder );
  +        }
  +        catch( Exception e )
  +        {
  +            final String msg = "Problem deploying web application (" + pathToWebAppFolder
  +                + ") in Jetty";
  +
  +            throw new SevakException( msg, e );
  +        }
   
  -            WebApplicationContext ctx =
  -                new SevakWebApplicationContext( sevakContext, m_sarRootDir, webAppURL );
  -            ctx.setContextPath( context );
  -            m_server.addContext( m_hostName, ctx );
  +        deploy( context );
  +    }
  +
  +    /**
  +     * Get a list of all webapps currently installed with the container
  +     *
  +     * @phoenix:mx-attribute
  +     *
  +     * @return The list of all contexts installed in the container
  +     */
  +    public Set getContextList()
  +    {
  +        return Collections.unmodifiableSet( m_webcontexts.keySet() );
  +    }
  +
  +    /**
  +     * Get the status of an installed webapp
  +     *
  +     * @phoenix:mx-operation
  +     *
  +     * @param context webapp to get status of
  +     * @return status of webapp
  +     * @throws SevakException if any problems occur
  +     */
  +    public String getStatus( String context ) throws SevakException
  +    {
  +        final WebApplicationContextHolder holder = getWebApplicationContextHolder( context
);
  +
  +        return holder.getStatus();
  +    }
  +
  +    /**
  +     * Start a stopped webapp
  +     *
  +     * @phoenix:mx-operation
  +     *
  +     * @param context webapp to start
  +     * @throws SevakException if any problems occur
  +     */
  +    public void start( String context ) throws SevakException
  +    {
  +        final WebApplicationContextHolder holder = getWebApplicationContextHolder( context
);
  +
  +        try
  +        {
  +            holder.start();
  +        }
  +        catch( Exception e )
  +        {
  +            final String msg = "Unable to start '" + context + "' : " + e.getMessage();
  +            getLogger().error( msg, e );
  +            throw new SevakException( msg, e );
  +        }
  +    }
  +
  +    /**
  +     * Stop a running webapp
  +     *
  +     * @phoenix:mx-operation
  +     *
  +     * @param context webapp to stop
  +     * @throws SevakException if any problems occur
  +     */
  +    public void stop( String context ) throws SevakException
  +    {
  +        final WebApplicationContextHolder holder = getWebApplicationContextHolder( context
);
  +
  +        try
  +        {
  +            holder.stop();
  +        }
  +        catch( Exception e )
  +        {
  +            final String msg = "Unable to stop '" + context + "' : " + e.getMessage();
  +            getLogger().error( msg, e );
  +            throw new SevakException( msg, e );
  +        }
  +    }
  +
  +    /**
  +     * Redeploy a webapp. This operation fully reloads the webapp, and is equivalent to
  +     * doing undeploy() followed by deploy()
  +     *
  +     * @phoenix:mx-operation
  +     *
  +     * @param context webapp to reload
  +     * @throws SevakException if any problems occur
  +     */
  +    public void redeploy( String context ) throws SevakException
  +    {
  +        try
  +        {
  +            undeploy( context );
  +            deploy( context );
  +        }
  +        catch( SevakException e )
  +        {
  +            getLogger().error( "Exception restarting: " + context, e );
  +
  +            throw e;
  +        }
  +    }
  +
  +    /**
  +     * Deploy a webapp
  +     *
  +     * @phoenix:mx-operation
  +     *
  +     * @param context webapp to deploy
  +     * @throws SevakException if any problems occur
  +     */
  +    public void deploy( String context ) throws SevakException
  +    {
  +        final WebApplicationContextHolder holder = getWebApplicationContextHolder( context
);
  +
  +        //Set the context classloader because the current classloader will be that of the
  +        Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
  +
  +        try
  +        {
  +            m_server.addContext( m_hostName, holder.create() );
   
               if( getLogger().isInfoEnabled() )
  -                getLogger().info( "deploying context=" + context + ", webapp=" + webAppURL
  -                                  + " to host=" + ( m_hostName == null ? "(All Hosts)"
: m_hostName ) );
  +                getLogger().info( "deploying context=" + context + ", webapp="
  +                                  + holder.getWebappUrl() + " to host="
  +                                  + ( m_hostName == null ? "(All Hosts)" : m_hostName )
);
   
  -            ctx.setExtractWAR( m_extractWebArchive );
  -            m_webapps.put( context, ctx );
  -            ctx.start();
  +            holder.start();
           }
           catch( Exception e )
           {
  -            final String msg = "Problem deploying web application (" + webAppURL + ") in
Jetty";
  +            final String msg = "Unable to deploy '" + context + "' : " + e.getMessage();
   
  +            getLogger().error( msg, e );
               throw new SevakException( msg, e );
           }
       }
   
  +    private WebApplicationContextHolder getWebApplicationContextHolder( String context
)
  +        throws SevakException
  +    {
  +        WebApplicationContextHolder holder =
  +            (WebApplicationContextHolder)m_webcontexts.get( context );
  +
  +        if( null == holder )
  +        {
  +            throw new SevakException( "Unknown context: " + context );
  +        }
  +
  +        return holder;
  +    }
  +
       /**
  -     * Undeploy a webapp.
  -     * @param context the context
  -     * @throws SevakException if a problem
  +     * Start a stopped webapp
  +     *
  +     * @phoenix:mx-operation
  +     *
  +     * @param context webapp to start
  +     * @throws SevakException if any problems occur
        */
       public void undeploy( String context ) throws SevakException
       {
  -        WebApplicationContext ctx = (WebApplicationContext)m_webapps.get( context );
  +        final WebApplicationContextHolder holder = getWebApplicationContextHolder( context
);
   
           try
           {
  -            ctx.stop();
  +            holder.stop();
           }
           catch( InterruptedException e )
           {
  -            throw new SevakException( "Problem stopping web application in Jetty", e );
  +            final String msg = "Problem stopping web application in Jetty";
  +
  +            getLogger().error( msg, e );
  +
  +            throw new SevakException( msg, e );
           }
   
  -        m_server.removeContext( ctx );
  -        ctx.destroy();
  -        m_webapps.remove( context );
  -    }
  +        if( !m_server.removeContext( holder.getWebApplicationContext() ) )
  +        {
  +            getLogger().warn( "Potential problems removing context" );
  +        }
  +
  +        try
  +        {
  +            holder.destroy();
  +        }
  +        catch( Exception e )
  +        {
  +            final String msg = "Problem destroying web application in Jetty";
   
  +            getLogger().error( msg, e );
  +
  +            throw new SevakException( msg, e );
  +        }
  +    }
   }
   
   
  
  
  
  1.1                  avalon-sandbox/sevak/src/java/org/apache/avalon/apps/sevak/blocks/jetty/WebApplicationContextHolder.java
  
  Index: WebApplicationContextHolder.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 2002,2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
      must not be used to endorse or promote products derived from this  software
      without  prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.avalon.apps.sevak.blocks.jetty;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.MalformedURLException;
  
  import org.apache.avalon.apps.sevak.SevakContext;
  
  import org.mortbay.jetty.servlet.WebApplicationContext;
  
  /**
   * Class to hold a WebApplicationContext in Jetty
   *
   * @author <a href="proyal@apache.org">peter royal</a>
   */
  class WebApplicationContextHolder
  {
      private final String m_context;
      private final String m_webappUrl;
      private final SevakContext m_sevakContext;
      private final File m_rootDirectory;
      private boolean m_extractWebArchive;
  
      private WebApplicationContext m_webApplicationContext;
  
      public WebApplicationContextHolder( String context,
                                    File pathToWebAppFolder,
                                    SevakContext sevakContext,
                                    File rootDirectory,
                                    boolean extractWebArchive )
          throws MalformedURLException
      {
          m_context = context;
          m_webappUrl = pathToWebAppFolder.toURL().toString();
          m_sevakContext = sevakContext;
          m_rootDirectory = rootDirectory;
          m_extractWebArchive = extractWebArchive;
      }
  
      String getWebappUrl()
      {
          return m_webappUrl;
      }
  
      String getContext()
      {
          return m_context;
      }
  
      WebApplicationContext getWebApplicationContext()
      {
          return m_webApplicationContext;
      }
  
      String getStatus()
      {
          if( null == m_webApplicationContext )
          {
              return "Ready to deploy";
          }
          else if( m_webApplicationContext.isStarted() )
          {
              return "Running";
          }
          else
          {
              return "Stopped";
          }
      }
  
      WebApplicationContext create() throws IOException
      {
          if( null != m_webApplicationContext )
          {
              throw new IllegalStateException( "context already exists" );
          }
  
          m_webApplicationContext =
              new SevakWebApplicationContext( m_sevakContext, m_rootDirectory, m_webappUrl
);
          m_webApplicationContext.setContextPath( m_context );
          m_webApplicationContext.setExtractWAR( m_extractWebArchive );
  
          return m_webApplicationContext;
      }
  
      void start() throws Exception
      {
          if( m_webApplicationContext == null )
          {
              throw new IllegalStateException( "haven't been created");
          }
          else if ( m_webApplicationContext.isStarted() )
          {
              throw new IllegalStateException( "already started" );
          }
  
          m_webApplicationContext.start();
      }
  
      void stop() throws InterruptedException
      {
          if( m_webApplicationContext == null || !m_webApplicationContext.isStarted() )
          {
              throw new IllegalStateException( "not started");
          }
  
          m_webApplicationContext.stop();
      }
  
      void destroy()
      {
          if( m_webApplicationContext == null )
          {
              throw new IllegalStateException( "already destroyed");
          }
          else if( m_webApplicationContext.isStarted() )
          {
              throw new IllegalStateException( "must stop before destroying ");
          }
  
          m_webApplicationContext.destroy();
          m_webApplicationContext = null;
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org


Mime
View raw message