Updated Branches: refs/heads/trunk f8444ad99 -> fbed96d8e
AMBARI-1777. Implement host delete. (ncole) Project: http://git-wip-us.apache.org/repos/asf/incubator-ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ambari/commit/fbed96d8 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ambari/tree/fbed96d8 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ambari/diff/fbed96d8 Branch: refs/heads/trunk Commit: fbed96d8e1f19ff46688a529ae360fc53d657b39 Parents: f8444ad Author: Nate Cole <[email protected]> Authored: Mon Jul 15 11:42:50 2013 -0400 Committer: Nate Cole <[email protected]> Committed: Mon Jul 15 17:19:06 2013 -0400 ---------------------------------------------------------------------- .../AmbariManagementControllerImpl.java | 73 +++++++++- .../server/orm/dao/HostConfigMappingDAO.java | 19 +++ .../HostComponentDesiredStateEntity.java | 2 +- .../orm/entities/HostComponentStateEntity.java | 2 +- .../orm/entities/HostConfigMappingEntity.java | 2 +- .../ambari/server/orm/entities/HostEntity.java | 10 +- .../orm/entities/HostRoleCommandEntity.java | 2 +- .../ServiceComponentDesiredStateEntity.java | 2 +- .../apache/ambari/server/state/Clusters.java | 15 ++ .../server/state/cluster/ClustersImpl.java | 95 ++++++++++++- .../AmbariManagementControllerTest.java | 142 ++++++++++++++++++- 11 files changed, 342 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java index 1bd20cb..cf23ee8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java @@ -3574,9 +3574,69 @@ public class AmbariManagementControllerImpl implements } @Override - public void deleteHosts(Set<HostRequest> request) + public void deleteHosts(Set<HostRequest> requests) throws AmbariException { - throw new AmbariException("Delete hosts not supported"); + + List<HostRequest> okToRemove = new ArrayList<HostRequest>(); + + for (HostRequest hostRequest : requests) { + String hostName = hostRequest.getHostname(); + if (null == hostName) + continue; + + if (null != hostRequest.getClusterName()) { + Cluster cluster = clusters.getCluster(hostRequest.getClusterName()); + + List<ServiceComponentHost> list = cluster.getServiceComponentHosts(hostName); + + if (0 != list.size()) { + StringBuilder reason = new StringBuilder("Cannot remove host ") + .append(hostName) + .append(" from ") + .append(hostRequest.getClusterName()) + .append(". The following roles exist: "); + + int i = 0; + for (ServiceComponentHost sch : list) { + if ((i++) > 0) + reason.append(", "); + reason.append(sch.getServiceComponentName()); + } + + 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); + } + } + + for (HostRequest hostRequest : okToRemove) { + if (null != hostRequest.getClusterName()) { + clusters.unmapHostFromCluster(hostRequest.getHostname(), + hostRequest.getClusterName()); + } else { + clusters.deleteHost(hostRequest.getHostname()); + } + } } @Override @@ -3617,11 +3677,12 @@ public class AmbariManagementControllerImpl implements + ", request=" + request); } - //Only allow removing master components in MAINTENANCE state without stages generation - if (component.isClientComponent() || + // Only allow removing master/slave components in MAINTENANCE state without stages generation. + // Clients may be removed without a state check. + if (!component.isClientComponent() && componentHost.getState() != State.MAINTENANCE) { - throw new AmbariException("Only master or slave component can be removed. They must be in " + - "MAINTENANCE state in order to be removed."); + throw new AmbariException("To remove master or slave components they must be in a " + + "MAINTENANCE state. Current=" + componentHost.getState() + "."); } if (!safeToRemoveSCHs.containsKey(component)) { http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/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 6451212..3a59a5e 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 @@ -88,4 +88,23 @@ public class HostConfigMappingDAO { return daoUtils.selectList(query, Long.valueOf(clusterId), type); } + /** + * @param clusterId + * @param hostName + */ + @Transactional + public void removeHost(long clusterId, String hostName) { + TypedQuery<HostConfigMappingEntity> query = entityManagerProvider.get().createQuery( + "SELECT entity FROM HostConfigMappingEntity entity " + + "WHERE entity.clusterId = ?1 AND entity.hostName = ?2", + HostConfigMappingEntity.class); + + List<HostConfigMappingEntity> list = daoUtils.selectList(query, Long.valueOf(clusterId), hostName); + + for (HostConfigMappingEntity entity : list) { + entityManagerProvider.get().remove(entity); + } + + } + } http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java index 4cb1f73..179c744 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java @@ -55,7 +55,7 @@ public class HostComponentDesiredStateEntity { @Column(name = "desired_stack_version", insertable = true, updatable = true) private String desiredStackVersion = ""; - @ManyToOne + @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false), @JoinColumn(name = "service_name", referencedColumnName = "service_name", nullable = false), http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java index d3854a3..29a906b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java @@ -55,7 +55,7 @@ public class HostComponentStateEntity { @Column(name = "current_stack_version", nullable = false, insertable = true, updatable = true) private String currentStackVersion; - @ManyToOne + @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumns({ @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false), @JoinColumn(name = "service_name", referencedColumnName = "service_name", nullable = false), http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/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 cca52ed..6c91eab 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 @@ -58,7 +58,7 @@ public class HostConfigMappingEntity { @Column(name = "user_name", insertable = true, updatable = true, nullable = false) private String user = null; - + public Long getClusterId() { return clusterId; } http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java index bc6f850..06ea84d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java @@ -97,10 +97,10 @@ public class HostEntity { @Lob private String hostAttributes = ""; - @OneToMany(mappedBy = "hostEntity") + @OneToMany(mappedBy = "hostEntity", cascade = {CascadeType.REMOVE, CascadeType.PERSIST}) private Collection<HostComponentDesiredStateEntity> hostComponentDesiredStateEntities; - @OneToMany(mappedBy = "hostEntity") + @OneToMany(mappedBy = "hostEntity", cascade = {CascadeType.REMOVE, CascadeType.PERSIST}) private Collection<HostComponentStateEntity> hostComponentStateEntities; @ManyToMany @@ -110,12 +110,12 @@ public class HostEntity { ) private Collection<ClusterEntity> clusterEntities; - @OneToOne(mappedBy = "hostEntity") + @OneToOne(mappedBy = "hostEntity", cascade = CascadeType.REMOVE) private HostStateEntity hostStateEntity; - @OneToMany(mappedBy = "host") + @OneToMany(mappedBy = "host", cascade = CascadeType.REMOVE) private Collection<HostRoleCommandEntity> hostRoleCommandEntities; - + public String getHostName() { return hostName; } http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/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 6dc25ce..50b2ec5 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 @@ -107,7 +107,7 @@ public class HostRoleCommandEntity { @JoinColumns({@JoinColumn(name = "request_id", referencedColumnName = "request_id", nullable = false), @JoinColumn(name = "stage_id", referencedColumnName = "stage_id", nullable = false)}) private StageEntity stage; - @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "host_name", referencedColumnName = "host_name", nullable = false) private HostEntity host; http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java index e57b0e1..f5cca9a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java @@ -55,7 +55,7 @@ public class ServiceComponentDesiredStateEntity { @JoinColumns({@javax.persistence.JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false), @JoinColumn(name = "service_name", referencedColumnName = "service_name", nullable = false)}) private ClusterServiceEntity clusterServiceEntity; - @OneToMany(mappedBy = "serviceComponentDesiredStateEntity") + @OneToMany(mappedBy = "serviceComponentDesiredStateEntity", cascade = CascadeType.PERSIST) private Collection<HostComponentStateEntity> hostComponentStateEntities; @OneToMany(mappedBy = "serviceComponentDesiredStateEntity") http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java index 8e35971..634f594 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java @@ -158,4 +158,19 @@ public interface Clusters { public void updateHostWithClusterAndAttributes( Map<String, Set<String>> hostsClusters, Map<String, Map<String, String>> hostAttributes) throws AmbariException; + + /** + * Removes a host from a cluster. Inverts {@link #mapHostToCluster(String, String) + * @param hostname + * @param clusterName + */ + public void unmapHostFromCluster(String hostname, String clusterName) + throws AmbariException; + + /** + * Removes a host. Inverts {@link #addHost(String)} + * @param hostname + */ + public void deleteHost(String hostname) + throws AmbariException; } http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/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 e64ad9d..444bf35 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 @@ -18,15 +18,20 @@ package org.apache.ambari.server.state.cluster; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.persistence.RollbackException; -import com.google.gson.Gson; -import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.ClusterNotFoundException; import org.apache.ambari.server.DuplicateResourceException; @@ -34,17 +39,27 @@ import org.apache.ambari.server.HostNotFoundException; import org.apache.ambari.server.agent.DiskInfo; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.orm.dao.ClusterDAO; +import org.apache.ambari.server.orm.dao.HostConfigMappingDAO; import org.apache.ambari.server.orm.dao.HostDAO; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.HostEntity; -import org.apache.ambari.server.state.*; +import org.apache.ambari.server.state.AgentVersion; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.HostHealthStatus; import org.apache.ambari.server.state.HostHealthStatus.HealthStatus; +import org.apache.ambari.server.state.HostState; +import org.apache.ambari.server.state.RepositoryInfo; +import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.host.HostFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.Gson; import com.google.inject.Inject; import com.google.inject.Singleton; +import com.google.inject.persist.Transactional; @Singleton public class ClustersImpl implements Clusters { @@ -76,6 +91,8 @@ public class ClustersImpl implements Clusters { AmbariMetaInfo ambariMetaInfo; @Inject Gson gson; + @Inject + private HostConfigMappingDAO hostConfigMappingDAO; @Inject public ClustersImpl() { @@ -452,7 +469,7 @@ public class ClustersImpl implements Clusters { w.unlock(); } } - + @Transactional void mapHostClusterEntities(String hostName, Long clusterId) { HostEntity hostEntity = hostDAO.findByName(hostName); @@ -567,5 +584,73 @@ public class ClustersImpl implements Clusters { w.unlock(); } } + + @Override + public void unmapHostFromCluster(String hostname, String clusterName) + throws AmbariException { + + loadClustersAndHosts(); + + w.lock(); + + try { + Host host = getHost(hostname); + Cluster cluster = getCluster(clusterName); + + if (LOG.isDebugEnabled()) { + LOG.debug("Unmapping a host from a cluster" + + ", clusterName=" + clusterName + + ", clusterId=" + cluster.getClusterId() + + ", hostname=" + hostname); + } + + unmapHostClusterEntities(hostname, cluster.getClusterId()); + + hostClusterMap.get(hostname).remove(cluster); + clusterHostMap.get(clusterName).remove(host); + + } finally { + w.unlock(); + } + + } + + @Transactional + private void unmapHostClusterEntities(String hostName, long clusterId) { + HostEntity hostEntity = hostDAO.findByName(hostName); + ClusterEntity clusterEntity = clusterDAO.findById(clusterId); + + hostEntity.getClusterEntities().remove(clusterEntity); + clusterEntity.getHostEntities().remove(hostEntity); + + hostConfigMappingDAO.removeHost(clusterId, hostName); + + hostDAO.merge(hostEntity); + clusterDAO.merge(clusterEntity); + } + + @Override + public void deleteHost(String hostname) throws AmbariException { + loadClustersAndHosts(); + + if (!hosts.containsKey(hostname)) + return; + + w.lock(); + + try { + HostEntity entity = hostDAO.findByName(hostname); + hostDAO.refresh(entity); + + hostDAO.remove(entity); + + hosts.remove(hostname); + } catch (Exception e) { + throw new AmbariException("Could not remove host", e); + } finally { + w.unlock(); + } + + } } http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/fbed96d8/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 59886d0..db855cb 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 @@ -21,7 +21,6 @@ package org.apache.ambari.server.controller; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -42,6 +41,7 @@ import junit.framework.Assert; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.ClusterNotFoundException; import org.apache.ambari.server.DuplicateResourceException; +import org.apache.ambari.server.HostNotFoundException; import org.apache.ambari.server.ObjectNotFoundException; import org.apache.ambari.server.ParentObjectNotFoundException; import org.apache.ambari.server.Role; @@ -80,6 +80,8 @@ import org.apache.ambari.server.state.ServiceFactory; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.StackInfo; import org.apache.ambari.server.state.State; +import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent; +import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpSucceededEvent; import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent; import org.apache.ambari.server.utils.StageUtils; import org.junit.After; @@ -6566,4 +6568,142 @@ public class AmbariManagementControllerTest { assertEquals(original, repo.getDefaultBaseUrl()); } + @Test + public void testDeleteHost() throws Exception { + String clusterName = "foo1"; + + createCluster(clusterName); + + Cluster cluster = clusters.getCluster(clusterName); + cluster.setDesiredStackVersion(new StackId("HDP-0.1")); + + String serviceName = "HDFS"; + createService(clusterName, serviceName, null); + String componentName1 = "NAMENODE"; + String componentName2 = "DATANODE"; + String componentName3 = "HDFS_CLIENT"; + + Map<String, String> mapRequestProps = new HashMap<String, String>(); + mapRequestProps.put("context", "Called from a test"); + + createServiceComponent(clusterName, serviceName, componentName1, State.INIT); + createServiceComponent(clusterName, serviceName, componentName2, State.INIT); + createServiceComponent(clusterName, serviceName, componentName3, State.INIT); + + String host1 = "h1"; + clusters.addHost(host1); + clusters.getHost("h1").setOsType("centos5"); + clusters.getHost("h1").persist(); + + String host2 = "h2"; + clusters.addHost(host2); + clusters.getHost("h2").setOsType("centos6"); + clusters.getHost("h2").persist(); + + String host3 = "h3"; + + clusters.mapHostToCluster(host1, clusterName); + + createServiceComponentHost(clusterName, null, 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 + Map<String, ServiceComponentHost> hostComponents = cluster.getService(serviceName).getServiceComponent(componentName1).getServiceComponentHosts(); + for (Map.Entry<String, ServiceComponentHost> entry : hostComponents.entrySet()) { + ServiceComponentHost cHost = entry.getValue(); + cHost.handleEvent(new ServiceComponentHostInstallEvent(cHost.getServiceComponentName(), cHost.getHostName(), System.currentTimeMillis(), cluster.getDesiredStackVersion().getStackId())); + cHost.handleEvent(new ServiceComponentHostOpSucceededEvent(cHost.getServiceComponentName(), cHost.getHostName(), System.currentTimeMillis())); + } + hostComponents = cluster.getService(serviceName).getServiceComponent(componentName2).getServiceComponentHosts(); + for (Map.Entry<String, ServiceComponentHost> entry : hostComponents.entrySet()) { + ServiceComponentHost cHost = entry.getValue(); + cHost.handleEvent(new ServiceComponentHostInstallEvent(cHost.getServiceComponentName(), cHost.getHostName(), System.currentTimeMillis(), cluster.getDesiredStackVersion().getStackId())); + cHost.handleEvent(new ServiceComponentHostOpSucceededEvent(cHost.getServiceComponentName(), cHost.getHostName(), System.currentTimeMillis())); + } + + Set<HostRequest> requests = new HashSet<HostRequest>(); + // delete from cluster + requests.clear(); + requests.add(new HostRequest(host1, clusterName, null)); + try { + controller.deleteHosts(requests); + fail("Expect failure deleting hosts when components exist."); + } catch (Exception e) { + } + + Set<ServiceComponentHostRequest> schRequests = new HashSet<ServiceComponentHostRequest>(); + // maintenance HC for non-clients + schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName1, host1, null, "MAINTENANCE")); + schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName2, host1, null, "MAINTENANCE")); + controller.updateHostComponents(schRequests, new HashMap<String,String>(), false); + + // delete HC + schRequests.clear(); + schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName1, host1, null, null)); + schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName2, host1, null, null)); + schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, componentName3, host1, null, null)); + controller.deleteHostComponents(schRequests); + + Assert.assertEquals(0, cluster.getServiceComponentHosts(host1).size()); + + // delete, which should fail since it is part of a cluster + requests.clear(); + requests.add(new HostRequest(host1, null, null)); + try { + controller.deleteHosts(requests); + fail("Expect failure when removing from host when it is part of a cluster."); + } catch (Exception e) { + } + + // delete host from cluster + requests.clear(); + requests.add(new HostRequest(host1, clusterName, null)); + controller.deleteHosts(requests); + + // host is no longer part of the cluster + Assert.assertFalse(clusters.getHostsForCluster(clusterName).containsKey(host1)); + Assert.assertFalse(clusters.getClustersForHost(host1).contains(cluster)); + + // delete entirely + requests.clear(); + requests.add(new HostRequest(host1, null, null)); + controller.deleteHosts(requests); + + // verify host does not exist + try { + clusters.getHost(host1); + Assert.fail("Expected a HostNotFoundException."); + } catch (HostNotFoundException e) { + // expected + } + + // remove host2 + requests.clear(); + requests.add(new HostRequest(host2, null, null)); + controller.deleteHosts(requests); + + // verify host does not exist + try { + clusters.getHost(host2); + Assert.fail("Expected a HostNotFoundException."); + } catch (HostNotFoundException e) { + // expected + } + + // try removing a host that never existed + requests.clear(); + requests.add(new HostRequest(host3, null, null)); + try { + controller.deleteHosts(requests); + Assert.fail("Expected a HostNotFoundException trying to remove a host that was never added."); + } catch (HostNotFoundException e) { + // expected + } + + } + }
