Selaa lähdekoodia

AMBARI-1194. API support for cascade delete of a specified cluster (Tom Beerbower via mahadev)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1437832 13f79535-47bb-0310-9956-ffa450edef68
Mahadev Konar 12 vuotta sitten
vanhempi
commit
8abee8ac5c

+ 3 - 0
CHANGES.txt

@@ -15,6 +15,9 @@ Trunk (unreleased changes):
  AMBARI-1163. During agent registration and heartbeat, send information about
  various hadoop artifacts back to Ambari. (Nate Cole via mahadev)
 
+ AMBARI-1194. API support for cascade delete of a specified cluster
+ (Tom Beerbower via mahadev)
+
  IMPROVEMENTS
 
  AMBARI-1236. Display a progress bar during deploy prep. (yusaku)

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java

@@ -159,7 +159,7 @@ public class ClusterEntity {
 
   private Collection<StageEntity> stages;
 
-  @OneToMany(mappedBy = "cluster")
+  @OneToMany(mappedBy = "cluster", cascade = CascadeType.REMOVE)
   public Collection<StageEntity> getStages() {
     return stages;
   }

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java

@@ -245,7 +245,7 @@ public class HostRoleCommandEntity {
 
   private ExecutionCommandEntity executionCommand;
 
-  @OneToOne(mappedBy = "hostRoleCommand")
+  @OneToOne(mappedBy = "hostRoleCommand", cascade = CascadeType.REMOVE)
   public ExecutionCommandEntity getExecutionCommand() {
     return executionCommand;
   }
@@ -277,4 +277,4 @@ public class HostRoleCommandEntity {
   public void setHost(HostEntity host) {
     this.host = host;
   }
-}
+}

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StageEntity.java

@@ -111,7 +111,7 @@ public class StageEntity {
 
   private Collection<HostRoleCommandEntity> hostRoleCommands;
 
-  @OneToMany(mappedBy = "stage")
+  @OneToMany(mappedBy = "stage", cascade = CascadeType.REMOVE)
   public Collection<HostRoleCommandEntity> getHostRoleCommands() {
     return hostRoleCommands;
   }
@@ -122,7 +122,7 @@ public class StageEntity {
 
   private Collection<RoleSuccessCriteriaEntity> roleSuccessCriterias;
 
-  @OneToMany(mappedBy = "stage")
+  @OneToMany(mappedBy = "stage", cascade = CascadeType.REMOVE)
   public Collection<RoleSuccessCriteriaEntity> getRoleSuccessCriterias() {
     return roleSuccessCriterias;
   }

+ 3 - 7
ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java

@@ -487,26 +487,22 @@ public class ServiceComponentImpl implements ServiceComponent {
 
   @Override
   public synchronized boolean canBeRemoved() {
-    State state = getDesiredState();
-    if (state != State.INIT
-        && state != State.UNINSTALLED) {
+    if (!getDesiredState().isRemovableState()) {
       return false;
     }
 
-    boolean safeToRemove = true;
     for (ServiceComponentHost sch : hostComponents.values()) {
       if (!sch.canBeRemoved()) {
-        safeToRemove = false;
         LOG.warn("Found non removable hostcomponent when trying to"
             + " delete service component"
             + ", clusterName=" + getClusterName()
             + ", serviceName=" + getServiceName()
             + ", componentName=" + getName()
             + ", hostname=" + sch.getHostName());
-        break;
+        return false;
       }
     }
-    return safeToRemove;
+    return true;
   }
 
   @Override

+ 3 - 7
ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java

@@ -444,24 +444,20 @@ public class ServiceImpl implements Service {
 
   @Override
   public synchronized boolean canBeRemoved() {
-    State state = getDesiredState();
-    if (state != State.INIT
-        && state != State.UNINSTALLED) {
+    if (!getDesiredState().isRemovableState()) {
       return false;
     }
 
-    boolean safeToRemove = true;
     for (ServiceComponent sc : components.values()) {
       if (!sc.canBeRemoved()) {
-        safeToRemove = false;
         LOG.warn("Found non removable component when trying to delete service"
             + ", clusterName=" + cluster.getClusterName()
             + ", serviceName=" + getName()
             + ", componentName=" + sc.getName());
-        break;
+        return false;
       }
     }
-    return safeToRemove;
+    return true;
   }
 
   @Override

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/State.java

@@ -121,4 +121,22 @@ public enum State {
     }
   }
 
+  /**
+   * Indicates whether or not the resource with this state
+   * can be removed.
+   *
+   * @return true if this is a removable state
+   */
+  public boolean isRemovableState() {
+    switch (State.values()[this.state]) {
+      case INIT:
+      case INSTALLING:
+      case INSTALLED:
+      case INSTALL_FAILED:
+      case UNINSTALLED:
+        return true;
+      default:
+        return false;
+    }
+  }
 }

+ 4 - 7
ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java

@@ -1212,16 +1212,13 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public synchronized boolean canBeRemoved() {
     try {
       readLock.lock();
-      State desiredState = getDesiredState();
-      State liveState = getState();
-      if ((desiredState == State.INIT || desiredState == State.UNINSTALLED)
-          && (liveState == State.INIT || liveState == State.UNINSTALLED)) {
-        return true;
-      }
+
+      return (getDesiredState().isRemovableState() &&
+              getState().isRemovableState());
+
     } finally {
       readLock.unlock();
     }
-    return false;
   }
 
   @Override

+ 19 - 0
ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionManager.java

@@ -34,6 +34,7 @@ import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.controller.HostsMap;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
 import org.apache.ambari.server.utils.StageUtils;
@@ -157,4 +158,22 @@ public class TestActionManager {
     stages.add(s);
     db.persistActions(stages);
   }
+
+  @Test
+  public void testCascadeDeleteStages() throws Exception {
+    ActionDBAccessor db = injector.getInstance(ActionDBAccessorImpl.class);
+    ActionManager am = injector.getInstance(ActionManager.class);
+    populateActionDB(db, hostname);
+    assertEquals(1, clusters.getClusters().size());
+
+    Cluster cluster = clusters.getCluster(clusterName);
+
+    assertEquals(1, am.getRequests().size());
+
+    clusters.deleteCluster(clusterName);
+
+    assertEquals(0, clusters.getClusters().size());
+    assertEquals(0, am.getRequests().size());
+
+  }
 }

+ 18 - 0
ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentTest.java

@@ -39,6 +39,7 @@ import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
 import org.apache.ambari.server.orm.entities.HostComponentStateEntityPK;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntityPK;
+import org.apache.ambari.server.state.svccomphost.ServiceComponentHostImpl;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -308,4 +309,21 @@ public class ServiceComponentTest {
     Assert.assertFalse(sb.toString().isEmpty());
   }
 
+  @Test
+  public void testCanBeRemoved() throws Exception{
+    String componentName = "NAMENODE";
+    ServiceComponent component = serviceComponentFactory.createNew(service,
+        componentName);
+
+    for (State state : State.values()) {
+      component.setDesiredState(state);
+
+      if (state.isRemovableState()) {
+        org.junit.Assert.assertTrue(component.canBeRemoved());
+      }
+      else {
+        org.junit.Assert.assertFalse(component.canBeRemoved());
+      }
+    }
+  }
 }

+ 27 - 0
ambari-server/src/test/java/org/apache/ambari/server/state/ServiceTest.java

@@ -252,4 +252,31 @@ public class ServiceTest {
     assertEquals(0, mapReduce.getServiceComponents().size());
 
   }
+
+  @Test
+  public void testCanBeRemoved() throws Exception{
+    Service service = cluster.addService("HDFS");
+
+    for (State state : State.values()) {
+      service.setDesiredState(state);
+
+      if (state.isRemovableState()) {
+        org.junit.Assert.assertTrue(service.canBeRemoved());
+      }
+      else {
+        org.junit.Assert.assertFalse(service.canBeRemoved());
+      }
+    }
+
+    ServiceComponent component = service.addServiceComponent("NAMENODE");
+    // can't remove a STARTED component
+    component.setDesiredState(State.STARTED);
+
+    for (State state : State.values()) {
+      service.setDesiredState(state);
+      // should always be false if the sub component can not be removed
+      org.junit.Assert.assertFalse(service.canBeRemoved());
+    }
+  }
+
 }

+ 18 - 0
ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java

@@ -22,7 +22,9 @@ import static org.junit.Assert.fail;
 
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import com.google.inject.Provider;
 import org.apache.ambari.server.AmbariException;
@@ -655,4 +657,20 @@ public class ServiceComponentHostTest {
     }
   }
 
+  @Test
+  public void testCanBeRemoved() throws Exception{
+    ServiceComponentHostImpl impl = (ServiceComponentHostImpl)
+        createNewServiceComponentHost("HDFS", "HDFS_CLIENT", "h1", true);
+
+    for (State state : State.values()) {
+      impl.setState(state);
+
+      if (state.isRemovableState()) {
+        Assert.assertTrue(impl.canBeRemoved());
+      }
+      else {
+        Assert.assertFalse(impl.canBeRemoved());
+      }
+    }
+  }
 }