Author: markt
Date: Mon Nov 25 22:00:13 2013
New Revision: 1545418
URL: http://svn.apache.org/r1545418
Log:
Backport automatic deployment changes part 6
Add the first part of the deletion tests for the auto-deployer.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestHostConfigAutomaticDeployment.java
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1482591,1545416
Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java?rev=1545418&r1=1545417&r2=1545418&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/HostConfig.java Mon
Nov 25 22:00:13 2013
@@ -167,7 +167,8 @@ public class HostConfig
/**
* The <code>Digester</code> instance used to parse context descriptors.
*/
- protected static Digester digester = createDigester();
+ protected Digester digester = createDigester(contextClass);
+ private final Object digesterLock = new Object();
/**
* The list of Wars in the appBase to be ignored because they are invalid
@@ -221,8 +222,14 @@ public class HostConfig
*/
public void setContextClass(String contextClass) {
+ String oldContextClass = this.contextClass;
this.contextClass = contextClass;
+ if (oldContextClass != contextClass) {
+ synchronized (digesterLock) {
+ digester = createDigester(getContextClass());
+ }
+ }
}
@@ -391,12 +398,11 @@ public class HostConfig
/**
* Create the digester which will be used to parse context config files.
*/
- protected static Digester createDigester() {
+ protected static Digester createDigester(String contextClassName) {
Digester digester = new Digester();
digester.setValidating(false);
// Add object creation rule
- digester.addObjectCreate("Context",
"org.apache.catalina.core.StandardContext",
- "className");
+ digester.addObjectCreate("Context", contextClassName, "className");
// Set the properties on that object (it doesn't matter if extra
// properties are set)
digester.addSetProperties("Context");
@@ -612,7 +618,7 @@ public class HostConfig
FileInputStream fis = null;
try {
fis = new FileInputStream(contextXml);
- synchronized (digester) {
+ synchronized (digesterLock) {
try {
context = (Context) digester.parse(fis);
} catch (Exception e) {
@@ -906,7 +912,7 @@ public class HostConfig
Context context = null;
try {
if (deployXML && xml.exists()) {
- synchronized (digester) {
+ synchronized (digesterLock) {
try {
context = (Context) digester.parse(xml);
} catch (Exception e) {
@@ -920,7 +926,7 @@ public class HostConfig
}
context.setConfigFile(xml.toURI().toURL());
} else if (deployXML && xmlInWar) {
- synchronized (digester) {
+ synchronized (digesterLock) {
try {
jar = new JarFile(war);
entry =
@@ -1067,7 +1073,7 @@ public class HostConfig
File xmlCopy = null;
try {
if (deployXML && xml.exists()) {
- synchronized (digester) {
+ synchronized (digesterLock) {
try {
context = (Context) digester.parse(xml);
} catch (Exception e) {
Modified:
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestHostConfigAutomaticDeployment.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestHostConfigAutomaticDeployment.java?rev=1545418&r1=1545417&r2=1545418&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestHostConfigAutomaticDeployment.java
(original)
+++
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestHostConfigAutomaticDeployment.java
Mon Nov 25 22:00:13 2013
@@ -34,6 +34,7 @@ import org.apache.catalina.Engine;
import org.apache.catalina.Globals;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleState;
+import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.util.ContextName;
import org.apache.tomcat.util.buf.B2CConverter;
@@ -56,6 +57,11 @@ public class TestHostConfigAutomaticDepl
private static final File DIR_SOURCE =
new File("test/deployment/dirNoContext");
+ private static final int XML = 1;
+ private static final int EXT = 2;
+ private static final int WAR = 3;
+ private static final int DIR = 4;
+
private static final String XML_COOKIE_NAME = "XML_CONTEXT";
private static final String WAR_COOKIE_NAME = "WAR_CONTEXT";
private static final String DIR_COOKIE_NAME = "DIR_CONTEXT";
@@ -677,6 +683,187 @@ public class TestHostConfigAutomaticDepl
}
+ /*
+ * Expected behaviour for deletion of files.
+ *
+ * Artifacts present(6) Artifact Artifacts remaining
+ * XML WAR EXT DIR Removed XML WAR EXT DIR Notes
+ * N N N Y DIR - - - N
+ * N Y N N WAR - N - -
+ * N Y N Y DIR - Y - R 8
+ * N Y N Y WAR - N - N
+ * Y N N N XML N - - -
+ * Y N N Y DIR Y - - N 2
+ * Y N N Y XML N - - N
+ * Y N Y N EXT Y - N - 2
+ * Y N Y N XML N - Y - 9
+ * Y N Y Y DIR Y - Y R 10,8
+ * Y N Y Y EXT Y - N N 2
+ * Y N Y Y XML N - Y N
+ * Y Y N N WAR Y N - - 2
+ * Y Y N N XML N N - -
+ * Y Y N Y DIR Y Y - R 8
+ * Y Y N Y WAR Y N - - 2
+ * Y Y N Y XML N N - N
+ *
+ * Notes:
+ */
+ @Test
+ public void testDeleteDirRemoveDir() throws Exception {
+ doTestDelete(false, false, false, false, true, DIR, false, false,
false,
+ false, null);
+ }
+
+ @Test
+ public void testDeleteWarRemoveWar() throws Exception {
+ doTestDelete(false, false, false, true, false, WAR, false, false,
false,
+ false, null);
+ }
+
+ @Test
+ public void testDeleteWarDirRemoveDir() throws Exception {
+ doTestDelete(false, false, false, true, true, DIR, false, false, true,
+ true, WAR_COOKIE_NAME);
+ }
+
+ @Test
+ public void testDeleteWarDirRemoveWar() throws Exception {
+ doTestDelete(false, false, false, true, true, WAR, false, false, false,
+ false, null);
+ }
+
+ private void doTestDelete(boolean startXml, boolean startExternalWar,
+ boolean startExternalDir, boolean startWar, boolean startDir,
+ int toDelete, boolean resultXml, boolean resultExternal,
+ boolean resultWar, boolean resultDir, String resultCookieName)
+ throws Exception {
+
+ Tomcat tomcat = getTomcatInstance();
+ StandardHost host = (StandardHost) tomcat.getHost();
+
+ // Init
+ File xml = null;
+ File ext = null;
+ File war = null;
+ File dir = null;
+
+ if (startXml) {
+ xml = new File(getConfigBaseFile(host), APP_NAME + ".xml");
+ File parent = xml.getParentFile();
+ if (!parent.isDirectory()) {
+ Assert.assertTrue(parent.mkdirs());
+ }
+ Files.copy(XML_SOURCE.toPath(), xml.toPath());
+ }
+ if (startExternalWar) {
+ // Copy the test WAR file to the external directory
+ ext = new File(external, "external" + ".war");
+ Files.copy(WAR_XML_SOURCE.toPath(), ext.toPath());
+
+ // Create the XML file
+ xml = new File(getConfigBaseFile(host), APP_NAME + ".xml");
+ File parent = xml.getParentFile();
+ if (!parent.isDirectory()) {
+ Assert.assertTrue(parent.mkdirs());
+ }
+
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(xml);
+ fos.write(("<Context sessionCookieName=\"" + XML_COOKIE_NAME +
+ "\" docBase=\"" + ext.getAbsolutePath() +
+ "\" />").getBytes(B2CConverter.ISO_8859_1));
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+ }
+ if (startExternalDir) {
+ // Copy the test DIR file to the external directory
+ ext = new File(external, "external");
+ recurrsiveCopy(DIR_XML_SOURCE.toPath(), ext.toPath());
+
+ // Create the XML file
+ xml = new File(getConfigBaseFile(getTomcatInstance().getHost()),
+ APP_NAME + ".xml");
+ File parent = xml.getParentFile();
+ if (!parent.isDirectory()) {
+ Assert.assertTrue(parent.mkdirs());
+ }
+
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(xml);
+ fos.write(("<Context sessionCookieName=\"" + XML_COOKIE_NAME +
+ "\" docBase=\"" + ext.getAbsolutePath() +
+ "\" />").getBytes(B2CConverter.ISO_8859_1));
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+ }
+ if (startWar) {
+ // Copy the test WAR file to the appBase
+ war = new File(getAppBaseFile(getTomcatInstance().getHost()),
+ APP_NAME.getBaseName() + ".war");
+ Files.copy(WAR_XML_SOURCE.toPath(), war.toPath());
+ }
+ if (startDir) {
+ // Copy the test DIR file to the appBase
+ dir = new File(getAppBaseFile(getTomcatInstance().getHost()),
+ APP_NAME.getBaseName());
+ recurrsiveCopy(DIR_XML_SOURCE.toPath(), dir.toPath());
+ }
+
+ if (startWar && !startDir) {
+ host.setUnpackWARs(false);
+ // WARDirContext always locks the WAR file so need to use
+ // anti-resource locking to enable the WAR to be deleted
+ host.setContextClass(AntiResourceLockingContext.class.getName());
+ }
+
+ // Deploy the files we copied
+ tomcat.start();
+ host.backgroundProcess();
+
+ // Remove the specified file
+ switch (toDelete) {
+ case XML:
+ ExpandWar.delete(xml);
+ break;
+ case EXT:
+ ExpandWar.delete(ext);
+ break;
+ case WAR:
+ ExpandWar.delete(war);
+ break;
+ case DIR:
+ ExpandWar.delete(dir);
+ break;
+ default:
+ Assert.fail();
+ }
+
+ // Trigger an auto-deployment cycle
+ host.backgroundProcess();
+
+ Context ctxt = (Context) host.findChild(APP_NAME.getName());
+
+ // Check the results
+ if (!resultXml && !resultWar && !resultDir) {
+ // App should have been undeployed
+ Assert.assertNull(ctxt);
+ return;
+ }
+
+ if (resultWar) {
+ Assert.assertEquals(resultCookieName, ctxt.getSessionCookieName());
+ }
+ }
+
+
private static void recurrsiveCopy(final Path src, final Path dest)
throws IOException {
@@ -747,4 +934,44 @@ public class TestHostConfigAutomaticDepl
return file;
}
}
+
+ private static class AntiResourceLockingContext extends StandardContext {
+
+ @Override
+ public boolean getAntiResourceLocking() {
+ return true;
+ }
+ }
+
+
+ @Test
+ public void testSetContextClassName() throws Exception {
+
+ Tomcat tomcat = getTomcatInstance();
+
+ Host host = tomcat.getHost();
+ if (host instanceof StandardHost) {
+ StandardHost standardHost = (StandardHost) host;
+ standardHost.setContextClass(TesterContext.class.getName());
+ }
+
+ // Copy the WAR file
+ File war = new File(getAppBaseFile(host),
+ APP_NAME.getBaseName() + ".war");
+ Files.copy(WAR_XML_SOURCE.toPath(), war.toPath());
+
+ // Deploy the copied war
+ tomcat.start();
+ host.backgroundProcess();
+
+ // Check the Context class
+ Context ctxt = (Context) host.findChild(APP_NAME.getName());
+
+ Assert.assertTrue(ctxt instanceof TesterContext);
+ }
+
+
+ public static class TesterContext extends StandardContext {
+ // No functional change
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]