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: [email protected]
For additional commands, e-mail: [email protected]