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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to