[jboss-cvs] JBossAS SVN: r102186 - in trunk: server/src/main/java/org/jboss/as/javaee and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Mar 9 23:29:56 EST 2010


Author: bstansberry at jboss.com
Date: 2010-03-09 23:29:55 -0500 (Tue, 09 Mar 2010)
New Revision: 102186

Added:
   trunk/server/src/main/java/org/jboss/deployment/ModuleNameDeployer.java
   trunk/testsuite/src/main/org/jboss/test/deployers/ear/test/ModuleNameDeployerUnitTestCase.java
Modified:
   trunk/server/src/etc/deployers/ear-deployer-jboss-beans.xml
   trunk/server/src/main/java/org/jboss/as/javaee/SimpleJavaEEModuleIdentifier.java
   trunk/server/src/main/java/org/jboss/as/naming/javaee/NamingJavaEEModuleInformer.java
Log:
[JBAS-7644] Implement EE 6 module naming requirements

Modified: trunk/server/src/etc/deployers/ear-deployer-jboss-beans.xml
===================================================================
--- trunk/server/src/etc/deployers/ear-deployer-jboss-beans.xml	2010-03-10 04:26:32 UTC (rev 102185)
+++ trunk/server/src/etc/deployers/ear-deployer-jboss-beans.xml	2010-03-10 04:29:55 UTC (rev 102186)
@@ -56,4 +56,18 @@
       -->      
       <property name="isolated">true</property>
    </bean>
+   
+   <!--  Enforce the EE module name requirements in EE 6 section EE.8.1 -->
+   <bean name="ModuleNameDeployer" class="org.jboss.deployment.ModuleNameDeployer">
+      <constructor>
+         <parameter>
+            <set elementClass="java.lang.Class">
+               <value>org.jboss.metadata.ejb.jboss.JBossMetaData</value>
+               <value>org.jboss.metadata.web.jboss.JBossWebMetaData</value>
+               <!--<value>org.jboss.resource.metadata.RARDeploymentMetaData</value>-->
+               <value>org.jboss.metadata.client.jboss.JBossClientMetaData</value>
+            </set>
+         </parameter>
+      </constructor>
+   </bean>
 </deployment>

Modified: trunk/server/src/main/java/org/jboss/as/javaee/SimpleJavaEEModuleIdentifier.java
===================================================================
--- trunk/server/src/main/java/org/jboss/as/javaee/SimpleJavaEEModuleIdentifier.java	2010-03-10 04:26:32 UTC (rev 102185)
+++ trunk/server/src/main/java/org/jboss/as/javaee/SimpleJavaEEModuleIdentifier.java	2010-03-10 04:29:55 UTC (rev 102186)
@@ -26,6 +26,7 @@
 import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeanMetaData;
 import org.jboss.metadata.ejb.jboss.JBossEntityBeanMetaData;
 import org.jboss.metadata.ejb.jboss.JBossMetaData;
+import org.jboss.metadata.javaee.jboss.NamedModule;
 import org.jboss.metadata.web.jboss.JBossWebMetaData;
 import org.jboss.reloaded.naming.deployers.javaee.JavaEEModuleInformer;
 
@@ -49,6 +50,14 @@
          return JavaEEModuleInformer.ModuleType.WEB;
       return JavaEEModuleInformer.ModuleType.JAVA;
    }
+   
+   public String getModuleName(DeploymentUnit unit)
+   {
+      NamedModule moduleName = unit.getAttachment(NamedModule.class);
+      
+      return moduleName == null ? null : moduleName.getModuleName(); 
+      
+   }
 
    public String[] getRequiredAttachments()
    {

Modified: trunk/server/src/main/java/org/jboss/as/naming/javaee/NamingJavaEEModuleInformer.java
===================================================================
--- trunk/server/src/main/java/org/jboss/as/naming/javaee/NamingJavaEEModuleInformer.java	2010-03-10 04:26:32 UTC (rev 102185)
+++ trunk/server/src/main/java/org/jboss/as/naming/javaee/NamingJavaEEModuleInformer.java	2010-03-10 04:29:55 UTC (rev 102186)
@@ -19,6 +19,13 @@
 
    public String getModulePath(DeploymentUnit deploymentUnit)
    {
+      // FIXME this is a hack to give the CURRENT users of this class, 
+      // ComponentNamingDeployer and ModuleNamingDeployer, the info they actually
+      // want, rather than what they ask for. :) Tear this out once they
+      // use the NamedModule DU attachment directly. 
+      String moduleName = identifier.getModuleName(deploymentUnit);
+      if (moduleName != null)
+         return moduleName;
       /*
        * JavaEE 6 FR 8.1.1:
        * The name can be explicitly set in the deployment descriptor for the module. If not set, the name
@@ -30,6 +37,7 @@
       String path = deploymentUnit.getRelativePath();
       if(path == null || path.length() == 0)
          path = deploymentUnit.getSimpleName();
+//      return path.substring(0, path.length() - 4);
       return path;
    }
 

Added: trunk/server/src/main/java/org/jboss/deployment/ModuleNameDeployer.java
===================================================================
--- trunk/server/src/main/java/org/jboss/deployment/ModuleNameDeployer.java	                        (rev 0)
+++ trunk/server/src/main/java/org/jboss/deployment/ModuleNameDeployer.java	2010-03-10 04:29:55 UTC (rev 102186)
@@ -0,0 +1,229 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010 Red Hat, Inc. and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.deployment;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.spi.deployer.DeploymentStages;
+import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.metadata.ear.jboss.JBossAppMetaData;
+import org.jboss.metadata.ear.spec.ModuleMetaData;
+import org.jboss.metadata.ear.spec.ModulesMetaData;
+import org.jboss.metadata.javaee.jboss.NamedModule;
+
+/**
+ * Ensures that EE modules have names that comply with the requirements of
+ * EE 6 Section EE.8.1.1.
+ * 
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class ModuleNameDeployer extends AbstractDeployer
+{
+   private final Set<Class<? extends NamedModule>> inputTypes;
+   
+   /**
+    * Creates a new ModuleNameDeployer
+    */
+   public ModuleNameDeployer(Set<Class<? extends NamedModule>> inputTypes)
+   {
+      if (inputTypes == null)
+      {
+         throw new IllegalArgumentException("inputTypes cannot be null");
+      }
+      
+      // We want to run after any scanning-based metadata is done
+      setStage(DeploymentStages.PRE_REAL);
+      addInput(JBossAppMetaData.class);
+      addOutput(JBossAppMetaData.class);
+      addOutput(NamedModule.class);
+      for (Class<? extends NamedModule> type : inputTypes)
+      {
+         addInput(type);
+         addOutput(type);
+      }
+      this.inputTypes = inputTypes;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.deployers.spi.deployer.Deployer#deploy(org.jboss.deployers.structure.spi.DeploymentUnit)
+    */
+   public void deploy(DeploymentUnit unit) throws DeploymentException
+   {
+      // Find all the metadata types assoc w/ unit that specify a moduleName
+      List<NamedModule> metadatas = null;
+      for (Class<? extends NamedModule> type : inputTypes)
+      {
+         NamedModule nm = unit.getAttachment(type);
+         if (nm != null)
+         {
+            if (metadatas == null)
+            {
+               metadatas = new ArrayList<NamedModule>();
+            }
+            metadatas.add(nm);
+         }
+      }
+      
+      if (metadatas == null)
+      {
+         return;
+      }
+      
+      String moduleName = null;
+      
+      // See if any of the existing metadata specifies a module name
+      for (NamedModule nm : metadatas)
+      {
+         moduleName = nm.getModuleName();
+         if (moduleName != null)
+         {
+            break;
+         }
+      }
+      
+      // Enforce EAR rules from EE 6 EE.8.1.1
+      JBossAppMetaData appMetaData = null;
+      DeploymentUnit parent = unit.getParent();
+      if (parent != null)
+      {
+         appMetaData = parent.getAttachment(JBossAppMetaData.class);
+      }      
+      if (appMetaData != null)
+      {         
+         moduleName = establishUniqueModuleName(unit, moduleName, appMetaData);
+      }
+      else if (moduleName == null)
+      {
+         // Not in an EAR and no name was configured. 
+         // Create a default module name as per EE 6 EE.8.1.2:
+         // "when a stand-alone module is deployed....  [t]he module name can be 
+         // explicitly set in the module deployment descriptor. If not set, the 
+         // name of the module is the base name of the module file with any 
+         // extension (.war, .jar, .rar) removed and with any directory names removed."
+         moduleName = trimExtension(unit.getSimpleName());
+      }
+      
+      // Apply the name to all metadata
+      for (NamedModule nm : metadatas)
+      {
+         nm.setModuleName(moduleName);
+      }
+      
+      // Let other deployers get the module name w/o having to search
+      // for all the possible metadata types
+      unit.addAttachment(NamedModule.class, metadatas.get(0));
+   }
+   
+   private String establishUniqueModuleName(DeploymentUnit unit, String configuredName, JBossAppMetaData appMetaData) throws DeploymentException
+   {      
+      String name = configuredName == null ? trimExtension(unit.getRelativePath()): configuredName;
+      
+      String modulePath = unit.getRelativePath();
+      ModulesMetaData modules = appMetaData.getModules();
+      if (modules == null)
+      {
+         throw new DeploymentException(unit + " has attached " + JBossAppMetaData.class.getSimpleName() + 
+               " but it has no associated " + ModulesMetaData.class.getSimpleName());
+      }
+      ModuleMetaData ourModule = null;
+      String uniqueName = null;
+      // Synchronize on the modules to ensure concurrent deployments of the
+      // modules pass serially through this logic
+      synchronized(modules)
+      {
+         ourModule = modules.get(modulePath);
+         if (ourModule == null)
+         {
+            String parentUnitName = unit.getParent().getName();
+            throw new DeploymentException("No module with relative path " + 
+                  modulePath + " found  in set of modules for " + parentUnitName + " "  + modules.keySet());
+         }
+         
+          uniqueName = name;
+          if (!isNameUnique(uniqueName, ourModule, modules))
+          {
+             // Try the relative path w/ extension removed
+             uniqueName = trimExtension(unit.getRelativePath());
+             if (uniqueName.equals(name) || !isNameUnique(uniqueName, ourModule, modules))
+             {
+                // Try leaving the extension
+                uniqueName = unit.getRelativePath();
+                if (!isNameUnique(uniqueName, ourModule, modules))
+                {
+                   // To get here, people would have to configure in xml a 
+                   // module name that conflicts with the relative path of
+                   // another module. Not likely, but...
+                   // Append a digit until the name is unique
+                   int i = 0;
+                   do
+                   {
+                      i++;
+                      uniqueName = name + "-" + i;
+                   }
+                   while (!isNameUnique(uniqueName, ourModule, modules));
+                }
+             }
+          }
+          
+          ourModule.setUniqueName(uniqueName);
+         
+      }
+      
+      // Log a WARN if we had to change the module name
+      if (configuredName != null && !configuredName.equals(uniqueName))
+      {
+         log.warn("Module name " + configuredName + " specified in deployment descriptor for " + unit + " was not unique within the application; using module name " + uniqueName + " instead");
+      }
+      else if (!name.equals(uniqueName))
+      {
+         log.warn("Module name " + name + " derived from the modules relative path in " + unit + " was not unique within the application; using module name " + uniqueName + " instead");
+      }
+      
+      return uniqueName;
+   }
+   
+   private static boolean isNameUnique(String uniqueName, ModuleMetaData ourModule, ModulesMetaData modules)
+   {
+      for (Iterator<ModuleMetaData> it = modules.iterator(); it.hasNext(); )
+      {
+         ModuleMetaData module = it.next();
+         if (!ourModule.equals(module) && uniqueName.equals(module.getUniqueName()))
+         {
+            return false;
+         }
+      }
+      return true;
+   }
+
+   private static String trimExtension(String path)
+   {
+      int lastDot = path.lastIndexOf('.');
+      return (lastDot > -1) ? path.substring(0, lastDot) : path;
+   }
+
+}


Property changes on: trunk/server/src/main/java/org/jboss/deployment/ModuleNameDeployer.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision

Added: trunk/testsuite/src/main/org/jboss/test/deployers/ear/test/ModuleNameDeployerUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/deployers/ear/test/ModuleNameDeployerUnitTestCase.java	                        (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/deployers/ear/test/ModuleNameDeployerUnitTestCase.java	2010-03-10 04:29:55 UTC (rev 102186)
@@ -0,0 +1,589 @@
+/**
+ * 
+ */
+package org.jboss.test.deployers.ear.test;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.TestCase;
+
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.deployment.ModuleNameDeployer;
+import org.jboss.metadata.client.jboss.JBossClientMetaData;
+import org.jboss.metadata.ear.jboss.JBossAppMetaData;
+import org.jboss.metadata.ear.spec.ModuleMetaData;
+import org.jboss.metadata.ear.spec.ModulesMetaData;
+import org.jboss.metadata.ejb.jboss.JBossMetaData;
+import org.jboss.metadata.javaee.jboss.NamedModule;
+import org.jboss.metadata.web.jboss.JBossWebMetaData;
+
+/**
+ * Unit tests for {@link ModuleNameDeployer}.
+ * 
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class ModuleNameDeployerUnitTestCase extends TestCase
+{
+   private static final Set<Class<? extends NamedModule>> standardTypes = new HashSet<Class<? extends NamedModule>>();
+   static
+   {
+      standardTypes.add(JBossWebMetaData.class);
+      standardTypes.add(JBossMetaData.class);
+      standardTypes.add(JBossClientMetaData.class);
+//      standardTypes.add(getJCAMetaDataClass());
+   }
+   
+   // At the time this test is being written, the JCA metadata class that
+   // will implement NamedModule is unclear. This method lets me isolate
+   // the effect of that decision on the test code in one place.
+//   private static NamedModule getJCAMetaData()
+//   {
+//      return new RARDeploymentMetaData();
+//   }
+//   
+//   private static Class<? extends NamedModule> getJCAMetaDataClass()
+//   {
+//      return getJCAMetaData().getClass();
+//   }
+   
+   private static final String TEST = "test";
+   private static final String SIMPLE = "simple";
+   private static final String PATH = "pathTo/";
+   private static final String SIMPLE_DU_EAR = SIMPLE + ".ear";
+   private static final String SIMPLE_DU_WAR = SIMPLE + ".war";
+   private static final String SIMPLE_DU_WAR_PATH = PATH + SIMPLE_DU_WAR;
+   private static final String SIMPLE_DU_JAR = SIMPLE + ".jar";
+   private static final String SIMPLE_DU_JAR_PATH = PATH + SIMPLE_DU_JAR;
+   private static final String SIMPLE_DU_RAR = SIMPLE + ".rar";
+   private static final String SIMPLE_DU_RAR_PATH = PATH + SIMPLE_DU_RAR;
+   private static final String SIMPLE_DU_APPCLIENT = SIMPLE + "-client.jar";
+   private static final String SIMPLE_DU_APPCLIENT_PATH = PATH + SIMPLE_DU_APPCLIENT;
+   private static final String SIMPLE_TRIMMED_PATH = PATH + SIMPLE;
+   private static final String SIMPLE_TRIMMED_CLIENT_PATH = PATH + SIMPLE + "-client";
+   
+   private ModuleNameDeployer testee;
+   
+   /**
+    * @param name
+    */
+   public ModuleNameDeployerUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   /* (non-Javadoc)
+    * @see junit.framework.TestCase#setUp()
+    */
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      testee = new ModuleNameDeployer(standardTypes);
+   }
+   
+   /** Ensure we handle DUs that we're not interested in */
+   public void testNoNamedModules() throws DeploymentException
+   {
+      DUIH duih = new DUIH();
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertNull(duih.getNamedModuleMetaData(NamedModule.class));
+   }
+   
+   /** Basic case where there's 1 MD object that specified its name */
+   public void testConfiguredName() throws DeploymentException
+   {
+      DUIH duih = getSingleAttachmentDUIH();
+      NamedModule md = getSingleAttachment(duih);
+      md.setModuleName(TEST);
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(TEST, md.getModuleName());
+      assertEquals(TEST, duih.getModuleName(NamedModule.class));
+   }
+
+   
+   /** DU has 1 MD object that specified its name; others that didn't */
+   public void testOneConfiguredNameMultipleAttachments() throws DeploymentException
+   {
+      DUIH duih = getMultiAttachmentDUIH();
+      duih.getNamedModuleMetaData(JBossWebMetaData.class).setModuleName(TEST);
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      for (Class<? extends NamedModule> type : standardTypes)
+      {
+         assertEquals("Module name correct for " + type, TEST, duih.getModuleName(type));
+      }
+      assertEquals(TEST, duih.getModuleName(NamedModule.class));
+   }
+   
+   /** Basic case where there's 1 MD object that did not specify its name */
+   public void testNoConfiguredName() throws DeploymentException
+   {
+      DUIH duih = getSingleAttachmentDUIH();
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(SIMPLE, getSingleAttachment(duih).getModuleName());
+      assertEquals(SIMPLE, duih.getModuleName(NamedModule.class));
+   }
+   
+   /** DU has multiple attachments none of which specified its name */
+   public void testNoConfiguredNameMultipleAttachments() throws DeploymentException
+   {
+      DUIH duih = getMultiAttachmentDUIH();
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      for (Class<? extends NamedModule> type : standardTypes)
+      {
+         assertEquals("Module name correct for " + type, SIMPLE, duih.getModuleName(type));
+      }
+      assertEquals(SIMPLE, duih.getModuleName(NamedModule.class));
+   }
+   
+   /** Same as testConfiguredName but in an EAR */
+   public void testConfiguredNameWithParent() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(false);
+      NamedModule md = getSingleAttachment(duih);
+      md.setModuleName(TEST);
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(TEST, md.getModuleName());
+      assertEquals(TEST, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(TEST, modmd.getUniqueName());
+   }
+
+   public void testOneConfiguredNameMultipleAttachmentsWithParent() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(true);
+      duih.getNamedModuleMetaData(JBossWebMetaData.class).setModuleName(TEST);
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      for (Class<? extends NamedModule> type : standardTypes)
+      {
+         assertEquals("Module name correct for " + type, TEST, duih.getModuleName(type));
+      }
+      assertEquals(TEST, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(TEST, modmd.getUniqueName());
+   }
+   
+   public void testNoConfiguredNameWithParent() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(false);
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(SIMPLE_TRIMMED_PATH, getSingleAttachment(duih).getModuleName());
+      assertEquals(SIMPLE_TRIMMED_PATH, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(SIMPLE_TRIMMED_PATH, modmd.getUniqueName());
+   }
+   
+   public void testNoConfiguredNameMultipleAttachmentsWithParent() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(true);
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      for (Class<? extends NamedModule> type : standardTypes)
+      {
+         assertEquals("Module name correct for " + type, SIMPLE_TRIMMED_PATH, duih.getModuleName(type));
+      }
+      assertEquals(SIMPLE_TRIMMED_PATH, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(SIMPLE_TRIMMED_PATH, modmd.getUniqueName());
+   }
+   
+   public void testConfiguredNameConflict() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(false);
+      NamedModule md = getSingleAttachment(duih);
+      md.setModuleName(TEST);
+      ModulesMetaData modules = getModulesMetaData(duih);
+      ModuleMetaData conflict = new ModuleMetaData();
+      conflict.setName(SIMPLE_DU_JAR_PATH);
+      conflict.setUniqueName(TEST);
+      modules.add(conflict);
+      
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(SIMPLE_TRIMMED_PATH, md.getModuleName());
+      assertEquals(SIMPLE_TRIMMED_PATH, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(SIMPLE_TRIMMED_PATH, modmd.getUniqueName());
+      
+      assertEquals(TEST, conflict.getUniqueName());
+   }
+   
+   public void testNoConfiguredNameConflict() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(false);
+      ModulesMetaData modules = getModulesMetaData(duih);
+      ModuleMetaData conflict = new ModuleMetaData();
+      conflict.setName(SIMPLE_DU_JAR_PATH);
+      conflict.setUniqueName(SIMPLE_TRIMMED_PATH);
+      modules.add(conflict);
+      
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(SIMPLE_DU_WAR_PATH, getSingleAttachment(duih).getModuleName());
+      assertEquals(SIMPLE_DU_WAR_PATH, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(SIMPLE_DU_WAR_PATH, modmd.getUniqueName());
+      
+      assertEquals(SIMPLE_TRIMMED_PATH, conflict.getUniqueName());
+   }
+   
+   public void testConfiguredNamePathologicalConflict() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(false);
+      NamedModule md = getSingleAttachment(duih);
+      md.setModuleName(TEST);
+      
+      ModulesMetaData modules = getModulesMetaData(duih);
+      ModuleMetaData conflict = new ModuleMetaData();
+      conflict.setName(SIMPLE_DU_JAR_PATH);
+      conflict.setUniqueName(TEST);
+      modules.add(conflict);
+      
+      ModuleMetaData conflict2 = new ModuleMetaData();
+      conflict2.setName(SIMPLE_DU_RAR_PATH);
+      conflict2.setUniqueName(SIMPLE_TRIMMED_PATH);
+      modules.add(conflict2);
+      
+      ModuleMetaData conflict3 = new ModuleMetaData();
+      conflict3.setName("pathological.war");
+      conflict3.setUniqueName(SIMPLE_DU_WAR_PATH);
+      modules.add(conflict3);
+      
+      ModuleMetaData conflict4 = new ModuleMetaData();
+      conflict4.setName("more-pathological.war");
+      conflict4.setUniqueName(SIMPLE_TRIMMED_PATH + "-1");
+      modules.add(conflict4);
+      
+      String expected = "test-1";
+      
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(expected, md.getModuleName());
+      assertEquals(expected, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(expected, modmd.getUniqueName());
+   }
+   
+   public void testNoConfiguredNamePathologicalConflict() throws DeploymentException
+   {
+      DUIH duih = getDUIHWithParent(false);
+      
+      ModulesMetaData modules = getModulesMetaData(duih);
+      ModuleMetaData conflict = new ModuleMetaData();
+      conflict.setName(SIMPLE_DU_JAR_PATH);
+      conflict.setUniqueName(TEST);
+      modules.add(conflict);
+      
+      ModuleMetaData conflict2 = new ModuleMetaData();
+      conflict2.setName(SIMPLE_DU_RAR_PATH);
+      conflict2.setUniqueName(SIMPLE_TRIMMED_PATH);
+      modules.add(conflict2);
+      
+      ModuleMetaData conflict3 = new ModuleMetaData();
+      conflict3.setName("pathological.war");
+      conflict3.setUniqueName(SIMPLE_DU_WAR_PATH);
+      modules.add(conflict3);
+      
+      ModuleMetaData conflict4 = new ModuleMetaData();
+      conflict4.setName("more-pathological.war");
+      conflict4.setUniqueName(SIMPLE_TRIMMED_PATH + "-1");
+      modules.add(conflict4);
+      
+      String expected = SIMPLE_TRIMMED_PATH + "-2";
+      
+      DeploymentUnit unit = getDeploymentUnitProxy(duih);
+      testee.deploy(unit);
+      assertEquals(expected, getSingleAttachment(duih).getModuleName());
+      assertEquals(expected, duih.getModuleName(NamedModule.class));
+      
+      ModuleMetaData modmd = getModuleMetaData(duih);
+      assertEquals(expected, modmd.getUniqueName());
+   }
+   
+   /**
+    * Tests situation where several DUs associated with same ear are
+    * concurrently passing through deployer.
+    * 
+    * @throws InterruptedException
+    */
+   public void testConcurrentDeployments() throws InterruptedException
+   {
+      // Set up an ear with a war, jar, ear
+      
+      DUIH parentDUIH = getParentDUIH(true);
+      DeploymentUnit parent = getDeploymentUnitProxy(parentDUIH);
+      JBossAppMetaData appmd = (JBossAppMetaData) parentDUIH.attachments.get(JBossAppMetaData.class);
+      ModulesMetaData modsmd = appmd.getModules();
+      
+      DUIH war = getSingleAttachmentDUIH(); // this does most setup for war
+      war.parent = parent;
+      war.relativePath = SIMPLE_DU_WAR_PATH;
+      ModuleMetaData warmod = appmd.getModule(SIMPLE_DU_WAR_PATH);
+      
+      DUIH jar = new DUIH();
+      jar.attachments.put(JBossMetaData.class, new JBossMetaData());
+      jar.parent = parent;
+      jar.relativePath = SIMPLE_DU_JAR_PATH;
+      jar.simpleName = SIMPLE_DU_JAR;
+      ModuleMetaData jarmod = new ModuleMetaData();
+      jarmod.setName(SIMPLE_DU_JAR_PATH);
+      modsmd.add(jarmod);
+      
+      DUIH appClient = new DUIH();
+      appClient.attachments.put(JBossClientMetaData.class, new JBossClientMetaData());
+      appClient.parent = parent;
+      appClient.relativePath = SIMPLE_DU_APPCLIENT_PATH;
+      appClient.simpleName = SIMPLE_DU_APPCLIENT;
+      ModuleMetaData appclientmod = new ModuleMetaData();
+      appclientmod.setName(SIMPLE_DU_APPCLIENT_PATH);
+      modsmd.add(appclientmod);
+      
+      // Make assertions simple by not letting anything have SIMPLE_TRIMMED_PATH
+      ModuleMetaData conflict = new ModuleMetaData();
+      conflict.setName("conflict.war");
+      conflict.setUniqueName(SIMPLE_TRIMMED_PATH);
+      modsmd.add(conflict);
+      
+      ExecutorService executor = Executors.newFixedThreadPool(3);
+      
+      CountDownLatch startLatch = new CountDownLatch(4);
+      CountDownLatch finishLatch = new CountDownLatch(3);
+      
+      DeploymentTask warTask = new DeploymentTask(startLatch, finishLatch, war);
+      executor.execute(warTask);
+      
+      DeploymentTask jarTask = new DeploymentTask(startLatch, finishLatch, jar);
+      executor.execute(jarTask);
+      
+      DeploymentTask appclientTask = new DeploymentTask(startLatch, finishLatch, appClient);
+      executor.execute(appclientTask);
+      
+      startLatch.countDown();
+      
+      assertTrue(finishLatch.await(5, TimeUnit.SECONDS));
+      
+      assertNull(warTask.exception);
+      assertNull(jarTask.exception);
+      assertNull(appclientTask.exception);
+      
+      assertEquals(SIMPLE_DU_WAR_PATH, getSingleAttachment(war).getModuleName());
+      assertEquals(SIMPLE_DU_WAR_PATH, warmod.getUniqueName());
+      
+      assertEquals(SIMPLE_DU_JAR_PATH, ((NamedModule) jar.attachments.get(JBossMetaData.class)).getModuleName());
+      assertEquals(SIMPLE_DU_JAR_PATH, jarmod.getUniqueName());
+      
+      assertEquals(SIMPLE_TRIMMED_CLIENT_PATH, ((NamedModule) appClient.attachments.get(JBossClientMetaData.class)).getModuleName());
+      assertEquals(SIMPLE_TRIMMED_CLIENT_PATH, appclientmod.getUniqueName());
+   }
+   
+   private static JBossAppMetaData getJBossAppMetaData(boolean addModule)
+   {
+      JBossAppMetaData appmd = new JBossAppMetaData();
+      appmd.setModules(new ModulesMetaData());
+      if (addModule)
+      {
+         ModuleMetaData modmd = new ModuleMetaData();
+         modmd.setName(SIMPLE_DU_WAR_PATH);
+         appmd.getModules().add(modmd);         
+      }
+      return appmd;
+   }
+   
+   private static DeploymentUnit getDeploymentUnitProxy(DUIH duih)
+   {
+      return (DeploymentUnit) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{DeploymentUnit.class}, duih);
+   }
+   
+   private static DUIH getMultiAttachmentDUIH()
+   {
+      DUIH duih = new DUIH();
+      JBossWebMetaData webmd = new JBossWebMetaData();
+      duih.attachments.put(JBossWebMetaData.class, webmd);
+      JBossMetaData ejbmd = new JBossMetaData();
+      duih.attachments.put(JBossMetaData.class, ejbmd);
+      JBossClientMetaData clientmd = new JBossClientMetaData();
+      duih.attachments.put(JBossClientMetaData.class, clientmd);
+//      NamedModule jcamd = getJCAMetaData();
+//      duih.attachments.put(jcamd.getClass(), jcamd);
+      
+      return duih;
+   }
+   
+   private static DUIH getSingleAttachmentDUIH()
+   {
+      DUIH duih = new DUIH();
+      JBossWebMetaData webmd = new JBossWebMetaData();
+      duih.attachments.put(JBossWebMetaData.class, webmd);
+      return duih;
+   }
+   
+   private NamedModule getSingleAttachment(DUIH duih)
+   {
+      return duih.getNamedModuleMetaData(JBossWebMetaData.class);
+   }
+   
+   private static DUIH getDUIHWithParent(boolean multiAttachment)
+   {
+      DUIH parent = getParentDUIH(true);
+      DUIH child = multiAttachment ? getMultiAttachmentDUIH() : getSingleAttachmentDUIH();
+      child.parent = getDeploymentUnitProxy(parent);
+      child.relativePath = SIMPLE_DU_WAR_PATH;
+      return child;
+   }
+   
+   private static DUIH getParentDUIH(boolean addModule)
+   {
+      DUIH parent = new DUIH();
+      parent.simpleName = SIMPLE_DU_EAR;
+      JBossAppMetaData appmd = getJBossAppMetaData(addModule);
+      parent.attachments.put(JBossAppMetaData.class, appmd);
+      return parent;
+   }
+   
+   private static ModulesMetaData getModulesMetaData(DUIH child)
+   {
+      DUIH parent = getParentDUIH(child);
+      JBossAppMetaData appmd = (JBossAppMetaData) parent.attachments.get(JBossAppMetaData.class);
+      return appmd.getModules();
+   }
+   
+   private static ModuleMetaData getModuleMetaData(DUIH child)
+   {
+      DUIH parent = getParentDUIH(child);
+      JBossAppMetaData appmd = (JBossAppMetaData) parent.attachments.get(JBossAppMetaData.class);
+      return appmd.getModule(child.relativePath);
+   }
+   
+   private static DUIH getParentDUIH(DUIH child)
+   {
+      return (DUIH) Proxy.getInvocationHandler(child.parent);
+   }
+   
+   /** 
+    * Simple InvocationHandler for mock DeploymentUnit proxies that only handles the 
+    * few methods ModuleNameDeployer is expected to invoke. Bit poor as it's 
+    * tightly coupled to expected implementation, but if ModuleNameDeployer adds some 
+    * new call for some reason, just add handling for it here.
+    */
+   private static class DUIH implements InvocationHandler
+   {
+      private final Map<Object, Object> attachments = new HashMap<Object, Object>();
+      private DeploymentUnit parent;
+      private String simpleName = SIMPLE_DU_WAR;
+      private String relativePath = simpleName;
+
+      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+      {
+         Object result = null;
+         String methodName = method.getName();
+         if ("addAttachment".equals(method.getName()) && args != null && args.length == 2)
+         {
+            attachments.put(args[0], args[1]);
+         }
+         else if ("getAttachment".equals(method.getName()) && args != null && args.length == 1)
+         {
+            result = attachments.get(args[0]);
+         }
+         else if ("getParent".equals(method.getName()) && (args == null || args.length == 0))
+         {
+            result = parent;
+         }
+         else if ("getSimpleName".equals(method.getName()) && (args == null || args.length == 0))
+         {
+            return simpleName;
+         }
+         else if ("getName".equals(method.getName()) && (args == null || args.length == 0))
+         {
+            return simpleName;
+         }
+         else if ("getRelativePath".equals(method.getName()) && (args == null || args.length == 0))
+         {
+            return relativePath;
+         }
+         else if ("toString".equals(method.getName()) && (args == null || args.length == 0))
+         {
+            return "MockDeploymentUnit[" + relativePath + "]";
+         }
+         else
+         {
+            throw new IllegalArgumentException("ModuleNameDeployer invoked unknown method " + 
+                  methodName + " or number of args " + args + 
+                  " -- please add them to this test's mock invocation handler");
+         }
+         return result;
+      }
+      
+      private NamedModule getNamedModuleMetaData(Class<? extends NamedModule> key)
+      {
+         return (NamedModule) attachments.get(key);
+      }
+      
+      private String getModuleName(Class<? extends NamedModule> key)
+      {
+         NamedModule nm = getNamedModuleMetaData(key);
+         return nm == null ? null : nm.getModuleName();
+      }
+   }
+   
+   private class DeploymentTask implements Runnable
+   {
+      private final CountDownLatch startLatch;
+      private final CountDownLatch finishLatch;
+      private final DeploymentUnit unit;
+      private Exception exception;
+      
+      private DeploymentTask(CountDownLatch startLatch, CountDownLatch finishLatch, DUIH duih)
+      {
+         this.startLatch = startLatch;
+         this.finishLatch = finishLatch;
+         this.unit = getDeploymentUnitProxy(duih);
+      }
+
+      public void run()
+      {
+         try
+         {
+            startLatch.countDown();
+            startLatch.await(3, TimeUnit.SECONDS);
+            testee.deploy(unit);
+         }
+         catch (Exception e)
+         {
+            this.exception = e;
+         }
+         finally
+         {
+            finishLatch.countDown();
+         }
+         
+      }
+      
+      
+   }
+
+}


Property changes on: trunk/testsuite/src/main/org/jboss/test/deployers/ear/test/ModuleNameDeployerUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision




More information about the jboss-cvs-commits mailing list