[jboss-cvs] JBossAS SVN: r64309 - in projects/microcontainer/trunk: deployers-impl/src/main/org/jboss/deployers/plugins/main and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 26 11:25:49 EDT 2007


Author: adrian at jboss.org
Date: 2007-07-26 11:25:49 -0400 (Thu, 26 Jul 2007)
New Revision: 64309

Added:
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentDeployer.java
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaData.java
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaDataContainer.java
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentRealDeployer.java
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/test/HeuristicAllOrNothingUnitTestCase.java
Modified:
   projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployerWrapper.java
   projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployersImpl.java
   projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/main/MainDeployerImpl.java
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/AbstractDeployerTest.java
   projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestSimpleDeployer.java
   projects/microcontainer/trunk/deployers-spi/src/main/org/jboss/deployers/spi/deployer/helpers/AbstractRealDeployerWithInput.java
Log:
[JBMICROCONT-168] - Add support for all or nothing deployment heuristic

Modified: projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployerWrapper.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployerWrapper.java	2007-07-26 15:09:24 UTC (rev 64308)
+++ projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployerWrapper.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -166,7 +166,7 @@
       }
       catch (Throwable t)
       {
-         log.error("Error during deploy: " + unit.getName(), t);
+         log.debug("Error during deploy: " + unit.getName(), t);
          throw DeploymentException.rethrowAsDeploymentException("Error during deploy: " + unit.getName(), t);
       }
    }

Modified: projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployersImpl.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployersImpl.java	2007-07-26 15:09:24 UTC (rev 64308)
+++ projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/deployers/DeployersImpl.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -378,9 +378,9 @@
             try
             {
                controller.uninstall(deploymentControllerContext.getName());
-               context.setState(DeploymentState.UNDEPLOYED);
+               setState(context, DeploymentState.UNDEPLOYED, null);
                // TODO JBMICROCONT-182 perform with the deployer that created the classloader?
-               context.removeClassLoader();
+               removeClassLoader(context);
                log.debug("Fully Undeployed " + context.getName());
             }
             catch (Throwable t)
@@ -408,8 +408,11 @@
             }
             catch (Throwable t)
             {
+               // Set the error on the parent
                context.setState(DeploymentState.ERROR);
                context.setProblem(t);
+               // Set the children to not deployed
+               setState(context, DeploymentState.UNDEPLOYED, DeploymentState.DEPLOYING);
             }
          }
 
@@ -478,7 +481,6 @@
             deploymentsMissingDeployer.add(context.getName());
       }
       
-      
       if (controller != null)
       {
          List<ControllerState> states = controller.getStates();
@@ -585,15 +587,14 @@
       DeploymentContext deploymentContext = deploymentControllerContext.getDeploymentContext();
       try
       {
-         doInstall(deploymentContext, stageName, true);
+         doInstall(deploymentContext, stageName, true, true);
       }
       finally
       {
          if (ControllerState.INSTALLED.equals(toState) && DeploymentState.DEPLOYING.equals(deploymentContext.getState()))
          {
             log.debug("Fully Deployed " + context.getName());
-            deploymentContext.setState(DeploymentState.DEPLOYED);
-            
+            setState(deploymentContext, DeploymentState.DEPLOYED, null);
          }
       }
    }
@@ -603,10 +604,11 @@
     * 
     * @param context the context
     * @param stageName the stage
+    * @param doChildren whether to do children
     * @param doComponents whether to do components
     * @throws Throwable for any problem
     */
-   protected void doInstall(DeploymentContext context, String stageName, boolean doComponents) throws Throwable
+   protected void doInstall(DeploymentContext context, String stageName, boolean doChildren, boolean doComponents) throws Throwable
    {
       List<Deployer> theDeployers = getDeployersList(stageName);
       
@@ -621,7 +623,7 @@
             while (i < theDeployers.size())
             {
                Deployer deployer = theDeployers.get(i);
-               doInstall(deployer, context, doComponents);
+               doInstall(deployer, context, doChildren, doComponents);
                ++i;
             }
          }
@@ -629,11 +631,17 @@
          {
             context.setState(DeploymentState.ERROR);
             context.setProblem(t);
+            
+            // Unwind the previous deployments
             for (int j = i-1; j >= 0; --j)
             {
                Deployer deployer = theDeployers.get(j);
-               doUninstall(deployer, context, true);
+               doUninstall(deployer, context, true, true);
             }
+            
+            // It can happen that subdeployments are not processed if the parent fails immediately
+            // so there is no callback to undeploy when nothing was done
+            setState(context, DeploymentState.UNDEPLOYED, DeploymentState.DEPLOYING);
             throw t;
          }
       }
@@ -644,10 +652,11 @@
     * 
     * @param deployer the deployer
     * @param context the context
+    * @param doChildren whether to do children
     * @param doComponents whether to do components
     * @throws Throwable for any problem
     */
-   protected void doInstall(Deployer deployer, DeploymentContext context, boolean doComponents) throws Throwable
+   protected void doInstall(Deployer deployer, DeploymentContext context, boolean doChildren, boolean doComponents) throws Throwable
    {
       List<DeploymentContext> currentComponents = context.getComponents();
       // Take a copy of the components so we don't start looping on newly added components
@@ -658,10 +667,21 @@
 
       DeploymentUnit unit = context.getDeploymentUnit();
       if (isRelevant(deployer, unit, context.isTopLevel(), context.isComponent()))
-         deployer.deploy(unit);
+      {
+         try
+         {
+            deployer.deploy(unit);
+         }
+         catch (DeploymentException e)
+         {
+            context.setState(DeploymentState.ERROR);
+            context.setProblem(e);
+            throw e;
+         }
+      }
       else if (log.isTraceEnabled())
          log.trace("Deployer " + deployer + " not relevant for " + context.getName());
-
+      
       if (doComponents && components != null)
       {
          try
@@ -671,7 +691,7 @@
                DeploymentContext component = components.get(i);
                try
                {
-                  doInstall(deployer, component, true);
+                  doInstall(deployer, component, false, true);
                }
                catch (DeploymentException e)
                {
@@ -679,7 +699,7 @@
                   for (int j = i - 1; j >= 0; --j)
                   {
                      component = components.get(j);
-                     doUninstall(deployer, component, true);
+                     doUninstall(deployer, component, false, true);
                   }
                   throw e;
                }
@@ -687,10 +707,43 @@
          }
          catch (DeploymentException e)
          {
-            doUninstall(deployer, context, false);
+            // Just undeploy this context
+            doUninstall(deployer, context, false, false);
             throw e;
          }
       }
+
+      List<DeploymentContext> children = context.getChildren();
+      if (doChildren && children != null)
+      {
+         try
+         {
+            for (int i = 0; i < children.size(); ++i)
+            {
+               DeploymentContext child = children.get(i);
+               try
+               {
+                  doInstall(deployer, child, true, true);
+               }
+               catch (DeploymentException e)
+               {
+                  // Unwind the previous children
+                  for (int j = i - 1; j >= 0; --j)
+                  {
+                     child = children.get(j);
+                     doUninstall(deployer, child, true, true);
+                  }
+                  throw e;
+               }
+            }
+         }
+         catch (DeploymentException e)
+         {
+            // Undeploy the context but the children are already unwound
+            doUninstall(deployer, context, false, true);
+            throw e;
+         }
+      }         
    }
    
    public void uninstall(ControllerContext context, ControllerState fromState, ControllerState toState)
@@ -699,7 +752,7 @@
       String stageName = fromState.getStateString();
       
       DeploymentContext deploymentContext = deploymentControllerContext.getDeploymentContext();
-      doUninstall(deploymentContext, stageName, true);
+      doUninstall(deploymentContext, stageName, true, true);
    }
 
    /**
@@ -707,9 +760,10 @@
     * 
     * @param context the context
     * @param stageName the stage
+    * @param doChildren whether to do children
     * @param doComponents whether to do components
     */
-   protected void doUninstall(DeploymentContext context, String stageName, boolean doComponents)
+   protected void doUninstall(DeploymentContext context, String stageName, boolean doChildren, boolean doComponents)
    {
       List<Deployer> theDeployers = getDeployersList(stageName);
       
@@ -721,7 +775,7 @@
          for (int i = theDeployers.size()-1; i >= 0; --i)
          {
             Deployer deployer = theDeployers.get(i);
-            doUninstall(deployer, context, doComponents);
+            doUninstall(deployer, context, doChildren, doComponents);
          }
       }
    }
@@ -731,10 +785,24 @@
     *
     * @param deployer the deployer
     * @param context the context
+    * @param doChildren whether to do children
     * @param doComponents whether to do components
     */
-   protected void doUninstall(Deployer deployer, DeploymentContext context, boolean doComponents)
+   protected void doUninstall(Deployer deployer, DeploymentContext context, boolean doChildren, boolean doComponents)
    {
+      if (doChildren)
+      {
+         List<DeploymentContext> children = context.getChildren();
+         if (children != null && children.isEmpty() == false)
+         {
+            for (int i = children.size()-1; i >=  0; --i)
+            {
+               DeploymentContext child = children.get(i);
+               doUninstall(deployer, child, true, true);
+            }
+         }
+      }
+
       if (doComponents)
       {
          List<DeploymentContext> components = context.getComponents();
@@ -743,7 +811,7 @@
             for (int i = components.size()-1; i >=  0; --i)
             {
                DeploymentContext component = components.get(i);
-               doUninstall(deployer, component, doComponents);
+               doUninstall(deployer, component, false, true);
             }
          }
       }
@@ -816,117 +884,38 @@
       return sorter.sortDeployers(original, newDeployer);
    }
 
-/*
-   */
-/**
-    * Sort the deployers
+   /**
+    * Set the deployment state for a context and its children
     * 
-    * @param original the original deployers
-    * @param newDeployer the new deployer
-    * @return the sorted deployers
+    * @param context the context
+    * @param state the state
+    * @param ifState the ifState
     */
-/*
-   protected List<Deployer> sort(List<Deployer> original, Deployer newDeployer)
+   private static void setState(DeploymentContext context, DeploymentState state, DeploymentState ifState)
    {
-      List<Deployer> result = new ArrayList<Deployer>(original);
-      result.add(newDeployer);
-
-      // Bubble sort :-)
-      boolean changed = true;
-      while (changed)
+      if (ifState == null || ifState.equals(context.getState()))
+         context.setState(state);
+      List<DeploymentContext> children = context.getChildren();
+      if (children != null && children.isEmpty() == false)
       {
-         changed = false;
-
-         for (int i = 0; i < result.size() -1; ++i)
-         {
-            int j = i+1;
-
-            Deployer one = result.get(i);
-            Deployer two = result.get(j);
-
-            Set<String> oneOutputs = one.getOutputs();
-
-            // Don't move if one outputs something for two
-            boolean swap = true;
-            if (oneOutputs.isEmpty() == false)
-            {
-               Set<String> twoInputs = two.getInputs();
-               for (String output : oneOutputs)
-               {
-                  if (twoInputs.contains(output))
-                  {
-                     swap = false;
-                     break;
-                  }
-               }
-
-               if (swap == false)
-                  continue;
-            }
-
-            // Move if one inputs from two
-            swap = false;
-            Set<String> twoOutputs = two.getOutputs();
-            if (twoOutputs.isEmpty() == false)
-            {
-               Set<String> oneInputs = one.getInputs();
-               for (String output : twoOutputs)
-               {
-                  if (oneInputs.contains(output))
-                  {
-                     swap = true;
-                     break;
-                  }
-               }
-            }
-
-            // Move if the order is not correct
-            if (Ordered.COMPARATOR.compare(one, two) > 0)
-               swap = true;
-
-            if (swap)
-            {
-               Collections.swap(result, i, j);
-               changed = true;
-            }
-         }
+         for (DeploymentContext child : children)
+            setState(child, state, ifState);
       }
+   }
 
-      // Now check the consistency
-      // The new deployer should be before anything that accepts its outputs
-      Set<String> outputs = newDeployer.getOutputs();
-      if  (outputs.isEmpty() == false)
+   /**
+    * Remove a classloader for a context and its children
+    * 
+    * @param context the context
+    */
+   private static void removeClassLoader(DeploymentContext context)
+   {
+      context.removeClassLoader();
+      List<DeploymentContext> children = context.getChildren();
+      if (children != null && children.isEmpty() == false)
       {
-         int location = result.indexOf(newDeployer);
-         for (int i = 0; i < location; ++i)
-         {
-            Deployer other = result.get(i);
-            Set<String> otherInputs = other.getInputs();
-            Set<String> otherOutputs = other.getOutputs();
-            if (otherInputs.isEmpty() == false)
-            {
-               for (String input : otherInputs)
-               {
-                  // Ignore transient usage
-                  if (outputs.contains(input) && otherOutputs.contains(input) == false)
-                  {
-                     StringBuilder builder = new StringBuilder();
-                     builder.append("Cannot add ").append(newDeployer).append(" it will cause a loop\n");
-                     for (Deployer temp : result)
-                     {
-                        builder.append(temp);
-                        builder.append("{inputs=").append(temp.getInputs());
-                        builder.append(" outputs=").append(temp.getOutputs());
-                        builder.append("}\n");
-                     }
-                     throw new IllegalStateException(builder.toString());
-                  }
-               }
-            }
-         }
+         for (DeploymentContext child : children)
+            removeClassLoader(child);
       }
-
-      return result;
    }
-*/
 }

Modified: projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/main/MainDeployerImpl.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/main/MainDeployerImpl.java	2007-07-26 15:09:24 UTC (rev 64308)
+++ projects/microcontainer/trunk/deployers-impl/src/main/org/jboss/deployers/plugins/main/MainDeployerImpl.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -504,8 +504,12 @@
          return;
       }
       context.setState(DeploymentState.DEPLOYING);
-      log.debug("Scheduling deployment: " + context.getName());
-      deploy.add(context);
+      DeploymentContext parent = context.getParent();
+      log.debug("Scheduling deployment: " + context.getName() + " parent=" + parent);
+
+      // Process the parent only
+      if (context.isTopLevel())
+         deploy.add(context);
       
       // Add all the children
       List<DeploymentContext> children = context.getChildren();
@@ -533,8 +537,12 @@
          return;
       }
       context.setState(DeploymentState.UNDEPLOYING);
-      log.debug("Scheduling undeployment: " + name);
-      undeploy.add(context);
+      DeploymentContext parent = context.getParent();
+      log.debug("Scheduling undeployment: " + name + " parent=" + parent);
+
+      // Process the top level only
+      if (context.isTopLevel())
+         undeploy.add(context);
       
       // Remove all the children
       List<DeploymentContext> children = context.getChildren();

Modified: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/AbstractDeployerTest.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/AbstractDeployerTest.java	2007-07-26 15:09:24 UTC (rev 64308)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/AbstractDeployerTest.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -31,8 +31,10 @@
 import org.jboss.deployers.plugins.deployers.DeployerWrapper;
 import org.jboss.deployers.plugins.deployers.DeployersImpl;
 import org.jboss.deployers.plugins.main.MainDeployerImpl;
+import org.jboss.deployers.spi.attachments.PredeterminedManagedObjectAttachments;
 import org.jboss.deployers.spi.deployer.Deployer;
 import org.jboss.deployers.spi.deployer.Deployers;
+import org.jboss.deployers.spi.structure.ContextInfo;
 import org.jboss.deployers.structure.spi.DeploymentContext;
 import org.jboss.deployers.structure.spi.StructuralDeployers;
 import org.jboss.deployers.structure.spi.StructureBuilder;
@@ -48,6 +50,8 @@
  */
 public abstract class AbstractDeployerTest extends BaseTestCase
 {
+   DeploymentFactory factory = new DeploymentFactory();
+
    public AbstractDeployerTest(String name)
    {
       super(name);
@@ -136,14 +140,18 @@
    protected Deployment createSimpleDeployment(String name)
    {
       AbstractDeployment unit = new AbstractDeployment(name);
-      DeploymentFactory factory = new DeploymentFactory();
       factory.addContext(unit, "");
       return unit;
    }
+   
+   protected ContextInfo addChild(PredeterminedManagedObjectAttachments parent, String name)
+   {
+      return factory.addContext(parent, name);
+   }
 
    @Override
    protected void configureLogging()
    {
-      enableTrace("org.jboss.deployers");
+      //enableTrace("org.jboss.deployers");
    }
 }

Added: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentDeployer.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentDeployer.java	                        (rev 0)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentDeployer.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.test.deployers.deployer.support;
+
+import java.util.List;
+
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.spi.deployer.helpers.AbstractComponentDeployer;
+import org.jboss.deployers.spi.deployer.helpers.DeploymentVisitor;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+
+/**
+ * TestDeploymentDeployer.
+ * 
+ * @author <a href="adrian at jboss.org">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestComponentDeployer extends AbstractComponentDeployer<TestComponentMetaDataContainer, TestComponentMetaData>
+{
+   public TestComponentDeployer(int order)
+   {
+      setDeploymentVisitor(new TestComponentMetaDataContainerVisitor());
+      setComponentVisitor(new TestComponentMetaDataVisitor());
+      setRelativeOrder(order);
+   }
+
+   protected static void addTestComponent(DeploymentUnit unit, TestComponentMetaData test)
+   {
+      DeploymentUnit component = unit.addComponent(test.name);
+      component.addAttachment(TestComponentMetaData.class, test);
+   }
+
+   protected static void removeTestComponent(DeploymentUnit unit, TestComponentMetaData test)
+   {
+      unit.removeComponent(test.name);
+   }
+   
+   public class TestComponentMetaDataContainerVisitor implements DeploymentVisitor<TestComponentMetaDataContainer>
+   {
+      public Class<TestComponentMetaDataContainer> getVisitorType()
+      {
+         return TestComponentMetaDataContainer.class;
+      }
+
+      public void deploy(DeploymentUnit unit, TestComponentMetaDataContainer deployment) throws DeploymentException
+      {
+         try
+         {
+            List<TestComponentMetaData> tests = deployment.componentMetaData;
+            if (tests == null || tests.isEmpty())
+               return;
+            
+            for (TestComponentMetaData test : tests)
+               addTestComponent(unit, test);
+         }
+         catch (Throwable t)
+         {
+            throw DeploymentException.rethrowAsDeploymentException("Error deploying: " + deployment, t);
+         }
+      }
+
+      public void undeploy(DeploymentUnit unit, TestComponentMetaDataContainer deployment)
+      {
+         List<TestComponentMetaData> tests = deployment.componentMetaData;
+         if (tests == null)
+            return;
+         
+         for (TestComponentMetaData test : tests)
+         {
+            unit.removeComponent(test.name);
+         }
+      }
+   }
+
+   public static class TestComponentMetaDataVisitor implements DeploymentVisitor<TestComponentMetaData>
+   {
+      public Class<TestComponentMetaData> getVisitorType()
+      {
+         return TestComponentMetaData.class;
+      }
+
+      public void deploy(DeploymentUnit unit, TestComponentMetaData deployment) throws DeploymentException
+      {
+         addTestComponent(unit, deployment);
+      }
+
+      public void undeploy(DeploymentUnit unit, TestComponentMetaData deployment)
+      {
+         removeTestComponent(unit, deployment);
+      }
+   }
+}

Added: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaData.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaData.java	                        (rev 0)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaData.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -0,0 +1,46 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.deployers.deployer.support;
+
+/**
+ * TestComponentMetaData.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestComponentMetaData
+{
+   public String name;
+   
+   public boolean fail = false;
+   
+   public TestComponentMetaData(String name, boolean fail)
+   {
+      this.name = name;
+      this.fail = fail;
+   }
+   
+   public String toString()
+   {
+      return name;
+   }
+}

Added: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaDataContainer.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaDataContainer.java	                        (rev 0)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentMetaDataContainer.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -0,0 +1,43 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.deployers.deployer.support;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TestComponentMetaDataContainer.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestComponentMetaDataContainer
+{
+   public List<TestComponentMetaData> componentMetaData;
+   
+   public TestComponentMetaDataContainer(TestComponentMetaData... metaDatas)
+   {
+      componentMetaData = new ArrayList<TestComponentMetaData>();
+      for (TestComponentMetaData metaData: metaDatas)
+         componentMetaData.add(metaData);
+   }
+}

Added: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentRealDeployer.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentRealDeployer.java	                        (rev 0)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestComponentRealDeployer.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -0,0 +1,69 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.deployers.deployer.support;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployerWithInput;
+import org.jboss.deployers.spi.deployer.helpers.DeploymentVisitor;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+
+/**
+ * TestSimpleDeployer.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestComponentRealDeployer extends AbstractRealDeployerWithInput<TestComponentMetaData>
+{
+   public Set<TestComponentMetaData> deployed = new HashSet<TestComponentMetaData>();
+   public Set<TestComponentMetaData> undeployed = new HashSet<TestComponentMetaData>();
+   
+   public TestComponentRealDeployer(int order)
+   {
+      setDeploymentVisitor(new TestComponentMetaDataVisitor());
+      setWantComponents(true);
+      setRelativeOrder(order);
+   }
+   
+   public class TestComponentMetaDataVisitor implements DeploymentVisitor<TestComponentMetaData>
+   {
+      public Class<TestComponentMetaData> getVisitorType()
+      {
+         return TestComponentMetaData.class;
+      }
+
+      public void deploy(DeploymentUnit unit, TestComponentMetaData deployment) throws DeploymentException
+      {
+         deployed.add(deployment);
+         if (deployment.fail)
+            throw new DeploymentException("Asked to fail");
+      }
+
+      public void undeploy(DeploymentUnit unit, TestComponentMetaData deployment)
+      {
+         undeployed.add(deployment);
+      }
+   }
+}

Modified: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestSimpleDeployer.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestSimpleDeployer.java	2007-07-26 15:09:24 UTC (rev 64308)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/support/TestSimpleDeployer.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -67,7 +67,7 @@
    {
       setRelativeOrder(relativeOrder);
       this.setType("test");
-      name = super.toString();
+      name = "TestSimpleDeployer" + relativeOrder;
    }
    
    public TestSimpleDeployer(DeploymentStage stage)
@@ -124,12 +124,16 @@
 
    public void deploy(DeploymentUnit unit) throws DeploymentException
    {
+      log.debug(this + " deploy  : " + unit.getName());
       unit.getTypes().add(getType());
       deployed.put(unit.getName(), ++order);
+      if (this.equals(unit.getAttachment("fail")))
+         throw new DeploymentException("Asked to fail");
    }
 
    public void undeploy(DeploymentUnit unit)
    {
+      log.debug(this + " undeploy: " + unit.getName());
       undeployed.put(unit.getName(), ++order);
    }
 }

Added: projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/test/HeuristicAllOrNothingUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/test/HeuristicAllOrNothingUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/deployers-impl/src/tests/org/jboss/test/deployers/deployer/test/HeuristicAllOrNothingUnitTestCase.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -0,0 +1,594 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.deployers.deployer.test;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.jboss.deployers.client.spi.DeployerClient;
+import org.jboss.deployers.client.spi.Deployment;
+import org.jboss.deployers.spi.DeploymentState;
+import org.jboss.deployers.spi.attachments.MutableAttachments;
+import org.jboss.deployers.spi.attachments.PredeterminedManagedObjectAttachments;
+import org.jboss.deployers.spi.deployer.Deployer;
+import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.test.deployers.AbstractDeployerTest;
+import org.jboss.test.deployers.deployer.support.TestComponentDeployer;
+import org.jboss.test.deployers.deployer.support.TestComponentMetaData;
+import org.jboss.test.deployers.deployer.support.TestComponentMetaDataContainer;
+import org.jboss.test.deployers.deployer.support.TestComponentRealDeployer;
+import org.jboss.test.deployers.deployer.support.TestSimpleDeployer;
+
+/**
+ * DeployerProtocolUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class HeuristicAllOrNothingUnitTestCase extends AbstractDeployerTest
+{
+   private TestSimpleDeployer deployer1 = new TestSimpleDeployer(1);
+   private TestSimpleDeployer deployer2 = new TestSimpleDeployer(2);
+   private TestComponentDeployer deployer3 = new TestComponentDeployer(3);
+   private TestComponentRealDeployer deployer4 = new TestComponentRealDeployer(4);
+   
+   private static String parentName = "parent";
+   private static String childPath = "child";
+   private static String childName = parentName + "/" + childPath;
+   private static String child1Path = "child1";
+   private static String child1Name = parentName + "/" + child1Path;
+   private static String child2Path = "child2";
+   private static String child2Name = parentName + "/" + child2Path;
+
+   private static Set<String> expectedNothing = Collections.emptySet();
+   private static Set<String> expectedParent = makeSet(parentName);
+   private static Set<String> expectedParentChild = makeSet(parentName, childName);
+   private static Set<String> expectedParentChild1 = makeSet(parentName, child1Name);
+   private static Set<String> expectedParentChild1Child2 = makeSet(parentName, child1Name, child2Name);
+
+   private static TestComponentMetaData parentmd1 = new TestComponentMetaData(parentName + ".1", false);
+   private static TestComponentMetaData parentmd1fail = new TestComponentMetaData(parentName + ".1", true);
+   private static TestComponentMetaData parentmd2 = new TestComponentMetaData(parentName + ".2", false);
+   private static TestComponentMetaData parentmd2fail = new TestComponentMetaData(parentName + ".2", true);
+   private static TestComponentMetaData child1md1 = new TestComponentMetaData(child1Name + ".1", false);
+   private static TestComponentMetaData child1md1fail = new TestComponentMetaData(child1Name + ".1", true);
+   private static TestComponentMetaData child1md2 = new TestComponentMetaData(child1Name + ".2", false);
+   private static TestComponentMetaData child1md2fail = new TestComponentMetaData(child1Name + ".2", true);
+   private static TestComponentMetaData child2md1 = new TestComponentMetaData(child2Name + ".1", false);
+   private static TestComponentMetaData child2md1fail = new TestComponentMetaData(child2Name + ".1", true);
+   private static TestComponentMetaData child2md2 = new TestComponentMetaData(child2Name + ".2", false);
+   private static TestComponentMetaData child2md2fail = new TestComponentMetaData(child2Name + ".2", true);
+   
+   private static TestComponentMetaDataContainer parentmd = new TestComponentMetaDataContainer(parentmd1, parentmd2);
+   private static TestComponentMetaDataContainer parentmdfail1 = new TestComponentMetaDataContainer(parentmd1fail, parentmd2);
+   private static TestComponentMetaDataContainer parentmdfail2 = new TestComponentMetaDataContainer(parentmd1, parentmd2fail);
+   private static TestComponentMetaDataContainer child1md = new TestComponentMetaDataContainer(child1md1, child1md2);
+   private static TestComponentMetaDataContainer child1mdfail1 = new TestComponentMetaDataContainer(child1md1fail, child1md2);
+   private static TestComponentMetaDataContainer child1mdfail2 = new TestComponentMetaDataContainer(child1md1, child1md2fail);
+   private static TestComponentMetaDataContainer child2md = new TestComponentMetaDataContainer(child2md1, child2md2);
+   private static TestComponentMetaDataContainer child2mdfail1 = new TestComponentMetaDataContainer(child2md1fail, child2md2);
+   private static TestComponentMetaDataContainer child2mdfail2 = new TestComponentMetaDataContainer(child2md1, child2md2fail);
+   
+   private static Set<TestComponentMetaData> expectedNone = Collections.emptySet();
+   private static Set<TestComponentMetaData> expectedPmd1Fail = makeSet(parentmd1fail);
+   private static Set<TestComponentMetaData> expectedPmd1 = makeSet(parentmd1);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2Fail = makeSet(parentmd1, parentmd2fail);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2 = makeSet(parentmd1, parentmd2);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1Fail = makeSet(parentmd1, parentmd2, child1md1fail);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1 = makeSet(parentmd1, parentmd2, child1md1);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1C1md2Fail = makeSet(parentmd1, parentmd2, child1md1, child1md2fail);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1C1md2 = makeSet(parentmd1, parentmd2, child1md1, child1md2);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1C1md2C2md1Fail = makeSet(parentmd1, parentmd2, child1md1, child1md2, child2md1fail);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1C1md2C2md1 = makeSet(parentmd1, parentmd2, child1md1, child1md2, child2md1);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1C1md2C2md1C2md2Fail = makeSet(parentmd1, parentmd2, child1md1, child1md2, child2md1, child2md2fail);
+   private static Set<TestComponentMetaData> expectedPmd1Pmd2C1md1C1md2C2md1C2md2 = makeSet(parentmd1, parentmd2, child1md1, child1md2, child2md1, child2md2);
+   
+   @SuppressWarnings("unchecked")
+   private static <T> Set<T> makeSet(T... objects)
+   {
+      Set<T> result = new HashSet();
+      for (T object : objects)
+         result.add(object);
+      return result;
+   }
+   
+   public static Test suite()
+   {
+      return new TestSuite(HeuristicAllOrNothingUnitTestCase.class);
+   }
+   
+   public HeuristicAllOrNothingUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testDeployParentNoErrors() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParent, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedParent, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(deployment.getName()));
+   }
+
+   public void testDeployParentFailInParentDeployer1() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      makeFail(deployment, deployer1);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParent, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedNothing, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+   }
+
+   public void testDeployParentFailInParentDeployer2() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      makeFail(deployment, deployer2);
+      main.addDeployment(deployment);
+      main.process();
+
+      Set<String> expected = new HashSet<String>();
+      expected.add(deployment.getName());
+      assertEquals(expectedParent, deployer1.getDeployedUnits());
+      assertEquals(expectedParent, deployer1.getUndeployedUnits());
+      assertEquals(expectedParent, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+   }
+
+   public void testDeployParentOneChildNoErrors() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addChild(deployment, childPath); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(childName));
+   }
+   
+   public void testDeployParentOneChildFailInParentDeployer1() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      makeFail(deployment, deployer1);
+      addChild(deployment, childPath); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParent, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedNothing, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(childName));
+   }
+   
+   public void testDeployParentOneChildFailInParentDeployer2() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      makeFail(deployment, deployer2);
+      addChild(deployment, "child"); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild, deployer1.getUndeployedUnits());
+      assertEquals(expectedParent, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(childName));
+   }
+   
+   public void testDeployParentOneChildFailInChildDeployer1() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      ContextInfo child = addChild(deployment, childPath); 
+      makeFail(child, deployer1);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild, deployer1.getDeployedUnits());
+      assertEquals(expectedParent, deployer1.getUndeployedUnits());
+      assertEquals(expectedNothing, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(childName));
+   }
+   
+   public void testDeployParentOneChildFailInChildDeployer2() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      ContextInfo child = addChild(deployment, childPath); 
+      makeFail(child, deployer2);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild, deployer2.getDeployedUnits());
+      assertEquals(expectedParent, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(childName));
+   }
+
+   public void testDeployParentMultipleChildrenNoErrors() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addChild(deployment, child1Path); 
+      addChild(deployment, child2Path); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenFailInParentDeployer1() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      makeFail(deployment, deployer1);
+      addChild(deployment, child1Path); 
+      addChild(deployment, child2Path); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParent, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedNothing, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenFailInParentDeployer2() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      makeFail(deployment, deployer2);
+      addChild(deployment, child1Path); 
+      addChild(deployment, child2Path); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParent, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenFailInChild1Deployer1() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      ContextInfo child1 = addChild(deployment, child1Path); 
+      makeFail(child1, deployer1);
+      addChild(deployment, child2Path); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1, deployer1.getDeployedUnits());
+      assertEquals(expectedParent, deployer1.getUndeployedUnits());
+      assertEquals(expectedNothing, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenFailInChild1Deployer2() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      ContextInfo child1 = addChild(deployment, child1Path); 
+      makeFail(child1, deployer2);
+      addChild(deployment, child2Path); 
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1, deployer2.getDeployedUnits());
+      assertEquals(expectedParent, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenFailInChild2Deployer1() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addChild(deployment, child1Path); 
+      ContextInfo child2 = addChild(deployment, child2Path); 
+      makeFail(child2, deployer1);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1, deployer1.getUndeployedUnits());
+      assertEquals(expectedNothing, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenFailInChild2Deployer2() throws Exception
+   {
+      DeployerClient main = getMainDeployer();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addChild(deployment, child1Path); 
+      ContextInfo child2 = addChild(deployment, child2Path); 
+      makeFail(child2, deployer2);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1, deployer2.getUndeployedUnits());
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsNoErrors() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmd);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1md);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2md);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedNothing, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedNothing, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Pmd2C1md1C1md2C2md1C2md2, deployer4.deployed);
+      assertEquals(expectedNone, deployer4.undeployed);
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.DEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsParentComponent1Fails() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmdfail1);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1md);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2md);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Fail, deployer4.deployed);
+      assertEquals(expectedNone, deployer4.undeployed);
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsParentComponent2Fails() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmdfail2);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1md);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2md);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Pmd2Fail, deployer4.deployed);
+      assertEquals(expectedPmd1, deployer4.undeployed);
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsChild1Component1Fails() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmd);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1mdfail1);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2md);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Pmd2C1md1Fail, deployer4.deployed);
+      assertEquals(expectedPmd1Pmd2, deployer4.undeployed);
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsChild1Component2Fails() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmd);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1mdfail2);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2md);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Pmd2C1md1C1md2Fail, deployer4.deployed);
+      assertEquals(expectedPmd1Pmd2C1md1, deployer4.undeployed);
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsChild2Component1Fails() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmd);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1md);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2mdfail1);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Pmd2C1md1C1md2C2md1Fail, deployer4.deployed);
+      assertEquals(expectedPmd1Pmd2C1md1C1md2, deployer4.undeployed);
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child2Name));
+   }
+
+   public void testDeployParentMultipleChildrenAndComponentsChild2Component2Fails() throws Exception
+   {
+      DeployerClient main = getMainDeployerWithComponentDeployers();
+      
+      Deployment deployment = createSimpleDeployment(parentName);
+      addMetaData(deployment, parentmd);
+      ContextInfo child1 = addChild(deployment, child1Path);
+      addMetaData(child1, child1md);
+      ContextInfo child2 = addChild(deployment, child2Path);
+      addMetaData(child2, child2mdfail2);
+      main.addDeployment(deployment);
+      main.process();
+
+      assertEquals(expectedParentChild1Child2, deployer1.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer1.getUndeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getDeployedUnits());
+      assertEquals(expectedParentChild1Child2, deployer2.getUndeployedUnits());
+      assertEquals(expectedPmd1Pmd2C1md1C1md2C2md1C2md2Fail, deployer4.deployed);
+      assertEquals(expectedPmd1Pmd2C1md1C1md2C2md1, deployer4.undeployed);
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(deployment.getName()));
+      assertEquals(DeploymentState.UNDEPLOYED, main.getDeploymentState(child1Name));
+      assertEquals(DeploymentState.ERROR, main.getDeploymentState(child2Name));
+   }
+
+   protected static void addMetaData(PredeterminedManagedObjectAttachments attachments, TestComponentMetaDataContainer md)
+   {
+      MutableAttachments mutable = (MutableAttachments) attachments.getPredeterminedManagedObjects();
+      mutable.addAttachment(TestComponentMetaDataContainer.class, md);
+   }
+   
+   protected static void makeFail(PredeterminedManagedObjectAttachments attachments, Deployer deployer)
+   {
+      MutableAttachments mutable = (MutableAttachments) attachments.getPredeterminedManagedObjects();
+      mutable.addAttachment("fail", deployer);
+   }
+   
+   protected DeployerClient getMainDeployer()
+   {
+      return createMainDeployer(deployer1, deployer2);
+   }
+   
+   protected DeployerClient getMainDeployerWithComponentDeployers()
+   {
+      return createMainDeployer(deployer1, deployer2, deployer3, deployer4);
+   }
+}

Modified: projects/microcontainer/trunk/deployers-spi/src/main/org/jboss/deployers/spi/deployer/helpers/AbstractRealDeployerWithInput.java
===================================================================
--- projects/microcontainer/trunk/deployers-spi/src/main/org/jboss/deployers/spi/deployer/helpers/AbstractRealDeployerWithInput.java	2007-07-26 15:09:24 UTC (rev 64308)
+++ projects/microcontainer/trunk/deployers-spi/src/main/org/jboss/deployers/spi/deployer/helpers/AbstractRealDeployerWithInput.java	2007-07-26 15:25:49 UTC (rev 64309)
@@ -21,6 +21,8 @@
  */
 package org.jboss.deployers.spi.deployer.helpers;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 import org.jboss.deployers.spi.DeploymentException;
@@ -84,6 +86,7 @@
       setInput(input);
    }
 
+   @SuppressWarnings("unchecked")
    public void deploy(DeploymentUnit unit) throws DeploymentException
    {
       if (visitor == null)
@@ -96,15 +99,29 @@
          return;
       }
 
+      List<T> visited = new ArrayList();
       try
       {
          Set<? extends T> deployments = unit.getAllMetaData(getInput());
          for (T deployment : deployments)
+         {
             visitor.deploy(unit, deployment);
+            visited.add(deployment);
+         }
       }
       catch (Throwable t)
       {
-         undeploy(unit);
+         for (int i = visited.size()-1; i >= 0; --i)
+         {
+            try
+            {
+               visitor.undeploy(unit, visited.get(i));
+            }
+            catch (Throwable ignored)
+            {
+               log.warn("Error during undeploy: " + unit.getName(), ignored);
+            }
+         }
          throw DeploymentException.rethrowAsDeploymentException("Error deploying: " + unit.getName(), t);
       }
    }




More information about the jboss-cvs-commits mailing list