Author: markt
Date: Fri Jan 28 21:04:55 2011
New Revision: 1064881

URL: http://svn.apache.org/viewvc?rev=1064881&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50679
Update the FarmWarDeployer to support parallel deployment. This deliberately 
breaks the API since the meaning of a number of method parameters has changed 
(context path -> context name).

Modified:
    tomcat/trunk/java/org/apache/catalina/ha/ClusterDeployer.java
    tomcat/trunk/java/org/apache/catalina/ha/deploy/FarmWarDeployer.java
    tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessage.java
    tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessageFactory.java
    tomcat/trunk/java/org/apache/catalina/ha/deploy/UndeployMessage.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/ha/ClusterDeployer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/ClusterDeployer.java?rev=1064881&r1=1064880&r2=1064881&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ha/ClusterDeployer.java (original)
+++ tomcat/trunk/java/org/apache/catalina/ha/ClusterDeployer.java Fri Jan 28 
21:04:55 2011
@@ -24,8 +24,8 @@ package org.apache.catalina.ha;
  * @author Filip Hanik
  * @version $Id$
  */
+import java.io.File;
 import java.io.IOException;
-import java.net.URL;
 
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.tribes.ChannelListener;
@@ -48,59 +48,48 @@ public interface ClusterDeployer extends
     public void stop() throws LifecycleException;
 
     /**
-     * Sets the deployer for this cluster deployer to use.
-     * @param deployer Deployer
-     */
-    // FIXME
-    //public void setDeployer(Deployer deployer);
-
-    /**
      * Install a new web application, whose web application archive is at the
      * specified URL, into this container and all the other
-     * members of the cluster with the specified context path.
-     * A context path of "" (the empty string) should be used for the root
-     * application for this container.  Otherwise, the context path must
-     * start with a slash.
+     * members of the cluster with the specified context name.
      * <p>
      * If this application is successfully installed locally, 
      * a ContainerEvent of type
      * <code>INSTALL_EVENT</code> will be sent to all registered listeners,
      * with the newly created <code>Context</code> as an argument.
      *
-     * @param contextPath The context path to which this application should
+     * @param contextName The context name to which this application should
      *  be installed (must be unique)
-     * @param war A URL of type "jar:" that points to a WAR file, or type
-     *  "file:" that points to an unpacked directory structure containing
-     *  the web application to be installed
+     * @param wepapp    A WAR file or unpacked directory structure containing
+     *                  the web application to be installed
      *
-     * @exception IllegalArgumentException if the specified context path
-     *  is malformed (it must be "" or start with a slash)
-     * @exception IllegalStateException if the specified context path
+     * @exception IllegalArgumentException if the specified context name
+     *  is malformed
+     * @exception IllegalStateException if the specified context name
      *  is already attached to an existing web application
      * @exception IOException if an input/output error was encountered
      *  during installation
      */
-    public void install(String contextPath, URL war) throws IOException;
+    public void install(String contextName, File webapp) throws IOException;
 
     /**
      * Remove an existing web application, attached to the specified context
-     * path.  If this application is successfully removed, a
+     * name.  If this application is successfully removed, a
      * ContainerEvent of type <code>REMOVE_EVENT</code> will be sent to all
      * registered listeners, with the removed <code>Context</code> as
      * an argument. Deletes the web application war file and/or directory
      * if they exist in the Host's appBase.
      *
-     * @param contextPath The context path of the application to be removed
+     * @param contextName The context name of the application to be removed
      * @param undeploy boolean flag to remove web application from server
      *
-     * @exception IllegalArgumentException if the specified context path
-     *  is malformed (it must be "" or start with a slash)
-     * @exception IllegalArgumentException if the specified context path does
+     * @exception IllegalArgumentException if the specified context name
+     *  is malformed
+     * @exception IllegalArgumentException if the specified context name does
      *  not identify a currently installed web application
      * @exception IOException if an input/output error occurs during
      *  removal
      */
-    public void remove(String contextPath, boolean undeploy) throws 
IOException;
+    public void remove(String contextName, boolean undeploy) throws 
IOException;
 
     /**
      * call from container Background Process

Modified: tomcat/trunk/java/org/apache/catalina/ha/deploy/FarmWarDeployer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/deploy/FarmWarDeployer.java?rev=1064881&r1=1064880&r2=1064881&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ha/deploy/FarmWarDeployer.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/ha/deploy/FarmWarDeployer.java Fri 
Jan 28 21:04:55 2011
@@ -19,7 +19,6 @@ package org.apache.catalina.ha.deploy;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.URL;
 import java.util.HashMap;
 
 import javax.management.MBeanServer;
@@ -35,6 +34,7 @@ import org.apache.catalina.ha.ClusterDep
 import org.apache.catalina.ha.ClusterListener;
 import org.apache.catalina.ha.ClusterMessage;
 import org.apache.catalina.tribes.Member;
+import org.apache.catalina.util.ContextName;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.modeler.Registry;
@@ -44,7 +44,7 @@ import org.apache.tomcat.util.res.String
 /**
  * <p>
  * A farm war deployer is a class that is able to deploy/undeploy web
- * applications in WAR form within the cluster.
+ * applications in WAR from within the cluster.
  * </p>
  * Any host can act as the admin, and will have three directories
  * <ul>
@@ -233,7 +233,7 @@ public class FarmWarDeployer extends Clu
                 FileMessage fmsg = (FileMessage) msg;
                 if (log.isDebugEnabled())
                     log.debug(sm.getString("farmWarDeployer.msgRxDeploy",
-                            fmsg.getContextPath(), fmsg.getFileName()));
+                            fmsg.getContextName(), fmsg.getFileName()));
                 FileMessageFactory factory = getFactory(fmsg);
                 // TODO correct second try after app is in service!
                 if (factory.writeMessage(fmsg)) {
@@ -243,27 +243,28 @@ public class FarmWarDeployer extends Clu
                         name = name + ".war";
                     File deployable = new File(getDeployDir(), name);
                     try {
-                        String path = fmsg.getContextPath();
-                        if (!isServiced(path)) {
-                            addServiced(path);
+                        String contextName = fmsg.getContextName();
+                        if (!isServiced(contextName)) {
+                            addServiced(contextName);
                             try {
-                                remove(path);
+                                remove(contextName);
                                 if (!factory.getFile().renameTo(deployable)) {
                                     log.error(sm.getString(
                                             "farmWarDeployer.renameFail",
                                             factory.getFile(), deployable));
                                 }
-                                check(path);
+                                check(contextName);
                             } finally {
-                                removeServiced(path);
+                                removeServiced(contextName);
                             }
                             if (log.isDebugEnabled())
                                 log.debug(sm.getString(
-                                        "farmWarDeployer.deployEnd", path));
+                                        "farmWarDeployer.deployEnd",
+                                        contextName));
                         } else
                             log.error(sm.getString(
-                                    "farmWarDeployer.servicingDeploy", path,
-                                    name));
+                                    "farmWarDeployer.servicingDeploy",
+                                    contextName, name));
                     } catch (Exception ex) {
                         log.error(ex);
                     } finally {
@@ -273,23 +274,25 @@ public class FarmWarDeployer extends Clu
             } else if (msg instanceof UndeployMessage) {
                 try {
                     UndeployMessage umsg = (UndeployMessage) msg;
-                    String path = umsg.getContextPath();
+                    String contextName = umsg.getContextName();
                     if (log.isDebugEnabled())
                         log.debug(sm.getString("farmWarDeployer.msgRxUndeploy",
-                                path));
-                    if (!isServiced(path)) {
-                        addServiced(path);
+                                contextName));
+                    if (!isServiced(contextName)) {
+                        addServiced(contextName);
                         try {
-                            remove(path);
+                            remove(contextName);
                         } finally {
-                            removeServiced(path);
+                            removeServiced(contextName);
                         }
                         if (log.isDebugEnabled())
                             log.debug(sm.getString(
-                                    "farmWarDeployer.undeployEnd", path));
+                                    "farmWarDeployer.undeployEnd",
+                                    contextName));
                     } else
                         log.error(sm.getString(
-                                "farmWarDeployer.servicingUneploy", path));
+                                "farmWarDeployer.servicingUneploy",
+                                contextName));
                 } catch (Exception ex) {
                     log.error(ex);
                 }
@@ -309,8 +312,7 @@ public class FarmWarDeployer extends Clu
      */
     public synchronized FileMessageFactory getFactory(FileMessage msg)
             throws java.io.FileNotFoundException, java.io.IOException {
-        File tmpFile = new File(msg.getFileName());
-        File writeToFile = new File(getTempDir(), tmpFile.getName());
+        File writeToFile = new File(getTempDir(), msg.getFileName());
         FileMessageFactory factory = fileFactories.get(msg.getFileName());
         if (factory == null) {
             factory = FileMessageFactory.getInstance(writeToFile, true);
@@ -347,109 +349,103 @@ public class FarmWarDeployer extends Clu
     /**
      * Install a new web application, whose web application archive is at the
      * specified URL, into this container and all the other members of the
-     * cluster with the specified context path. A context path of "" (the empty
-     * string) should be used for the root application for this container.
-     * Otherwise, the context path must start with a slash.
+     * cluster with the specified context name.
      * <p>
      * If this application is successfully installed locally, a ContainerEvent
      * of type <code>INSTALL_EVENT</code> will be sent to all registered
      * listeners, with the newly created <code>Context</code> as an argument.
      * 
-     * @param contextPath
-     *            The context path to which this application should be 
installed
+     * @param contextName
+     *            The context name to which this application should be 
installed
      *            (must be unique)
-     * @param war
-     *            A URL of type "jar:" that points to a WAR file, or type
-     *            "file:" that points to an unpacked directory structure
-     *            containing the web application to be installed
+     * @param webapp
+     *            A WAR file or unpacked directory structure containing the web
+     *            application to be installed
      * 
      * @exception IllegalArgumentException
-     *                if the specified context path is malformed (it must be ""
-     *                or start with a slash)
+     *                if the specified context name is malformed
      * @exception IllegalStateException
-     *                if the specified context path is already attached to an
-     *                existing web application
+     *                if the specified context name is already deployed
      * @exception IOException
      *                if an input/output error was encountered during
      *                installation
      */
     @Override
-    public void install(String contextPath, URL war) throws IOException {
+    public void install(String contextName, File webapp) throws IOException {
         Member[] members = getCluster().getMembers();
         Member localMember = getCluster().getLocalMember();
-        FileMessageFactory factory = FileMessageFactory.getInstance(new File(
-                war.getFile()), false);
-        FileMessage msg = new FileMessage(localMember, war.getFile(),
-                contextPath);
+        FileMessageFactory factory =
+            FileMessageFactory.getInstance(webapp, false);
+        FileMessage msg = new FileMessage(localMember, webapp.getName(),
+                contextName);
         if(log.isDebugEnabled())
-            log.debug(sm.getString("farmWarDeployer.sendStart", contextPath,
-                    war));
+            log.debug(sm.getString("farmWarDeployer.sendStart", contextName,
+                    webapp));
         msg = factory.readMessage(msg);
         while (msg != null) {
             for (int i = 0; i < members.length; i++) {
                 if (log.isDebugEnabled())
                     log.debug(sm.getString("farmWarDeployer.sendFragment",
-                            contextPath, war, members[i]));
+                            contextName, webapp, members[i]));
                 getCluster().send(msg, members[i]);
             }
             msg = factory.readMessage(msg);
         }
         if(log.isDebugEnabled())
             log.debug(sm.getString(
-                    "farmWarDeployer.sendEnd", contextPath, war));
+                    "farmWarDeployer.sendEnd", contextName, webapp));
     }
 
     /**
      * Remove an existing web application, attached to the specified context
-     * path. If this application is successfully removed, a ContainerEvent of
+     * name. If this application is successfully removed, a ContainerEvent of
      * type <code>REMOVE_EVENT</code> will be sent to all registered
      * listeners, with the removed <code>Context</code> as an argument.
      * Deletes the web application war file and/or directory if they exist in
      * the Host's appBase.
      * 
-     * @param contextPath
-     *            The context path of the application to be removed
+     * @param contextName
+     *            The context name of the application to be removed
      * @param undeploy
      *            boolean flag to remove web application from server
      * 
      * @exception IllegalArgumentException
-     *                if the specified context path is malformed (it must be ""
-     *                or start with a slash)
+     *                if the specified context name is malformed
      * @exception IllegalArgumentException
-     *                if the specified context path does not identify a
+     *                if the specified context name does not identify a
      *                currently installed web application
      * @exception IOException
      *                if an input/output error occurs during removal
      */
     @Override
-    public void remove(String contextPath, boolean undeploy)
+    public void remove(String contextName, boolean undeploy)
             throws IOException {
         if (log.isInfoEnabled())
-            log.info(sm.getString("farmWarDeployer.removeStart", contextPath));
+            log.info(sm.getString("farmWarDeployer.removeStart", contextName));
         Member localMember = getCluster().getLocalMember();
         UndeployMessage msg = new UndeployMessage(localMember, System
-                .currentTimeMillis(), "Undeploy:" + contextPath + ":"
-                + System.currentTimeMillis(), contextPath, undeploy);
+                .currentTimeMillis(), "Undeploy:" + contextName + ":"
+                + System.currentTimeMillis(), contextName, undeploy);
         if (log.isDebugEnabled())
-            log.debug(sm.getString("farmWarDeployer.removeTxMsg", 
contextPath));
+            log.debug(sm.getString("farmWarDeployer.removeTxMsg", 
contextName));
         cluster.send(msg);
         // remove locally
         if (undeploy) {
             try {
-                if (!isServiced(contextPath)) {
-                    addServiced(contextPath);
+                if (!isServiced(contextName)) {
+                    addServiced(contextName);
                     try {
-                        remove(contextPath);
+                        remove(contextName);
                     } finally {
-                        removeServiced(contextPath);
+                        removeServiced(contextName);
                     }
                 } else
                     log.error(sm.getString("farmWarDeployer.removeFailRemote",
-                            contextPath));
+                            contextName));
 
             } catch (Exception ex) {
                 log.error(sm.getString("farmWarDeployer.removeFailLocal",
-                        contextPath), ex);
+                        contextName), ex);
             }
         }
 
@@ -465,16 +461,16 @@ public class FarmWarDeployer extends Clu
         try {
             File deployWar = new File(getDeployDir(), newWar.getName());
             copy(newWar, deployWar);
-            String contextName = getContextName(deployWar);
+            ContextName cn = new ContextName(deployWar.getName());
             if (log.isInfoEnabled())
-                log.info(sm.getString("farmWarDeployer.modInstall", 
contextName,
-                        deployWar.getAbsolutePath()));
+                log.info(sm.getString("farmWarDeployer.modInstall",
+                        cn.getName(), deployWar.getAbsolutePath()));
             try {
-                remove(contextName, false);
+                remove(cn.getName(), false);
             } catch (Exception x) {
                 log.error(sm.getString("farmWarDeployer.modRemoveFail"), x);
             }
-            install(contextName, deployWar.toURI().toURL());
+            install(cn.getName(), deployWar);
         } catch (Exception x) {
             log.error(sm.getString("farmWarDeployer.modInstallFail"), x);
         }
@@ -488,32 +484,17 @@ public class FarmWarDeployer extends Clu
     @Override
     public void fileRemoved(File removeWar) {
         try {
-            String contextName = getContextName(removeWar);
+            ContextName cn = new ContextName(removeWar.getName());
             if (log.isInfoEnabled())
                 log.info(sm.getString("farmWarDeployer.removeLocal",
-                        contextName));
-            remove(contextName, true);
+                        cn.getName()));
+            remove(cn.getName(), true);
         } catch (Exception x) {
             log.error(sm.getString("farmWarDeployer.removeLocalFail"), x);
         }
     }
 
     /**
-     * Create a context path from war
-     * @param war War filename
-     * @return '/filename' or if war name is ROOT.war context name is empty
-     *         string '' 
-     */
-    protected String getContextName(File war) {
-        String contextName = "/"
-        + war.getName().substring(0,
-                war.getName().lastIndexOf(".war"));
-        if("/ROOT".equals(contextName))
-            contextName= "" ;
-        return contextName ;
-    }
-    
-    /**
      * Return a File object representing the "application root" directory for
      * our associated Host.
      */
@@ -539,13 +520,14 @@ public class FarmWarDeployer extends Clu
     /**
      * Invoke the remove method on the deployer.
      */
-    protected void remove(String path) throws Exception {
+    protected void remove(String contextName) throws Exception {
         // TODO Handle remove also work dir content !
         // Stop the context first to be nicer
-        Context context = (Context) host.findChild(path);
+        Context context = (Context) host.findChild(contextName);
         if (context != null) {
             if(log.isDebugEnabled())
-                log.debug(sm.getString("farmWarDeployer.undeployLocal", path));
+                log.debug(sm.getString("farmWarDeployer.undeployLocal",
+                        contextName));
             context.stop();
             String baseName = context.getBaseName();
             File war = new File(getAppBase(), baseName + ".war");
@@ -563,7 +545,7 @@ public class FarmWarDeployer extends Clu
                 }
             }
             // Perform new deployment and remove internal HostConfig state
-            check(path);
+            check(contextName);
         }
 
     }

Modified: tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessage.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessage.java?rev=1064881&r1=1064880&r2=1064881&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessage.java (original)
+++ tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessage.java Fri Jan 28 
21:04:55 2011
@@ -37,14 +37,14 @@ public class FileMessage extends Cluster
     private long totalLength;
     private long totalNrOfMsgs;
     private String fileName;
-    private String contextPath;
+    private String contextName;
     
     public FileMessage(Member source,
                        String fileName,
-                       String contextPath) {
+                       String contextName) {
         this.address=source;
         this.fileName=fileName;
-        this.contextPath=contextPath;
+        this.contextName=contextName;
     }
     
     /*
@@ -106,8 +106,8 @@ public class FileMessage extends Cluster
     public void setFileName(String fileName) {
         this.fileName = fileName;
     }
-    public String getContextPath() {
-        return contextPath;
+    public String getContextName() {
+        return contextName;
     }
     
 }

Modified: 
tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessageFactory.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessageFactory.java?rev=1064881&r1=1064880&r2=1064881&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessageFactory.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/ha/deploy/FileMessageFactory.java Fri 
Jan 28 21:04:55 2011
@@ -238,8 +238,8 @@ public class FileMessageFactory {
         
         if (msg.getMessageNumber() <= lastMessageProcessed.get()) {
             // Duplicate of message already processed
-            log.warn("Receive Message again -- Sender ActTimeout too short [ 
path: "
-                    + msg.getContextPath()
+            log.warn("Receive Message again -- Sender ActTimeout too short [ 
name: "
+                    + msg.getContextName()
                     + " war: "
                     + msg.getFileName()
                     + " data: "
@@ -252,8 +252,8 @@ public class FileMessageFactory {
             msgBuffer.put(Long.valueOf(msg.getMessageNumber()), msg);
         if (previous !=null) {
             // Duplicate of message not yet processed
-            log.warn("Receive Message again -- Sender ActTimeout too short [ 
path: "
-                    + msg.getContextPath()
+            log.warn("Receive Message again -- Sender ActTimeout too short [ 
name: "
+                    + msg.getContextName()
                     + " war: "
                     + msg.getFileName()
                     + " data: "

Modified: tomcat/trunk/java/org/apache/catalina/ha/deploy/UndeployMessage.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/deploy/UndeployMessage.java?rev=1064881&r1=1064880&r2=1064881&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/ha/deploy/UndeployMessage.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/ha/deploy/UndeployMessage.java Fri 
Jan 28 21:04:55 2011
@@ -26,7 +26,7 @@ public class UndeployMessage implements 
     private Member address;
     private long timestamp;
     private String uniqueId;
-    private String contextPath;
+    private String contextName;
     private boolean undeploy;
     private int resend = 0;
     private int compress = 0;
@@ -35,14 +35,14 @@ public class UndeployMessage implements 
     public UndeployMessage(Member address,
                            long timestamp,
                            String uniqueId,
-                           String contextPath,
+                           String contextName,
                            boolean undeploy) {
         this.address  = address;
         this.timestamp= timestamp;
         this.undeploy = undeploy;
         this.uniqueId = uniqueId;
         this.undeploy = undeploy;
-        this.contextPath = contextPath;
+        this.contextName = contextName;
     }
 
     @Override
@@ -75,12 +75,12 @@ public class UndeployMessage implements 
         this.uniqueId = uniqueId;
     }
 
-    public String getContextPath() {
-        return contextPath;
+    public String getContextName() {
+        return contextName;
     }
 
-    public void setContextPath(String contextPath) {
-        this.contextPath = contextPath;
+    public void setContextPath(String contextName) {
+        this.contextName = contextName;
     }
 
     public boolean getUndeploy() {

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1064881&r1=1064880&r2=1064881&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Jan 28 21:04:55 2011
@@ -177,6 +177,10 @@
         <bug>50646</bug>: Ensure larger Tribes messages are fully read. Patch
         provided by Olivier Costet. (markt)
       </fix>
+      <fix>
+        <bug>50679</bug>: Update the FarmWarDeployer to support parallel
+        deployment. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Web applications">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to