You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/05/05 21:33:55 UTC

ambari git commit: AMBARI-10877. Full Delete of Host : Deleting a host in a cluster should delete references to the host in all tables (alejandro)

Repository: ambari
Updated Branches:
  refs/heads/trunk bd44220a5 -> 9735a78d6


AMBARI-10877. Full Delete of Host : Deleting a host in a cluster should delete references to the host in all tables (alejandro)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9735a78d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9735a78d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9735a78d

Branch: refs/heads/trunk
Commit: 9735a78d696e62ff0d50f2a7846f7b7bd3cd0f4b
Parents: bd44220
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Mon Apr 27 19:12:01 2015 -0700
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Tue May 5 12:33:51 2015 -0700

----------------------------------------------------------------------
 .../internal/HostResourceProvider.java          |  30 +--
 .../server/orm/dao/HostConfigMappingDAO.java    | 130 +++++-----
 .../server/orm/dao/HostRoleCommandDAO.java      |  19 ++
 .../ambari/server/orm/dao/HostStateDAO.java     |  11 +-
 .../ambari/server/orm/dao/HostVersionDAO.java   |   9 +
 .../ambari/server/orm/dao/ServiceConfigDAO.java |  37 ++-
 .../orm/entities/HostConfigMappingEntity.java   |   8 +
 .../orm/entities/HostRoleCommandEntity.java     |   4 +-
 .../server/orm/entities/HostStateEntity.java    |   7 +
 .../server/state/cluster/ClusterImpl.java       |  42 ++--
 .../server/state/cluster/ClustersImpl.java      | 109 ++++++---
 .../ambari/server/state/host/HostImpl.java      |  93 +++++---
 .../AmbariManagementControllerTest.java         | 238 +++++++++----------
 .../orm/dao/HostConfigMappingDAOTest.java       |   2 +-
 .../server/orm/dao/ServiceConfigDAOTest.java    |   4 +-
 ambari-web/app/messages.js                      |   2 +
 .../main/host/details/doDeleteHostPopup.hbs     |  10 +
 17 files changed, 452 insertions(+), 303 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
index 45900e4..07c0e58 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
@@ -794,38 +794,16 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
 
           throw new AmbariException(reason.toString());
         }
-        okToRemove.add(hostRequest);
-
-      } else {
-        // check if host exists (throws exception if not found)
-        clusters.getHost(hostName);
-
-        // delete host outright
-        Set<Cluster> clusterSet = clusters.getClustersForHost(hostName);
-        if (0 != clusterSet.size()) {
-          StringBuilder reason = new StringBuilder("Cannot remove host ")
-              .append(hostName)
-              .append(".  It belongs to clusters: ");
-          int i = 0;
-          for (Cluster c : clusterSet) {
-            if ((i++) > 0) {
-              reason.append(", ");
-            }
-            reason.append(c.getClusterName());
-          }
-          throw new AmbariException(reason.toString());
-        }
-        okToRemove.add(hostRequest);
       }
+      okToRemove.add(hostRequest);
     }
 
     for (HostRequest hostRequest : okToRemove) {
+      // Assume the user also wants to delete it entirely, including all clusters.
+      clusters.deleteHost(hostRequest.getHostname());
+
       if (null != hostRequest.getClusterName()) {
-        clusters.unmapHostFromCluster(hostRequest.getHostname(),
-            hostRequest.getClusterName());
         clusters.getCluster(hostRequest.getClusterName()).recalculateAllClusterVersionStates();
-      } else {
-        clusters.deleteHost(hostRequest.getHostname());
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAO.java
index 34d0e3c..77ff4a2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAO.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -61,50 +62,39 @@ public class HostConfigMappingDAO {
   private HostDAO hostDAO;
 
   private final ReadWriteLock gl = new ReentrantReadWriteLock();
-  private Map<Long, Set<HostConfigMapping>> hostConfigMappingByHost;
+  private ConcurrentHashMap<Long, Set<HostConfigMapping>> hostConfigMappingByHost;
   
   private volatile boolean cacheLoaded;
   
   private void populateCache() {
     
     if (!cacheLoaded) {
-      gl.writeLock().lock();
-      try {
-        gl.writeLock().lock();
-        try {
-          if (hostConfigMappingByHost == null) {
-            hostConfigMappingByHost = new WeakHashMap<Long, Set<HostConfigMapping>>();
-            
-            TypedQuery<HostConfigMappingEntity> query = entityManagerProvider.get().createQuery(
-                "SELECT entity FROM HostConfigMappingEntity entity",
-                HostConfigMappingEntity.class);
-
-            List<HostConfigMappingEntity> hostConfigMappingEntities = daoUtils.selectList(query);
-            
-            for (HostConfigMappingEntity hostConfigMappingEntity : hostConfigMappingEntities) {
-              Long hostId = hostConfigMappingEntity.getHostId();
-
-              if (hostId == null) {
-                continue;
-              }
-
-              Set<HostConfigMapping> setByHost;
-              if (hostConfigMappingByHost.containsKey(hostId)) {
-                setByHost = hostConfigMappingByHost.get(hostId);
-              } else {
-                setByHost = new HashSet<HostConfigMapping>();
-                hostConfigMappingByHost.put(hostId, setByHost);
-              }
-       
-              HostConfigMapping hostConfigMapping = buildHostConfigMapping(hostConfigMappingEntity);
-              setByHost.add(hostConfigMapping);
-            } 
+      if (hostConfigMappingByHost == null) {
+        hostConfigMappingByHost = new ConcurrentHashMap<Long, Set<HostConfigMapping>>();
+
+        TypedQuery<HostConfigMappingEntity> query = entityManagerProvider.get().createNamedQuery(
+            "HostConfigMappingEntity.findAll", HostConfigMappingEntity.class);
+
+        List<HostConfigMappingEntity> hostConfigMappingEntities = daoUtils.selectList(query);
+
+        for (HostConfigMappingEntity hostConfigMappingEntity : hostConfigMappingEntities) {
+          Long hostId = hostConfigMappingEntity.getHostId();
+
+          if (hostId == null) {
+            continue;
           }
-        } finally {
-          gl.writeLock().unlock();
+
+          Set<HostConfigMapping> setByHost;
+          if (hostConfigMappingByHost.containsKey(hostId)) {
+            setByHost = hostConfigMappingByHost.get(hostId);
+          } else {
+            setByHost = new HashSet<HostConfigMapping>();
+            hostConfigMappingByHost.put(hostId, setByHost);
+          }
+
+          HostConfigMapping hostConfigMapping = buildHostConfigMapping(hostConfigMappingEntity);
+          setByHost.add(hostConfigMapping);
         }
-      } finally {
-        gl.writeLock().unlock();
       }
       
       cacheLoaded = true;
@@ -295,34 +285,64 @@ public class HostConfigMappingDAO {
   }
 
   /**
-   * @param clusterId
-   * @param hostName
+   * @param hostId
    */
   @Transactional
-  public void removeHost(final long clusterId, String hostName) {
+  public void removeByHostId(Long hostId) {
     populateCache();
 
-    if (hostConfigMappingByHost.containsKey(hostName)) {
-      Set<HostConfigMapping> set = hostConfigMappingByHost.get(hostName);
+    HostEntity hostEntity = hostDAO.findById(hostId);
+    if (hostEntity != null) {
+      if (hostConfigMappingByHost.containsKey(hostEntity.getHostId())) {
+        // Delete from db
+        TypedQuery<HostConfigMappingEntity> query = entityManagerProvider.get().createNamedQuery(
+            "HostConfigMappingEntity.findByHostId", HostConfigMappingEntity.class);
+        query.setParameter("hostId", hostId);
 
-      //Remove from cache items with clusterId
-      CollectionUtils.filter(set, new Predicate() {
-        @Override
-        public boolean evaluate(Object arg0) {
-          return !((HostConfigMapping) arg0).getClusterId().equals(clusterId);
+        List<HostConfigMappingEntity> hostConfigMappingEntities = daoUtils.selectList(query);
+
+        List<HostConfigMappingEntity> list = daoUtils.selectList(query, hostEntity.getHostId());
+
+        for (HostConfigMappingEntity entity : list) {
+          entityManagerProvider.get().remove(entity);
         }
-      });
+        // Update the cache
+        hostConfigMappingByHost.remove(hostEntity.getHostId());
+      }
+    }
+  }
+
+  /**
+   * @param clusterId
+   * @param hostName
+   */
+  @Transactional
+  public void removeByClusterAndHostName(final long clusterId, String hostName) {
+    populateCache();
 
-      //delete from db
-      TypedQuery<HostConfigMappingEntity> query = entityManagerProvider.get().createQuery(
-          "SELECT entity FROM HostConfigMappingEntity entity " +
-              "WHERE entity.clusterId = ?1 AND entity.hostEntity.hostName = ?2",
-          HostConfigMappingEntity.class);
+    HostEntity hostEntity = hostDAO.findByName(hostName);
+    if (hostEntity != null) {
+      if (hostConfigMappingByHost.containsKey(hostName)) {
+        // Delete from db
+        TypedQuery<HostConfigMappingEntity> query = entityManagerProvider.get().createQuery(
+            "SELECT entity FROM HostConfigMappingEntity entity " +
+                "WHERE entity.clusterId = ?1 AND entity.hostId=?2",
+            HostConfigMappingEntity.class);
 
-      List<HostConfigMappingEntity> list = daoUtils.selectList(query, Long.valueOf(clusterId), hostName);
+        List<HostConfigMappingEntity> list = daoUtils.selectList(query, clusterId, hostEntity.getHostId());
 
-      for (HostConfigMappingEntity entity : list) {
-        entityManagerProvider.get().remove(entity);
+        for (HostConfigMappingEntity entity : list) {
+          entityManagerProvider.get().remove(entity);
+        }
+
+        // Remove from cache items with given clusterId
+        Set<HostConfigMapping> set = hostConfigMappingByHost.get(hostEntity.getHostId());
+        CollectionUtils.filter(set, new Predicate() {
+          @Override
+          public boolean evaluate(Object arg0) {
+            return !((HostConfigMapping) arg0).getClusterId().equals(clusterId);
+          }
+        });
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
index 7d3f4e4..119737c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java
@@ -32,6 +32,7 @@ import java.util.Map;
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.HostEntity;
@@ -115,6 +116,16 @@ public class HostRoleCommandDAO {
   }
 
   @RequiresSession
+  public List<HostRoleCommandEntity> findByHostId(Long hostId) {
+    TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createNamedQuery(
+        "HostRoleCommandEntity.findByHostId",
+        HostRoleCommandEntity.class);
+
+    query.setParameter("hostId", hostId);
+    return daoUtils.selectList(query);
+  }
+
+  @RequiresSession
   public List<HostRoleCommandEntity> findByRequestIds(Collection<Long> requestIds) {
     TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createQuery(
         "SELECT task FROM HostRoleCommandEntity task " +
@@ -363,6 +374,14 @@ public class HostRoleCommandDAO {
   }
 
   @Transactional
+  public void removeByHostId(Long hostId) {
+    Collection<HostRoleCommandEntity> commands = this.findByHostId(hostId);
+    for (HostRoleCommandEntity cmd : commands) {
+      this.remove(cmd);
+    }
+  }
+
+  @Transactional
   public List<HostRoleCommandEntity> mergeAll(Collection<HostRoleCommandEntity> entities) {
     List<HostRoleCommandEntity> managedList = new ArrayList<HostRoleCommandEntity>(entities.size());
     for (HostRoleCommandEntity entity : entities) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostStateDAO.java
index f939de3..10828ac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostStateDAO.java
@@ -24,8 +24,10 @@ import com.google.inject.Singleton;
 import com.google.inject.persist.Transactional;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.HostStateEntity;
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
 
 import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
 import java.util.List;
 
 @Singleton
@@ -35,9 +37,10 @@ public class HostStateDAO {
   @Inject
   DaoUtils daoUtils;
 
+
   @RequiresSession
-  public HostStateEntity findByHostName(String hostName) {
-    return entityManagerProvider.get().find(HostStateEntity.class, hostName);
+  public HostStateEntity findByHostId(Long hostId) {
+    return entityManagerProvider.get().find(HostStateEntity.class, hostId);
   }
 
   @RequiresSession
@@ -66,8 +69,8 @@ public class HostStateDAO {
   }
 
   @Transactional
-  public void removeByHostName(String hostName) {
-    remove(findByHostName(hostName));
+  public void removeByHostId(Long hostId) {
+    remove(findByHostId(hostId));
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index de3b8cb..a2ff211 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -18,6 +18,7 @@
 
 package org.apache.ambari.server.orm.dao;
 
+import java.util.Collection;
 import java.util.List;
 
 import javax.persistence.EntityManager;
@@ -214,6 +215,14 @@ public class HostVersionDAO {
   }
 
   @Transactional
+  public void removeByHostName(String hostName) {
+    Collection<HostVersionEntity> hostVersions = this.findByHost(hostName);
+    for (HostVersionEntity hostVersion : hostVersions) {
+      this.remove(hostVersion);
+    }
+  }
+
+  @Transactional
   public void removeByPK(long id) {
     remove(findByPK(id));
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
index db0817b..1063c3f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
@@ -32,6 +32,7 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Root;
 
 import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.cache.ConfigGroupHostMapping;
 import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.StackId;
@@ -40,6 +41,8 @@ import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.persist.Transactional;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
 
 @Singleton
 public class ServiceConfigDAO {
@@ -128,7 +131,7 @@ public class ServiceConfigDAO {
    * @return all service configurations for the cluster and stack.
    */
   @RequiresSession
-  public List<ServiceConfigEntity> getAllServiceConfigs(Long clusterId,
+  public List<ServiceConfigEntity> getAllServiceConfigsForClusterAndStack(Long clusterId,
       StackId stackId) {
 
     StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
@@ -191,6 +194,11 @@ public class ServiceConfigDAO {
     return daoUtils.selectSingle(query, clusterId, serviceName);
   }
 
+  /**
+   * Get all service configs for the given cluster.
+   * @param clusterId Cluster Id
+   * @return Collection of service configs in the given cluster.
+   */
   @RequiresSession
   public List<ServiceConfigEntity> getServiceConfigs(Long clusterId) {
     TypedQuery<ServiceConfigEntity> query = entityManagerProvider.get()
@@ -202,6 +210,15 @@ public class ServiceConfigDAO {
   }
 
   /**
+   * Get all service configs
+   * @return Collection of all service configs.
+   */
+  @RequiresSession
+  public List<ServiceConfigEntity> findAll() {
+    return daoUtils.selectAll(entityManagerProvider.get(), ServiceConfigEntity.class);
+  }
+
+  /**
    * Gets the next version that will be created when persisting a new
    * {@link ServiceConfigEntity}.
    *
@@ -223,6 +240,24 @@ public class ServiceConfigDAO {
   }
 
   @Transactional
+  public void removeHostFromServiceConfigs(final Long hostId) {
+    List<ServiceConfigEntity> allServiceConfigs = this.findAll();
+    for (ServiceConfigEntity serviceConfigEntity : allServiceConfigs) {
+      List<Long> hostIds = serviceConfigEntity.getHostIds();
+      if (hostIds != null && hostIds.contains(hostId)) {
+        // Remove the hostId
+        CollectionUtils.filter(hostIds, new Predicate() {
+          @Override
+          public boolean evaluate(Object arg0) {
+            return !((Long) arg0).equals(hostId);
+          }
+        });
+        serviceConfigEntity.setHostIds(hostIds);
+      }
+    }
+  }
+
+  @Transactional
   public void create(ServiceConfigEntity serviceConfigEntity) {
     entityManagerProvider.get().persist(serviceConfigEntity);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostConfigMappingEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostConfigMappingEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostConfigMappingEntity.java
index 915b05f..eea4a40 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostConfigMappingEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostConfigMappingEntity.java
@@ -21,6 +21,8 @@ import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 
 /**
@@ -29,6 +31,12 @@ import javax.persistence.Table;
 @Table(name = "hostconfigmapping")
 @Entity
 @IdClass(HostConfigMappingEntityPK.class)
+@NamedQueries({
+    @NamedQuery(name = "HostConfigMappingEntity.findAll",
+        query = "SELECT entity FROM HostConfigMappingEntity entity"),
+    @NamedQuery(name = "HostConfigMappingEntity.findByHostId",
+        query = "SELECT entity FROM HostConfigMappingEntity entity WHERE entity.hostId = :hostId")
+})
 public class HostConfigMappingEntity {
 
   @Id

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
index 061f436..81a1b00 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostRoleCommandEntity.java
@@ -56,7 +56,9 @@ import org.apache.commons.lang.ArrayUtils;
 )
 @NamedQueries({
     @NamedQuery(name = "HostRoleCommandEntity.findCountByCommandStatuses", query = "SELECT COUNT(command.taskId) FROM HostRoleCommandEntity command WHERE command.status IN :statuses"),
-    @NamedQuery(name = "HostRoleCommandEntity.findByCommandStatuses", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.status IN :statuses ORDER BY command.requestId, command.stageId") })
+    @NamedQuery(name = "HostRoleCommandEntity.findByCommandStatuses", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.status IN :statuses ORDER BY command.requestId, command.stageId"),
+    @NamedQuery(name = "HostRoleCommandEntity.findByHostId", query = "SELECT command FROM HostRoleCommandEntity command WHERE command.hostId=:hostId")
+})
 public class HostRoleCommandEntity {
 
   private static int MAX_COMMAND_DETAIL_LENGTH = 250;

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostStateEntity.java
index 52ae322..544df6b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostStateEntity.java
@@ -27,12 +27,19 @@ import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
 import javax.persistence.OneToOne;
 
 import org.apache.ambari.server.state.HostState;
 
 @javax.persistence.Table(name = "hoststate")
 @Entity
+@NamedQueries({
+    @NamedQuery(name = "hostStateByHostId", query =
+        "SELECT hostState FROM HostStateEntity hostState " +
+            "WHERE hostState.hostId=:hostId"),
+})
 public class HostStateEntity {
   
   @javax.persistence.Column(name = "host_id", nullable = false, insertable = false, updatable = false)

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 3764dd1..98f7cfc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -1954,7 +1954,7 @@ public class ClusterImpl implements Cluster {
         }
       }
 
-      // TODO AMBARI-10679, need efficient caching from hostId to hostName
+      // TODO AMBARI-10679, need efficient caching from hostId to hostName...
       Map<Long, String> hostIdToName = new HashMap<Long, String>();
 
       if (!map.isEmpty()) {
@@ -1988,29 +1988,27 @@ public class ClusterImpl implements Cluster {
   public ServiceConfigVersionResponse createServiceConfigVersion(
       String serviceName, String user, String note, ConfigGroup configGroup) {
 
-    // create next service config version
+    // Create next service config version
     ServiceConfigEntity serviceConfigEntity = new ServiceConfigEntity();
 
-    // set config group
-    if (configGroup != null) {
-      serviceConfigEntity.setGroupId(configGroup.getId());
-      Collection<Config> configs = configGroup.getConfigurations().values();
-      List<ClusterConfigEntity> configEntities = new ArrayList<ClusterConfigEntity>(configs.size());
-      for (Config config : configs) {
-        configEntities.add(clusterDAO.findConfig(getClusterId(), config.getType(), config.getTag()));
-      }
-
-      serviceConfigEntity.setClusterConfigEntities(configEntities);
-      serviceConfigEntity.setHostIds(new ArrayList<Long>(configGroup.getHosts().keySet()));
+    clusterGlobalLock.writeLock().lock();
+    try {
+      // set config group
+      if (configGroup != null) {
+        serviceConfigEntity.setGroupId(configGroup.getId());
+        Collection<Config> configs = configGroup.getConfigurations().values();
+        List<ClusterConfigEntity> configEntities = new ArrayList<ClusterConfigEntity>(configs.size());
+        for (Config config : configs) {
+          configEntities.add(clusterDAO.findConfig(getClusterId(), config.getType(), config.getTag()));
+        }
 
-    } else {
-      List<ClusterConfigEntity> configEntities = getClusterConfigEntitiesByService(serviceName);
-      serviceConfigEntity.setClusterConfigEntities(configEntities);
-    }
+        serviceConfigEntity.setClusterConfigEntities(configEntities);
+      } else {
+        List<ClusterConfigEntity> configEntities = getClusterConfigEntitiesByService(serviceName);
+        serviceConfigEntity.setClusterConfigEntities(configEntities);
+      }
 
-    clusterGlobalLock.writeLock().lock();
 
-    try {
       long nextServiceConfigVersion = serviceConfigDAO.findNextServiceConfigVersion(
           clusterEntity.getClusterId(), serviceName);
 
@@ -2022,6 +2020,10 @@ public class ClusterImpl implements Cluster {
       serviceConfigEntity.setStack(clusterEntity.getDesiredStack());
 
       serviceConfigDAO.create(serviceConfigEntity);
+      if (configGroup != null) {
+        serviceConfigEntity.setHostIds(new ArrayList<Long>(configGroup.getHosts().keySet()));
+        serviceConfigDAO.merge(serviceConfigEntity);
+      }
     } finally {
       clusterGlobalLock.writeLock().unlock();
     }
@@ -2754,7 +2756,7 @@ public class ClusterImpl implements Cluster {
 
       clusterEntity = clusterDAO.merge(clusterEntity);
 
-      List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getAllServiceConfigs(
+      List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getAllServiceConfigsForClusterAndStack(
           clusterId, stackId);
 
       // remove all service configurations

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
index 9e63ff2..c21414a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
@@ -45,15 +45,18 @@ import org.apache.ambari.server.events.HostRemovedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.HostConfigMappingDAO;
 import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.dao.HostStateDAO;
 import org.apache.ambari.server.orm.dao.HostVersionDAO;
 import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
 import org.apache.ambari.server.orm.dao.ResourceTypeDAO;
+import org.apache.ambari.server.orm.dao.ServiceConfigDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
-import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.PermissionEntity;
 import org.apache.ambari.server.orm.entities.PrivilegeEntity;
 import org.apache.ambari.server.orm.entities.ResourceEntity;
@@ -100,25 +103,33 @@ public class ClustersImpl implements Clusters {
   private volatile boolean clustersLoaded = false;
 
   @Inject
-  ClusterDAO clusterDAO;
+  private ClusterDAO clusterDAO;
   @Inject
-  HostDAO hostDAO;
+  private HostDAO hostDAO;
   @Inject
-  ClusterVersionDAO clusterVersionDAO;
+  private ClusterVersionDAO clusterVersionDAO;
   @Inject
-  HostVersionDAO hostVersionDAO;
+  private HostVersionDAO hostVersionDAO;
   @Inject
-  ResourceTypeDAO resourceTypeDAO;
+  private HostStateDAO hostStateDAO;
   @Inject
-  KerberosPrincipalHostDAO kerberosPrincipalHostDAO;
+  private HostRoleCommandDAO hostRoleCommandDAO;
   @Inject
-  ClusterFactory clusterFactory;
+  private ResourceTypeDAO resourceTypeDAO;
   @Inject
-  HostFactory hostFactory;
+  private KerberosPrincipalHostDAO kerberosPrincipalHostDAO;
   @Inject
-  Configuration configuration;
+  private HostConfigMappingDAO hostConfigMappingDAO;
   @Inject
-  AmbariMetaInfo ambariMetaInfo;
+  private ServiceConfigDAO serviceConfigDAO;
+  @Inject
+  private ClusterFactory clusterFactory;
+  @Inject
+  private HostFactory hostFactory;
+  @Inject
+  private Configuration configuration;
+  @Inject
+  private AmbariMetaInfo ambariMetaInfo;
   @Inject
   private SecurityHelper securityHelper;
 
@@ -680,39 +691,45 @@ public class ClustersImpl implements Clusters {
   }
 
   @Override
-  public void unmapHostFromCluster(String hostname, String clusterName)
-      throws AmbariException {
+  public void unmapHostFromCluster(String hostname, String clusterName) throws AmbariException {
+    final Cluster cluster = getCluster(clusterName);
+    this.unmapHostFromClusters(hostname, new HashSet<Cluster>() {{ add(cluster); }});
+  }
+
+  public void unmapHostFromClusters(String hostname, Set<Cluster> clusters) throws AmbariException {
     Host host = null;
-    Cluster cluster = null;
     HostEntity hostEntity = null;
 
     checkLoaded();
+    if (clusters.isEmpty()) {
+      return;
+    }
 
     r.lock();
     try {
       host = getHost(hostname);
-      cluster = getCluster(clusterName);
       hostEntity = hostDAO.findByName(hostname);
     } finally {
       r.unlock();
     }
 
-    long clusterId = cluster.getClusterId();
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Unmapping host {} from cluster {} (id={})", hostname,
-          clusterName, clusterId);
-    }
-
     w.lock();
-
     try {
-      unmapHostClusterEntities(hostname, cluster.getClusterId());
+      for (Cluster cluster : clusters) {
+        long clusterId = cluster.getClusterId();
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Unmapping host {} from cluster {} (id={})", hostname,
+              cluster.getClusterName(), clusterId);
+        }
 
-      hostClusterMap.get(hostname).remove(cluster);
-      clusterHostMap.get(clusterName).remove(host);
+        unmapHostClusterEntities(hostname, cluster.getClusterId());
 
-      host.refresh();
-      cluster.refresh();
+        hostClusterMap.get(hostname).remove(cluster);
+        clusterHostMap.get(cluster.getClusterName()).remove(host);
+
+        host.refresh();
+        cluster.refresh();
+      }
 
       deleteConfigGroupHostMapping(hostEntity.getHostId());
 
@@ -745,12 +762,19 @@ public class ClustersImpl implements Clusters {
     }
   }
 
+  /***
+   * Delete a host entirely from the cluster and all database tables, except AlertHistory.
+   * If the host is not found, throws {@link org.apache.ambari.server.HostNotFoundException}
+   * @param hostname
+   * @throws AmbariException
+   */
   @Override
+  @Transactional
   public void deleteHost(String hostname) throws AmbariException {
     checkLoaded();
 
     if (!hosts.containsKey(hostname)) {
-      return;
+      throw new HostNotFoundException("Could not find host " + hostname);
     }
 
     w.lock();
@@ -761,26 +785,33 @@ public class ClustersImpl implements Clusters {
       if (entity == null) {
         return;
       }
+      // Remove from all clusters in the cluster_host_mapping table.
+      // This will also remove from kerberos_principal_hosts, hostconfigmapping, and configgrouphostmapping 
+      Set<Cluster> clusters = hostClusterMap.get(hostname);
+      this.unmapHostFromClusters(hostname, clusters);
+      hostDAO.refresh(entity);
 
-      deleteConfigGroupHostMapping(entity.getHostId());
+      hostVersionDAO.removeByHostName(hostname);
+      entity.setHostRoleCommandEntities(null);
+      hostRoleCommandDAO.removeByHostId(entity.getHostId());
 
-      Collection<HostVersionEntity> hostVersions = hosts.get(hostname).getAllHostVersions();
-      for (HostVersionEntity hostVersion : hostVersions) {
-        hostVersionDAO.remove(hostVersion);
-      }
+      entity.setHostStateEntity(null);
+      hostStateDAO.removeByHostId(entity.getHostId());
+      hostConfigMappingDAO.removeByHostId(entity.getHostId());
+      serviceConfigDAO.removeHostFromServiceConfigs(entity.getHostId());
 
-      hostDAO.refresh(entity);
-      hostDAO.remove(entity);
+      // Remove from dictionaries
       hosts.remove(hostname);
       hostsById.remove(entity.getHostId());
 
-      // Remove mapping of principals to deleted host
-      kerberosPrincipalHostDAO.removeByHost(entity.getHostId());
+      hostDAO.remove(entity);
 
-      // publish the event
+      // Publish the event
       HostRemovedEvent event = new HostRemovedEvent(hostname);
       eventPublisher.publish(event);
-
+      
+      // Note, if the host is still heartbeating, then new records will be re-inserted
+      // into the hosts and hoststate tables
     } catch (Exception e) {
       throw new AmbariException("Could not remove host", e);
     } finally {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
index 27f4800..e35e42b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
@@ -545,9 +545,11 @@ public class HostImpl implements Host {
 
       HostStateEntity hostStateEntity = getHostStateEntity();
 
-      hostStateEntity.setCurrentState(state);
-      hostStateEntity.setTimeInState(System.currentTimeMillis());
-      saveIfPersisted();
+      if (hostStateEntity != null) {
+        hostStateEntity.setCurrentState(state);
+        hostStateEntity.setTimeInState(System.currentTimeMillis());
+        saveIfPersisted();
+      }
     }
     finally {
       writeLock.unlock();
@@ -765,7 +767,8 @@ public class HostImpl implements Host {
   public long getAvailableMemBytes() {
     try {
       readLock.lock();
-      return getHostStateEntity().getAvailableMem();
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      return hostStateEntity != null ? hostStateEntity.getAvailableMem() : null;
     }
     finally {
       readLock.unlock();
@@ -776,8 +779,11 @@ public class HostImpl implements Host {
   public void setAvailableMemBytes(long availableMemBytes) {
     try {
       writeLock.lock();
-      getHostStateEntity().setAvailableMem(availableMemBytes);
-      saveIfPersisted();
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        getHostStateEntity().setAvailableMem(availableMemBytes);
+        saveIfPersisted();
+      }
     }
     finally {
       writeLock.unlock();
@@ -897,8 +903,11 @@ public class HostImpl implements Host {
   public HostHealthStatus getHealthStatus() {
     try {
       readLock.lock();
-      return gson.fromJson(getHostStateEntity().getHealthStatus(),
-          HostHealthStatus.class);
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        return gson.fromJson(hostStateEntity.getHealthStatus(), HostHealthStatus.class);
+      }
+      return null;
     } finally {
       readLock.unlock();
     }
@@ -908,13 +917,16 @@ public class HostImpl implements Host {
   public void setHealthStatus(HostHealthStatus healthStatus) {
     try {
       writeLock.lock();
-      getHostStateEntity().setHealthStatus(gson.toJson(healthStatus));
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        hostStateEntity.setHealthStatus(gson.toJson(healthStatus));
 
-      if (healthStatus.getHealthStatus().equals(HealthStatus.UNKNOWN)) {
-        setStatus(HealthStatus.UNKNOWN.name());
-      }
+        if (healthStatus.getHealthStatus().equals(HealthStatus.UNKNOWN)) {
+          setStatus(HealthStatus.UNKNOWN.name());
+        }
 
-      saveIfPersisted();
+        saveIfPersisted();
+      }
     } finally {
       writeLock.unlock();
     }
@@ -1031,8 +1043,12 @@ public class HostImpl implements Host {
   public AgentVersion getAgentVersion() {
     try {
       readLock.lock();
-      return gson.fromJson(getHostStateEntity().getAgentVersion(),
-          AgentVersion.class);
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        return gson.fromJson(getHostStateEntity().getAgentVersion(),
+            AgentVersion.class);
+      }
+      return null;
     }
     finally {
       readLock.unlock();
@@ -1043,8 +1059,11 @@ public class HostImpl implements Host {
   public void setAgentVersion(AgentVersion agentVersion) {
     try {
       writeLock.lock();
-      getHostStateEntity().setAgentVersion(gson.toJson(agentVersion));
-      saveIfPersisted();
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        getHostStateEntity().setAgentVersion(gson.toJson(agentVersion));
+        saveIfPersisted();
+      }
     }
     finally {
       writeLock.unlock();
@@ -1053,15 +1072,19 @@ public class HostImpl implements Host {
 
   @Override
   public long getTimeInState() {
-    return getHostStateEntity().getTimeInState();
+    HostStateEntity hostStateEntity = getHostStateEntity();
+    return hostStateEntity != null ? hostStateEntity.getTimeInState() :  null;
   }
 
   @Override
   public void setTimeInState(long timeInState) {
     try {
       writeLock.lock();
-      getHostStateEntity().setTimeInState(timeInState);
-      saveIfPersisted();
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        getHostStateEntity().setTimeInState(timeInState);
+        saveIfPersisted();
+      }
     }
     finally {
       writeLock.unlock();
@@ -1335,14 +1358,17 @@ public class HostImpl implements Host {
 
   private void ensureMaintMap() {
     if (null == maintMap) {
-      String entity = getHostStateEntity().getMaintenanceState();
-      if (null == entity) {
-        maintMap = new HashMap<Long, MaintenanceState>();
-      } else {
-        try {
-          maintMap = gson.fromJson(entity, maintMapType);
-        } catch (Exception e) {
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        String entity = hostStateEntity.getMaintenanceState();
+        if (null == entity) {
           maintMap = new HashMap<Long, MaintenanceState>();
+        } else {
+          try {
+            maintMap = gson.fromJson(entity, maintMapType);
+          } catch (Exception e) {
+            maintMap = new HashMap<Long, MaintenanceState>();
+          }
         }
       }
     }
@@ -1358,12 +1384,15 @@ public class HostImpl implements Host {
       maintMap.put(clusterId, state);
       String json = gson.toJson(maintMap, maintMapType);
 
-      getHostStateEntity().setMaintenanceState(json);
-      saveIfPersisted();
+      HostStateEntity hostStateEntity = getHostStateEntity();
+      if (hostStateEntity != null) {
+        getHostStateEntity().setMaintenanceState(json);
+        saveIfPersisted();
 
-      // broadcast the maintenance mode change
-      MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
-      eventPublisher.publish(event);
+        // broadcast the maintenance mode change
+        MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
+        eventPublisher.publish(event);
+      }
     } finally {
       writeLock.unlock();
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index ffe35af..ebe0763 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -251,10 +251,10 @@ public class AmbariManagementControllerTest {
   }
 
   private void addHost(String hostname) throws AmbariException {
-    addHost(hostname, null);
+    addHostToCluster(hostname, null);
   }
 
-  private void addHost(String hostname, String clusterName) throws AmbariException {
+  private void addHostToCluster(String hostname, String clusterName) throws AmbariException {
     clusters.addHost(hostname);
     setOsFamily(clusters.getHost(hostname), "redhat", "6.3");
     clusters.getHost(hostname).setState(HostState.HEALTHY);
@@ -1122,8 +1122,8 @@ public class AmbariManagementControllerTest {
       // Expected
     }
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     try {
       createServiceComponentHost(clusterName, serviceName, componentName1,
@@ -1207,8 +1207,8 @@ public class AmbariManagementControllerTest {
         State.INIT);
     String host1 = "h1";
     String host2 = "h2";
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Set<ServiceComponentHostRequest> set1 =
         new HashSet<ServiceComponentHostRequest>();
@@ -2502,8 +2502,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
         host1, null);
@@ -2635,7 +2635,7 @@ public class AmbariManagementControllerTest {
     controller.createCluster(r);
     Cluster c1 = clusters.getCluster(clusterName);
     for (String host : hosts) {
-      addHost(host, clusterName);
+      addHostToCluster(host, clusterName);
     }
     return c1;
   }
@@ -3018,8 +3018,8 @@ public class AmbariManagementControllerTest {
         State.INIT);
     String host1 = "h1";
     String host2 = "h2";
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Set<ServiceComponentHostRequest> set1 =
         new HashSet<ServiceComponentHostRequest>();
@@ -3257,8 +3257,8 @@ public class AmbariManagementControllerTest {
         State.INIT);
     String host1 = "h1";
     String host2 = "h2";
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Set<ServiceComponentHostRequest> set1 =
         new HashSet<ServiceComponentHostRequest>();
@@ -3447,8 +3447,8 @@ public class AmbariManagementControllerTest {
         State.INIT);
     String host1 = "h1";
     String host2 = "h2";
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     Set<ServiceComponentHostRequest> set1 =
@@ -3618,8 +3618,8 @@ public class AmbariManagementControllerTest {
         State.INIT);
     String host1 = "h1";
     String host2 = "h2";
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Set<ServiceComponentHostRequest> set1 =
         new HashSet<ServiceComponentHostRequest>();
@@ -3768,8 +3768,8 @@ public class AmbariManagementControllerTest {
         State.INIT);
     String host1 = "h1";
     String host2 = "h2";
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Set<ServiceComponentHostRequest> set1 =
         new HashSet<ServiceComponentHostRequest>();
@@ -4620,8 +4620,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
@@ -4694,8 +4694,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     // null service should work
@@ -4894,8 +4894,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     // null service should work
@@ -5042,8 +5042,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     // null service should work
@@ -5209,9 +5209,9 @@ public class AmbariManagementControllerTest {
     String host2 = "h2";
     String host3 = "h3";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
-    addHost(host3, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    addHostToCluster(host3, clusterName);
 
     createServiceComponentHost(clusterName, serviceName1, componentName1,
       host1, null);
@@ -5376,8 +5376,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
       host1, null);
@@ -5460,8 +5460,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Map<String, String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "Called from a test");
@@ -5558,9 +5558,9 @@ public class AmbariManagementControllerTest {
     String host2 = "h2";
     String host3 = "h3";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
-    addHost(host3, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    addHostToCluster(host3, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
         host1, null);
@@ -5696,9 +5696,9 @@ public class AmbariManagementControllerTest {
     String host2 = "h2";
     String host3 = "h3";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
-    addHost(host3, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    addHostToCluster(host3, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
         host1, null);
@@ -5801,9 +5801,9 @@ public class AmbariManagementControllerTest {
     String host2 = "h2";
     String host3 = "h3";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
-    addHost(host3, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    addHostToCluster(host3, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
       host1, null);
@@ -5866,9 +5866,9 @@ public class AmbariManagementControllerTest {
     String host2 = "h2";
     String host3 = "h3";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
-    addHost(host3, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    addHostToCluster(host3, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
       host1, null);
@@ -5923,8 +5923,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName,
       host1, null);
@@ -5981,8 +5981,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
       host1, null);
@@ -6368,8 +6368,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     // null service should work
@@ -6450,8 +6450,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
 
     // null service should work
@@ -6523,8 +6523,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Map<String, String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "Called from a test");
@@ -6594,9 +6594,9 @@ public class AmbariManagementControllerTest {
     String host2 = "h2";
     String host3 = "h3";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
-    addHost(host3, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    addHostToCluster(host3, clusterName);
 
     createServiceComponentHost(clusterName, serviceName1, componentName1,
       host1, null);
@@ -6755,8 +6755,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1,
         host1, null);
@@ -6857,8 +6857,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     // null service should work
     createServiceComponentHost(clusterName, null, componentName1,
@@ -7194,8 +7194,8 @@ public class AmbariManagementControllerTest {
     createService(clusterName, serviceName, State.INIT);
     createServiceComponent(clusterName, serviceName, componentName, null);
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, null, componentName,
         host1, null);
@@ -7371,8 +7371,8 @@ public class AmbariManagementControllerTest {
     createService(clusterName, pigServiceName, State.INIT);
     createServiceComponent(clusterName, pigServiceName, pigComponentName, null);
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, null, pigComponentName,
         host1, null);
@@ -7646,8 +7646,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Map<String, String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "Called from a test");
@@ -7922,8 +7922,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     Map<String, String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "Called from a test");
@@ -8020,7 +8020,7 @@ public class AmbariManagementControllerTest {
     createServiceComponent(clusterName, serviceName1, componentName2, State.INIT);
     createServiceComponent(clusterName, serviceName1, componentName3, State.INIT);
     String host1 = "h1";
-    addHost(host1, clusterName);
+    addHostToCluster(host1, clusterName);
 
     Set<ServiceComponentHostRequest> set1 =  new HashSet<ServiceComponentHostRequest>();
     ServiceComponentHostRequest r1 = new ServiceComponentHostRequest(clusterName, serviceName1,
@@ -8302,7 +8302,7 @@ public class AmbariManagementControllerTest {
 
     String host1 = "h1";
 
-    addHost(host1, clusterName);
+    addHostToCluster(host1, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1, host1, null);
     createServiceComponentHost(clusterName, serviceName, componentName2, host1, null);
@@ -8376,25 +8376,22 @@ public class AmbariManagementControllerTest {
     createServiceComponent(clusterName, serviceName, componentName2, State.INIT);
     createServiceComponent(clusterName, serviceName, componentName3, State.INIT);
 
-    String host1 = "h1";
-
-    String host2 = "h2";
-    clusters.addHost(host2);
-    setOsFamily(clusters.getHost("h2"), "redhat", "6.3");
-    clusters.getHost("h2").persist();
-
-    String host3 = "h3";
+    String host1 = "h1";  // Host will belong to the cluster and contain components
+    String host2 = "h2";  // Host will belong to the cluster and not contain any components
 
-    addHost(host1, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
+    String host3 = "h3";  // Host is not registered
 
-    createServiceComponentHost(clusterName, null, componentName1, host1, null);
+    // Add components to host1
+    createServiceComponentHost(clusterName, serviceName, componentName1, host1, null);
     createServiceComponentHost(clusterName, serviceName, componentName2, host1, null);
     createServiceComponentHost(clusterName, serviceName, componentName3, host1, null);
 
     // Install
     installService(clusterName, serviceName, false, false);
 
-    // make them believe they are up
+    // Treat host components on host1 as up and healthy
     Map<String, ServiceComponentHost> hostComponents = cluster.getService(serviceName).getServiceComponent(componentName1).getServiceComponentHosts();
     for (Map.Entry<String, ServiceComponentHost> entry : hostComponents.entrySet()) {
       ServiceComponentHost cHost = entry.getValue();
@@ -8408,23 +8405,24 @@ public class AmbariManagementControllerTest {
       cHost.handleEvent(new ServiceComponentHostOpSucceededEvent(cHost.getServiceComponentName(), cHost.getHostName(), System.currentTimeMillis()));
     }
 
+    // Case 1: Attempt delete when components still exist
     Set<HostRequest> requests = new HashSet<HostRequest>();
-    // delete from cluster
     requests.clear();
     requests.add(new HostRequest(host1, clusterName, null));
     try {
       HostResourceProviderTest.deleteHosts(controller, requests);
-      fail("Expect failure deleting hosts when components exist.");
+      fail("Expect failure deleting hosts when components exist and have not been deleted.");
     } catch (Exception e) {
     }
 
+    // Case 2: Delete host that is still part of cluster, but do not specify the cluster_name in the request
     Set<ServiceComponentHostRequest> schRequests = new HashSet<ServiceComponentHostRequest>();
-    // disable HC for non-clients
+    // Disable HC for non-clients
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName1, host1, "DISABLED"));
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName2, host1, "DISABLED"));
     updateHostComponents(schRequests, new HashMap<String,String>(), false);
 
-    // delete HC
+    // Delete HC
     schRequests.clear();
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName1, host1, null));
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName2, host1, null));
@@ -8433,51 +8431,50 @@ public class AmbariManagementControllerTest {
 
     Assert.assertEquals(0, cluster.getServiceComponentHosts(host1).size());
 
-    // delete, which should fail since it is part of a cluster
+    // Deletion without specifying cluster should be successful
     requests.clear();
     requests.add(new HostRequest(host1, null, null));
     try {
       HostResourceProviderTest.deleteHosts(controller, requests);
-      fail("Expect failure when removing from host when it is part of a cluster.");
     } catch (Exception e) {
+      fail("Did not expect an error deleting the host from the cluster. Error: " + e.getMessage());
     }
-
-    // delete host from cluster
-    requests.clear();
-    requests.add(new HostRequest(host1, clusterName, null));
-    HostResourceProviderTest.deleteHosts(controller, requests);
-
-    // host is no longer part of the cluster
+    // Verify host is no longer part of the cluster
     Assert.assertFalse(clusters.getHostsForCluster(clusterName).containsKey(host1));
     Assert.assertFalse(clusters.getClustersForHost(host1).contains(cluster));
 
-    // delete entirely
+
+    // Case 3: Delete host that is still part of the cluster, and specify the cluster_name in the request
     requests.clear();
-    requests.add(new HostRequest(host1, null, null));
-    HostResourceProviderTest.deleteHosts(controller, requests);
+    requests.add(new HostRequest(host2, clusterName, null));
+    try {
+      HostResourceProviderTest.deleteHosts(controller, requests);
+    } catch (Exception e) {
+      fail("Did not expect an error deleting the host from the cluster. Error: " + e.getMessage());
+    }
+    // Verify host is no longer part of the cluster
+    Assert.assertFalse(clusters.getHostsForCluster(clusterName).containsKey(host2));
+    Assert.assertFalse(clusters.getClustersForHost(host2).contains(cluster));
 
-    // verify host does not exist
+    // Case 4: Attempt to delete a host that has already been deleted
+    requests.clear();
+    requests.add(new HostRequest(host1, null, null));
     try {
-      clusters.getHost(host1);
-      Assert.fail("Expected a HostNotFoundException.");
+      HostResourceProviderTest.deleteHosts(controller, requests);
+      Assert.fail("Expected a HostNotFoundException trying to remove a host that was already deleted.");
     } catch (HostNotFoundException e) {
       // expected
     }
 
-    // remove host2
-    requests.clear();
-    requests.add(new HostRequest(host2, null, null));
-    HostResourceProviderTest.deleteHosts(controller, requests);
-
-    // verify host does not exist
+    // Verify host does not exist
     try {
-      clusters.getHost(host2);
+      clusters.getHost(host1);
       Assert.fail("Expected a HostNotFoundException.");
     } catch (HostNotFoundException e) {
       // expected
     }
 
-    // try removing a host that never existed
+    // Case 5: Attempt to delete a host that was never added to the cluster
     requests.clear();
     requests.add(new HostRequest(host3, null, null));
     try {
@@ -8486,7 +8483,6 @@ public class AmbariManagementControllerTest {
     } catch (HostNotFoundException e) {
       // expected
     }
-
   }
 
   @Test
@@ -8557,7 +8553,7 @@ public class AmbariManagementControllerTest {
 
     String host1 = "h1";
 
-    addHost(host1, clusterName);
+    addHostToCluster(host1, clusterName);
 
     createServiceComponentHost(clusterName, null, componentName1, host1, null);
     createServiceComponentHost(clusterName, serviceName, componentName2, host1, null);
@@ -9587,7 +9583,7 @@ public class AmbariManagementControllerTest {
 
     String host1 = "h1";
 
-    addHost(host1, clusterName);
+    addHostToCluster(host1, clusterName);
     createServiceComponentHost(clusterName, hdfsService, namenode, host1, null);
     createServiceComponentHost(clusterName, hdfsService, datanode, host1, null);
     createServiceComponentHost(clusterName, fakeMonitoringService, fakeServer, host1,
@@ -9639,7 +9635,7 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
+    addHostToCluster(host1, clusterName);
     createServiceComponentHost(clusterName, hdfsService, namenode, host1, null);
     createServiceComponentHost(clusterName, hdfsService, datanode, host1, null);
     createServiceComponentHost(clusterName, zookeeperService, zookeeperServer, host1,
@@ -9653,7 +9649,7 @@ public class AmbariManagementControllerTest {
     }
     assertFalse(zookeeperSch.isRestartRequired());
 
-    addHost(host2, clusterName);
+    addHostToCluster(host2, clusterName);
     createServiceComponentHost(clusterName, zookeeperService, zookeeperServer, host2, null);
 
     assertFalse(zookeeperSch.isRestartRequired());  //No restart required if adding host
@@ -9685,8 +9681,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName, componentName1, host1,
         null);
@@ -9918,8 +9914,8 @@ public class AmbariManagementControllerTest {
     String host1 = "h1";
     String host2 = "h2";
 
-    addHost(host1, clusterName);
-    addHost(host2, clusterName);
+    addHostToCluster(host1, clusterName);
+    addHostToCluster(host2, clusterName);
 
     createServiceComponentHost(clusterName, serviceName1, componentName1_1, host1, null);
     createServiceComponentHost(clusterName, serviceName1, componentName1_2, host1, null);
@@ -10436,8 +10432,6 @@ public class AmbariManagementControllerTest {
     return HostComponentResourceProviderTest.updateHostComponents(
         controller, injector, requests, requestProperties, runSmokeTest);
   }
-
-
 }
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAOTest.java
index 0dcc471..327e08b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostConfigMappingDAOTest.java
@@ -181,7 +181,7 @@ public class HostConfigMappingDAOTest {
     createEntity(1L, "h1", "global", "version1");
 
     HostEntity hostEntity = hostDAO.findByName("h1");
-    hostConfigMappingDAO.removeHost(1L, "h1");
+    hostConfigMappingDAO.removeByClusterAndHostName(1L, "h1");
     HostConfigMapping target = hostConfigMappingDAO.findSelectedByType(1L, hostEntity.getHostId(), "core-site");
     
     Assert.assertEquals(null, target);

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
index 3d93e4d..4c186b5 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
@@ -298,10 +298,10 @@ public class ServiceConfigDAOTest {
 
     long clusterId = serviceConfigEntity.getClusterId();
 
-    List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getAllServiceConfigs(clusterId, HDP_01);
+    List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getAllServiceConfigsForClusterAndStack(clusterId, HDP_01);
     Assert.assertEquals(4, serviceConfigs.size());
 
-    serviceConfigs = serviceConfigDAO.getAllServiceConfigs(clusterId, HDP_02);
+    serviceConfigs = serviceConfigDAO.getAllServiceConfigsForClusterAndStack(clusterId, HDP_02);
     Assert.assertEquals(0, serviceConfigs.size());
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index ee7b1eb..5998098 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -2214,6 +2214,8 @@ Em.I18n.translations = {
   'hosts.delete.popup.body.msg1':'By removing this host, Ambari will ignore future communications from this host. Software packages will not be removed from the host. The components on the host should not be restarted. If you wish to readd this host to the cluster, be sure to clean the host.',
   'hosts.delete.popup.body.msg3':'If this host was hosting a Zookeeper Server, the Zookeeper Service should be restarted. Go to the <i>Services</i> page.',
   'hosts.delete.popup.body.msg4':'<b>WARNING!</b> Delete the last <i>{0}</i> component[s] in the cluster?</br>Deleting the last components in the cluster could result in permanent loss of service data.',
+  'hosts.delete.popup.body.msg5':'<b>WARNING!</b> The agent is still heartbeating so the Host will still exist in the database.',
+  'hosts.delete.popup.body.msg6':'To completely delete the Host, first stop ambari-agent on it.',
   'hosts.delete.popup.body.msg.unknownComponents':'This host does not appear to be online and Ambari communication with the Agent has been lost.',
   'hosts.delete.popup.header':'Confirmation',
   'hosts.delete.popup.title':'Delete Host',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9735a78d/ambari-web/app/templates/main/host/details/doDeleteHostPopup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/details/doDeleteHostPopup.hbs b/ambari-web/app/templates/main/host/details/doDeleteHostPopup.hbs
index a149364..1870a51 100644
--- a/ambari-web/app/templates/main/host/details/doDeleteHostPopup.hbs
+++ b/ambari-web/app/templates/main/host/details/doDeleteHostPopup.hbs
@@ -39,4 +39,14 @@
   {{/if}}
   {{t hosts.delete.popup.body.msg1}}
 </div>
+
+{{#unless unknownComponents}}
+  <div class='alert'>
+  <!-- Agent is still online, so host record will be re-inserted on next heartbeat. -->
+  {{t hosts.delete.popup.body.msg5}}
+  <span style="color: red;">{{t hosts.delete.popup.body.msg6}}</span>
+  </div>
+{{/unless}}
+
+
 <div class='alert'>{{{t common.important}}} {{t hosts.delete.popup.body.msg3}}</div>