You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mp...@apache.org on 2018/05/15 16:36:13 UTC

[ambari] branch trunk updated: AMBARI-23791. Agent is not notified about cluster delete in runtime. (#1274)

This is an automated email from the ASF dual-hosted git repository.

mpapirkovskyy pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new a949b8a  AMBARI-23791. Agent is not notified about cluster delete in runtime. (#1274)
a949b8a is described below

commit a949b8aa2b1daebf9a11760b597c581ebdcbd66a
Author: Myroslav Papirkovskyi <mp...@apache.org>
AuthorDate: Tue May 15 19:36:10 2018 +0300

    AMBARI-23791. Agent is not notified about cluster delete in runtime. (#1274)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (mpapirkovskyy)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (mpapirkovskyy)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (mpapirkovskyy)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (aonishuk)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (mpapirkovskyy)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (mpapirkovskyy)
    
    * AMBARI-23791. Agent is not notified about cluster delete in runtime. (mpapirkovskyy)
---
 .../python/ambari_agent/ClusterMetadataCache.py    | 18 ++++++
 .../listeners/MetadataEventListener.py             | 11 +++-
 .../server/agent/stomp/AgentConfigsHolder.java     |  4 ++
 .../server/agent/stomp/AlertDefinitionsHolder.java | 17 ++++-
 .../server/agent/stomp/HostLevelParamsHolder.java  |  7 ++
 .../ambari/server/agent/stomp/MetadataHolder.java  | 44 +++++++++++--
 .../ambari/server/agent/stomp/TopologyHolder.java  | 28 ++++----
 .../server/agent/stomp/dto/AlertCluster.java       | 11 +++-
 .../server/agent/stomp/dto/MetadataCluster.java    |  4 ++
 .../server/agent/stomp/dto/TopologyCluster.java    | 31 +++++----
 .../controller/AmbariManagementControllerImpl.java | 37 ++++-------
 .../internal/ComponentResourceProvider.java        | 10 +--
 .../controller/internal/HostResourceProvider.java  |  7 +-
 .../internal/ServiceResourceProvider.java          |  8 +--
 .../ambari/server/events/MetadataUpdateEvent.java  | 13 +++-
 .../server/events/TopologyAgentUpdateEvent.java    |  2 +-
 .../ambari/server/events/TopologyUpdateEvent.java  | 14 ++--
 .../ambari/server/events/UpdateEventType.java      |  1 -
 .../apache/ambari/server/state/ConfigHelper.java   |  7 ++
 .../ambari/server/state/cluster/ClusterImpl.java   |  8 +--
 .../ambari/server/state/cluster/ClustersImpl.java  |  3 +-
 .../svccomphost/ServiceComponentHostImpl.java      |  3 +-
 ...rmer.java => STOMPComponentsDeleteHandler.java} | 74 +++++++++++++++++-----
 .../internal/ComponentResourceProviderTest.java    | 26 +++++---
 .../internal/ServiceResourceProviderTest.java      | 12 ++--
 .../apache/ambari/server/events/EventsTest.java    |  1 +
 .../ambari/server/state/cluster/ClustersTest.java  |  8 ++-
 27 files changed, 290 insertions(+), 119 deletions(-)

diff --git a/ambari-agent/src/main/python/ambari_agent/ClusterMetadataCache.py b/ambari-agent/src/main/python/ambari_agent/ClusterMetadataCache.py
index 2488ef0..2ae7962 100644
--- a/ambari-agent/src/main/python/ambari_agent/ClusterMetadataCache.py
+++ b/ambari-agent/src/main/python/ambari_agent/ClusterMetadataCache.py
@@ -38,5 +38,23 @@ class ClusterMetadataCache(ClusterCache):
     """
     super(ClusterMetadataCache, self).__init__(cluster_cache_dir)
 
+  def cache_delete(self, cache_update, cache_hash):
+    """
+    Only deleting cluster is supported here
+    """
+    mutable_dict = self._get_mutable_copy()
+    clusters_ids_to_delete = []
+
+    for cluster_id, cluster_updates_dict in cache_update.iteritems():
+      if cluster_updates_dict != {}:
+        raise Exception("Deleting cluster subvalues is not supported")
+
+      clusters_ids_to_delete.append(cluster_id)
+
+    for cluster_id in clusters_ids_to_delete:
+      del mutable_dict[cluster_id]
+
+    self.rewrite_cache(mutable_dict, cache_hash)
+
   def get_cache_name(self):
     return 'metadata'
diff --git a/ambari-agent/src/main/python/ambari_agent/listeners/MetadataEventListener.py b/ambari-agent/src/main/python/ambari_agent/listeners/MetadataEventListener.py
index 3dd7177..d80e40b 100644
--- a/ambari-agent/src/main/python/ambari_agent/listeners/MetadataEventListener.py
+++ b/ambari-agent/src/main/python/ambari_agent/listeners/MetadataEventListener.py
@@ -47,7 +47,16 @@ class MetadataEventListener(EventListener):
     if message == {}:
       return
 
-    self.metadata_cache.cache_update(message['clusters'], message['hash'])
+    event_type = message['eventType']
+
+    if event_type == 'CREATE':
+      self.metadata_cache.rewrite_cache(message['clusters'], message['hash'])
+    elif event_type == 'UPDATE':
+      self.metadata_cache.cache_update(message['clusters'], message['hash'])
+    elif event_type == 'DELETE':
+      self.metadata_cache.cache_delete(message['clusters'], message['hash'])
+    else:
+      logger.error("Unknown event type '{0}' for metadata event")
 
     try:
       self.config.update_configuration_from_metadata(message['clusters']['-1']['agentConfigs'])
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentConfigsHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentConfigsHolder.java
index 68b9b68..e8db31d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentConfigsHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentConfigsHolder.java
@@ -54,6 +54,10 @@ public class AgentConfigsHolder extends AgentHostDataHolder<AgentConfigsUpdateEv
     return configHelper.getHostActualConfigs(hostId);
   }
 
+  public AgentConfigsUpdateEvent getCurrentDataExcludeCluster(Long hostId, Long clusterId) throws AmbariException {
+    return configHelper.getHostActualConfigsExcludeCluster(hostId, clusterId);
+  }
+
   protected boolean handleUpdate(AgentConfigsUpdateEvent update) throws AmbariException {
     setData(update, update.getHostId());
     return true;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
index 6bf0587..c20d6a4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
@@ -18,6 +18,7 @@
 package org.apache.ambari.server.agent.stomp;
 
 import static org.apache.ambari.server.events.AlertDefinitionEventType.CREATE;
+import static org.apache.ambari.server.events.AlertDefinitionEventType.DELETE;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -43,6 +44,7 @@ import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
 import org.apache.ambari.server.state.alert.AlertDefinitionHash;
 import org.apache.ambari.server.state.alert.AlertHelper;
+import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -94,6 +96,12 @@ public class AlertDefinitionsHolder extends AgentHostDataHolder<AlertDefinitions
     return new AlertDefinitionsAgentUpdateEvent(CREATE, result, hostName, hostId);
   }
 
+  public AlertDefinitionsAgentUpdateEvent getDeleteCluster(Long clusterId, Long hostId) throws AmbariException {
+    Map<Long, AlertCluster> result = new TreeMap<>();
+    result.put(clusterId, AlertCluster.emptyAlertCluster());
+    return new AlertDefinitionsAgentUpdateEvent(DELETE, result, null, hostId);
+  }
+
   @Override
   protected AlertDefinitionsAgentUpdateEvent getEmptyData() {
     return AlertDefinitionsAgentUpdateEvent.emptyEvent();
@@ -114,10 +122,15 @@ public class AlertDefinitionsHolder extends AgentHostDataHolder<AlertDefinitions
       case UPDATE:
       case DELETE:
         if (!existingClusters.keySet().containsAll(updateClusters.keySet())) {
-          throw new AmbariException("Unknown clusters in update");
+          LOG.info("Unknown clusters in update, perhaps cluster was removed previously");
         }
         for (Map.Entry<Long, AlertCluster> e : updateClusters.entrySet()) {
-          changed |= existingClusters.get(e.getKey()).handleUpdate(update.getEventType(), e.getValue());
+          if (CollectionUtils.isEmpty(e.getValue().getAlertDefinitions())) {
+            existingClusters.remove(e.getKey());
+            changed = true;
+          } else {
+            changed |= existingClusters.get(e.getKey()).handleUpdate(update.getEventType(), e.getValue());
+          }
         }
         LOG.debug("Handled {} of alerts for {} cluster(s) on host with id {}, changed = {}", update.getEventType(), updateClusters.size(), hostId, changed);
         break;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java
index b2c1b22..abd78c8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java
@@ -55,9 +55,16 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
 
   @Override
   public HostLevelParamsUpdateEvent getCurrentData(Long hostId) throws AmbariException {
+    return getCurrentDataExcludeCluster(hostId, null);
+  }
+
+  public HostLevelParamsUpdateEvent getCurrentDataExcludeCluster(Long hostId, Long clusterId) throws AmbariException {
     TreeMap<String, HostLevelParamsCluster> hostLevelParamsClusters = new TreeMap<>();
     Host host = clusters.getHostById(hostId);
     for (Cluster cl : clusters.getClustersForHost(host.getHostName())) {
+      if (clusterId != null && cl.getClusterId() == clusterId) {
+        continue;
+      }
       HostLevelParamsCluster hostLevelParamsCluster = new HostLevelParamsCluster(
           m_ambariManagementController.get().retrieveHostRepositories(cl, host),
           recoveryConfigHelper.getRecoveryConfig(cl.getClusterName(), host.getHostName()));
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/MetadataHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/MetadataHolder.java
index 6e5d9cc..b3558cd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/MetadataHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/MetadataHolder.java
@@ -18,8 +18,10 @@
 package org.apache.ambari.server.agent.stomp;
 
 import java.util.Map;
+import java.util.TreeMap;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.agent.stomp.dto.MetadataCluster;
 import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
 import org.apache.ambari.server.events.AmbariPropertiesChangedEvent;
@@ -28,6 +30,7 @@ import org.apache.ambari.server.events.ClusterConfigChangedEvent;
 import org.apache.ambari.server.events.MetadataUpdateEvent;
 import org.apache.ambari.server.events.ServiceCredentialStoreUpdateEvent;
 import org.apache.ambari.server.events.ServiceInstalledEvent;
+import org.apache.ambari.server.events.UpdateEventType;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -57,23 +60,52 @@ public class MetadataHolder extends AgentClusterDataHolder<MetadataUpdateEvent>
     return ambariManagementController.getClustersMetadata();
   }
 
+  public MetadataUpdateEvent getDeleteMetadata(Long clusterId) throws AmbariException {
+    TreeMap<String, MetadataCluster> clusterToRemove = new TreeMap<>();
+    if (clusterId != null) {
+      clusterToRemove.put(Long.toString(clusterId), MetadataCluster.emptyMetadataCluster());
+    }
+    MetadataUpdateEvent deleteEvent = new MetadataUpdateEvent(clusterToRemove, null , null,
+        UpdateEventType.DELETE);
+    return deleteEvent;
+  }
+
   @Override
   protected boolean handleUpdate(MetadataUpdateEvent update) throws AmbariException {
     boolean changed = false;
+    UpdateEventType eventType = update.getEventType();
     if (MapUtils.isNotEmpty(update.getMetadataClusters())) {
       for (Map.Entry<String, MetadataCluster> metadataClusterEntry : update.getMetadataClusters().entrySet()) {
         MetadataCluster updatedCluster = metadataClusterEntry.getValue();
         String clusterId = metadataClusterEntry.getKey();
         Map<String, MetadataCluster> clusters = getData().getMetadataClusters();
         if (clusters.containsKey(clusterId)) {
-          MetadataCluster cluster = clusters.get(clusterId);
-          cluster.getClusterLevelParams().putAll(updatedCluster.getClusterLevelParams());
-          cluster.getServiceLevelParams().putAll(updatedCluster.getServiceLevelParams());
-          cluster.getStatusCommandsToRun().addAll(updatedCluster.getStatusCommandsToRun());
+          if (eventType.equals(UpdateEventType.DELETE)) {
+            getData().getMetadataClusters().remove(clusterId);
+            changed = true;
+          } else {
+            MetadataCluster cluster = clusters.get(clusterId);
+            if (!cluster.getClusterLevelParams().equals(updatedCluster.getClusterLevelParams())) {
+              cluster.getClusterLevelParams().putAll(updatedCluster.getClusterLevelParams());
+              changed = true;
+            }
+            if (!cluster.getServiceLevelParams().equals(updatedCluster.getServiceLevelParams())) {
+              cluster.getServiceLevelParams().putAll(updatedCluster.getServiceLevelParams());
+              changed = true;
+            }
+            if (!cluster.getStatusCommandsToRun().equals(updatedCluster.getStatusCommandsToRun())) {
+              cluster.getStatusCommandsToRun().addAll(updatedCluster.getStatusCommandsToRun());
+              changed = true;
+            }
+          }
         } else {
-          clusters.put(clusterId, updatedCluster);
+          if (eventType.equals(UpdateEventType.UPDATE)) {
+            clusters.put(clusterId, updatedCluster);
+            changed = true;
+          } else {
+            throw new ClusterNotFoundException(Long.parseLong(clusterId));
+          }
         }
-        changed = true;
       }
     }
     return changed;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
index fe76c12..69a0726 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
@@ -33,6 +33,7 @@ import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
 import org.apache.ambari.server.events.ClusterComponentsRepoChangedEvent;
 import org.apache.ambari.server.events.TopologyAgentUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -120,7 +121,7 @@ public class TopologyHolder extends AgentClusterDataHolder<TopologyUpdateEvent>
       topologyClusters.put(Long.toString(cl.getClusterId()),
           new TopologyCluster(topologyComponents, topologyHosts));
     }
-    return new TopologyUpdateEvent(topologyClusters, TopologyUpdateEvent.EventType.CREATE);
+    return new TopologyUpdateEvent(topologyClusters, UpdateEventType.CREATE);
   }
 
   @Override
@@ -145,14 +146,14 @@ public class TopologyHolder extends AgentClusterDataHolder<TopologyUpdateEvent>
   @Override
   protected boolean handleUpdate(TopologyUpdateEvent update) throws AmbariException {
     boolean changed = false;
-    TopologyUpdateEvent.EventType eventType = update.getEventType();
+    UpdateEventType eventType = update.getEventType();
     for (Map.Entry<String, TopologyCluster> updatedCluster : update.getClusters().entrySet()) {
       String clusterId = updatedCluster.getKey();
       TopologyCluster cluster = updatedCluster.getValue();
       if (getData().getClusters().containsKey(clusterId)) {
-        if (eventType.equals(TopologyUpdateEvent.EventType.DELETE) &&
-            CollectionUtils.isEmpty(getData().getClusters().get(clusterId).getTopologyComponents()) &&
-            CollectionUtils.isEmpty(getData().getClusters().get(clusterId).getTopologyHosts())) {
+        if (eventType.equals(UpdateEventType.DELETE) &&
+            CollectionUtils.isEmpty(cluster.getTopologyComponents()) &&
+            CollectionUtils.isEmpty(cluster.getTopologyHosts())) {
           getData().getClusters().remove(clusterId);
           changed = true;
         } else {
@@ -164,7 +165,7 @@ public class TopologyHolder extends AgentClusterDataHolder<TopologyUpdateEvent>
           }
         }
       } else {
-        if (eventType.equals(TopologyUpdateEvent.EventType.UPDATE)) {
+        if (eventType.equals(UpdateEventType.UPDATE)) {
           getData().getClusters().put(clusterId, cluster);
           changed = true;
         } else {
@@ -178,12 +179,15 @@ public class TopologyHolder extends AgentClusterDataHolder<TopologyUpdateEvent>
   private void prepareAgentTopology(TopologyUpdateEvent topologyUpdateEvent) {
     if (topologyUpdateEvent.getClusters() != null) {
       for (TopologyCluster topologyCluster : topologyUpdateEvent.getClusters().values()) {
-        for (TopologyComponent topologyComponent : topologyCluster.getTopologyComponents()) {
-          topologyComponent.setHostNames(new HashSet<>());
-          topologyComponent.setPublicHostNames(new HashSet<>());
-          topologyComponent.setLastComponentState(null);
+        if (CollectionUtils.isNotEmpty(topologyCluster.getTopologyComponents())) {
+          for (TopologyComponent topologyComponent : topologyCluster.getTopologyComponents()) {
+            topologyComponent.setHostNames(new HashSet<>());
+            topologyComponent.setPublicHostNames(new HashSet<>());
+            topologyComponent.setLastComponentState(null);
+          }
         }
-        if (topologyUpdateEvent.getEventType().equals(TopologyUpdateEvent.EventType.DELETE)) {
+        if (topologyUpdateEvent.getEventType().equals(UpdateEventType.DELETE)
+            && CollectionUtils.isNotEmpty(topologyCluster.getTopologyHosts())) {
           for (TopologyHost topologyHost : topologyCluster.getTopologyHosts()) {
             topologyHost.setHostName(null);
           }
@@ -205,7 +209,7 @@ public class TopologyHolder extends AgentClusterDataHolder<TopologyUpdateEvent>
     topologyCluster.setTopologyComponents(getTopologyComponentRepos(clusterId));
     TreeMap<String, TopologyCluster> topologyUpdates = new TreeMap<>();
     topologyUpdates.put(Long.toString(clusterId), topologyCluster);
-    TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(topologyUpdates, TopologyUpdateEvent.EventType.UPDATE);
+    TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(topologyUpdates, UpdateEventType.UPDATE);
     updateData(topologyUpdateEvent);
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
index fb92d47..ac34d4a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
@@ -59,6 +59,11 @@ public class AlertCluster {
     this.staleIntervalMultiplier = null;
   }
 
+  private AlertCluster() {
+    alertDefinitions = null;
+    hostName = null;
+  }
+
   @JsonProperty("staleIntervalMultiplier")
   public Integer getStaleIntervalMultiplier() {
     return staleIntervalMultiplier;
@@ -66,7 +71,7 @@ public class AlertCluster {
 
   @JsonProperty("alertDefinitions")
   public Collection<AlertDefinition> getAlertDefinitions() {
-    return alertDefinitions.values();
+    return alertDefinitions == null ? Collections.emptyList() : alertDefinitions.values();
   }
 
   @JsonProperty("hostName")
@@ -110,4 +115,8 @@ public class AlertCluster {
 
     return changed;
   }
+
+  public static AlertCluster emptyAlertCluster() {
+    return new AlertCluster();
+  }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/MetadataCluster.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/MetadataCluster.java
index 249d2a2..bb3604e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/MetadataCluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/MetadataCluster.java
@@ -50,6 +50,10 @@ public class MetadataCluster {
     this.agentConfigs = agentConfigs;
   }
 
+  public static MetadataCluster emptyMetadataCluster() {
+    return new MetadataCluster(null, null, null, null);
+  }
+
   public Set<String> getStatusCommandsToRun() {
     return statusCommandsToRun;
   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyCluster.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyCluster.java
index 6e44124..2a49f43 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyCluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyCluster.java
@@ -21,7 +21,8 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
-import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.SetUtils;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
@@ -44,14 +45,14 @@ public class TopologyCluster {
   }
 
   public boolean update(Set<TopologyComponent> componentsToUpdate, Set<TopologyHost> hostsToUpdate,
-                     TopologyUpdateEvent.EventType eventType) {
+                     UpdateEventType eventType) {
     boolean changed = false;
     for (TopologyComponent componentToUpdate : componentsToUpdate) {
       boolean isPresent = false;
       for (Iterator<TopologyComponent> iter = getTopologyComponents().iterator(); iter.hasNext() && !isPresent; ) {
         TopologyComponent existsComponent = iter.next();
         if (existsComponent.equals(componentToUpdate)) {
-          if (eventType.equals(TopologyUpdateEvent.EventType.DELETE)) {
+          if (eventType.equals(UpdateEventType.DELETE)) {
             if (SetUtils.isEqualSet(existsComponent.getHostIds(), componentToUpdate.getHostIds())) {
               iter.remove();
               changed = true;
@@ -64,7 +65,7 @@ public class TopologyCluster {
           isPresent = true;
         }
       }
-      if (!isPresent && eventType.equals(TopologyUpdateEvent.EventType.UPDATE)) {
+      if (!isPresent && eventType.equals(UpdateEventType.UPDATE)) {
         getTopologyComponents().add(componentToUpdate);
         changed = true;
       }
@@ -74,7 +75,7 @@ public class TopologyCluster {
       for (Iterator<TopologyHost> iter = getTopologyHosts().iterator(); iter.hasNext() && !isPresent; ) {
         TopologyHost existsHost = iter.next();
         if (existsHost.equals(hostToUpdate)) {
-          if (eventType.equals(TopologyUpdateEvent.EventType.DELETE)) {
+          if (eventType.equals(UpdateEventType.DELETE)) {
             iter.remove();
             changed = true;
           } else {
@@ -83,7 +84,7 @@ public class TopologyCluster {
           isPresent = true;
         }
       }
-      if (!isPresent && eventType.equals(TopologyUpdateEvent.EventType.UPDATE)) {
+      if (!isPresent && eventType.equals(UpdateEventType.UPDATE)) {
         getTopologyHosts().add(hostToUpdate);
         changed = true;
       }
@@ -108,13 +109,19 @@ public class TopologyCluster {
   }
 
   public TopologyCluster deepCopyCluster() {
-    Set<TopologyComponent> copiedComponents = new HashSet<>();
-    for (TopologyComponent topologyComponent : topologyComponents) {
-      copiedComponents.add(topologyComponent.deepCopy());
+    Set<TopologyComponent> copiedComponents = null;
+    if (CollectionUtils.isNotEmpty(topologyComponents)) {
+      copiedComponents = new HashSet<>();
+      for (TopologyComponent topologyComponent : topologyComponents) {
+        copiedComponents.add(topologyComponent.deepCopy());
+      }
     }
-    Set<TopologyHost> copiedHosts = new HashSet<>();
-    for (TopologyHost topologyHost : topologyHosts) {
-      copiedHosts.add(topologyHost.deepCopy());
+    Set<TopologyHost> copiedHosts = null;
+    if (CollectionUtils.isNotEmpty(topologyHosts)) {
+      copiedHosts = new HashSet<>();
+      for (TopologyHost topologyHost : topologyHosts) {
+        copiedHosts.add(topologyHost.deepCopy());
+      }
     }
     return new TopologyCluster(copiedComponents, copiedHosts);
   }
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 ffd9b12..aaf46f9 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
@@ -137,6 +137,7 @@ import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.events.MetadataUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
@@ -229,8 +230,8 @@ import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpSucceede
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostUpgradeEvent;
+import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
 import org.apache.ambari.server.topology.Setting;
-import org.apache.ambari.server.topology.TopologyDeleteFormer;
 import org.apache.ambari.server.utils.SecretReference;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.collections.CollectionUtils;
@@ -358,7 +359,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   protected OsFamily osFamily;
 
   @Inject
-  private TopologyDeleteFormer topologyDeleteFormer;
+  private STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler;
 
   @Inject
   private Provider<TopologyHolder> m_topologyHolder;
@@ -800,7 +801,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         Set<TopologyComponent> newComponents = new HashSet<>();
         newComponents.add(newComponent);
         topologyUpdates.get(clusterId).update(newComponents, Collections.emptySet(),
-            TopologyUpdateEvent.EventType.UPDATE);
+            UpdateEventType.UPDATE);
       } else {
         topologyUpdates.get(clusterId).addTopologyComponent(newComponent);
       }
@@ -809,7 +810,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       Host host = clusters.getHost(hostName);
       m_hostLevelParamsHolder.get().updateData(m_hostLevelParamsHolder.get().getCurrentData(host.getHostId()));
     }
-    return new TopologyUpdateEvent(topologyUpdates, TopologyUpdateEvent.EventType.UPDATE);
+    return new TopologyUpdateEvent(topologyUpdates, UpdateEventType.UPDATE);
   }
 
   private void setMonitoringServicesRestartRequired(
@@ -3665,7 +3666,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     //Response for these requests will have empty body with appropriate error code.
     if (deleteMetaData.getDeletedKeys().size() + deleteMetaData.getExceptionForKeys().size() == 1) {
       if (deleteMetaData.getDeletedKeys().size() == 1) {
-        topologyDeleteFormer.processDeleteMetaData(deleteMetaData);
+        STOMPComponentsDeleteHandler.processDeleteByMetaData(deleteMetaData);
         return null;
       }
       Exception ex = deleteMetaData.getExceptionForKeys().values().iterator().next();
@@ -3680,7 +3681,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     if (!safeToRemoveSCHs.isEmpty()) {
       setMonitoringServicesRestartRequired(requests);
     }
-    topologyDeleteFormer.processDeleteMetaData(deleteMetaData);
+    STOMPComponentsDeleteHandler.processDeleteByMetaData(deleteMetaData);
     return deleteMetaData;
   }
 
@@ -5575,7 +5576,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   /**
-   * Collects metadata info about clusters for agent.
+   * Collects full metadata info about clusters for agent.
    * @return metadata info about clusters
    * @throws AmbariException
    */
@@ -5595,7 +5596,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     }
 
     MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
-        getMetadataAmbariLevelParams(), getMetadataAgentConfigs());
+        getMetadataAmbariLevelParams(), getMetadataAgentConfigs(), UpdateEventType.CREATE);
     return metadataUpdateEvent;
   }
 
@@ -5612,7 +5613,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
 
     MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
-        null, getMetadataAgentConfigs());
+        null, getMetadataAgentConfigs(), UpdateEventType.UPDATE);
     return metadataUpdateEvent;
   }
 
@@ -5628,7 +5629,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
 
     MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
-        null, getMetadataAgentConfigs());
+        null, getMetadataAgentConfigs(), UpdateEventType.UPDATE);
     return metadataUpdateEvent;
   }
 
@@ -5642,22 +5643,12 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
 
     MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
-        null, getMetadataAgentConfigs());
+        null, getMetadataAgentConfigs(), UpdateEventType.UPDATE);
     return metadataUpdateEvent;
   }
 
   public MetadataUpdateEvent getClusterMetadataOnServiceInstall(Cluster cl, String serviceName) throws AmbariException {
-    TreeMap<String, MetadataCluster> metadataClusters = new TreeMap<>();
-
-    MetadataCluster metadataCluster = new MetadataCluster(null,
-        getMetadataServiceLevelParams(cl.getService(serviceName)),
-        new TreeMap<>(),
-        null);
-    metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
-
-    MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
-        null, getMetadataAgentConfigs());
-    return metadataUpdateEvent;
+    return getClusterMetadataOnServiceCredentialStoreUpdate(cl, serviceName);
   }
 
   public MetadataUpdateEvent getClusterMetadataOnServiceCredentialStoreUpdate(Cluster cl, String serviceName) throws AmbariException {
@@ -5670,7 +5661,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
 
     MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
-        null, getMetadataAgentConfigs());
+        null, getMetadataAgentConfigs(), UpdateEventType.UPDATE);
     return metadataUpdateEvent;
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
index 03b45e7..b3abbf8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
@@ -61,7 +61,7 @@ import org.apache.ambari.server.state.ServiceComponentFactory;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.topology.TopologyDeleteFormer;
+import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
 import org.slf4j.Logger;
@@ -171,7 +171,7 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
   private MaintenanceStateHelper maintenanceStateHelper;
 
   @Inject
-  private TopologyDeleteFormer topologyDeleteFormer;
+  private STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler;
 
   // ----- Constructors ----------------------------------------------------
 
@@ -797,13 +797,13 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
 
       if (sc != null) {
         deleteHostComponentsForServiceComponent(sc, request, deleteMetaData);
-        topologyDeleteFormer.processDeleteMetaDataException(deleteMetaData);
+        STOMPComponentsDeleteHandler.processDeleteByMetaDataException(deleteMetaData);
         sc.setDesiredState(State.DISABLED);
         s.deleteServiceComponent(request.getComponentName(), deleteMetaData);
-        topologyDeleteFormer.processDeleteMetaDataException(deleteMetaData);
+        STOMPComponentsDeleteHandler.processDeleteByMetaDataException(deleteMetaData);
       }
     }
-    topologyDeleteFormer.processDeleteMetaData(deleteMetaData);
+    STOMPComponentsDeleteHandler.processDeleteByMetaData(deleteMetaData);
     return null;
   }
 
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 53c4fe3..ac3d5d6 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
@@ -62,6 +62,7 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.events.HostLevelParamsUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 import org.apache.ambari.server.security.authorization.ResourceType;
@@ -582,7 +583,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
       hostLevelParamsHolder.updateData(hostLevelParamsUpdateEvent);
     }
     TopologyUpdateEvent topologyUpdateEvent =
-        new TopologyUpdateEvent(addedTopologies, TopologyUpdateEvent.EventType.UPDATE);
+        new TopologyUpdateEvent(addedTopologies, UpdateEventType.UPDATE);
     topologyHolder.updateData(topologyUpdateEvent);
   }
 
@@ -934,7 +935,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
       }
       topologyUpdates.get(clusterId.toString()).addTopologyHost(topologyHost);
       TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(topologyUpdates,
-          TopologyUpdateEvent.EventType.UPDATE);
+          UpdateEventType.UPDATE);
       topologyHolder.updateData(topologyUpdateEvent);
       //todo: if attempt was made to update a property other than those
       //todo: that are allowed above, should throw exception
@@ -1067,7 +1068,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
     }
     clusters.publishHostsDeletion(allClustersWithHosts, hostNames);
     TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(topologyUpdates,
-        TopologyUpdateEvent.EventType.DELETE);
+        UpdateEventType.DELETE);
     topologyHolder.updateData(topologyUpdateEvent);
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
index 28e97cb..4e080fc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
@@ -75,7 +75,7 @@ import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.topology.TopologyDeleteFormer;
+import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
@@ -186,7 +186,7 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
   private KerberosHelper kerberosHelper;
 
   @Inject
-  private TopologyDeleteFormer topologyDeleteFormer;
+  private STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler;
 
   /**
    * Used to lookup the repository when creating services.
@@ -967,9 +967,9 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
     DeleteHostComponentStatusMetaData deleteMetaData = new DeleteHostComponentStatusMetaData();
     for (Service service : removable) {
       service.getCluster().deleteService(service.getName(), deleteMetaData);
-      topologyDeleteFormer.processDeleteMetaDataException(deleteMetaData);
+      STOMPComponentsDeleteHandler.processDeleteByMetaDataException(deleteMetaData);
     }
-    topologyDeleteFormer.processDeleteMetaData(deleteMetaData);
+    STOMPComponentsDeleteHandler.processDeleteByMetaData(deleteMetaData);
 
     return null;
   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/MetadataUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/MetadataUpdateEvent.java
index e706919..c9be4a6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/MetadataUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/MetadataUpdateEvent.java
@@ -43,6 +43,8 @@ public class MetadataUpdateEvent extends STOMPEvent implements Hashable {
    */
   private String hash;
 
+  private final UpdateEventType eventType;
+
   /**
    * Map of metadatas for each cluster by cluster ids.
    */
@@ -52,14 +54,19 @@ public class MetadataUpdateEvent extends STOMPEvent implements Hashable {
   private MetadataUpdateEvent() {
     super(Type.METADATA);
     metadataClusters = null;
+    eventType = null;
   }
 
-  public MetadataUpdateEvent(SortedMap<String, MetadataCluster> metadataClusters, SortedMap<String, String> ambariLevelParams, SortedMap<String, SortedMap<String, String>> metadataAgentConfigs) {
+  public MetadataUpdateEvent(SortedMap<String, MetadataCluster> metadataClusters,
+                             SortedMap<String, String> ambariLevelParams,
+                             SortedMap<String, SortedMap<String, String>> metadataAgentConfigs,
+                             UpdateEventType eventType) {
     super(Type.METADATA);
     this.metadataClusters = metadataClusters;
     if (ambariLevelParams != null) {
       this.metadataClusters.put(AMBARI_LEVEL_CLUSTER_ID, new MetadataCluster(null, new TreeMap<>(), ambariLevelParams, metadataAgentConfigs));
     }
+    this.eventType = eventType;
   }
 
   public Map<String, MetadataCluster> getMetadataClusters() {
@@ -76,6 +83,10 @@ public class MetadataUpdateEvent extends STOMPEvent implements Hashable {
     this.hash = hash;
   }
 
+  public UpdateEventType getEventType() {
+    return eventType;
+  }
+
   public static MetadataUpdateEvent emptyUpdate() {
     return new MetadataUpdateEvent();
   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyAgentUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyAgentUpdateEvent.java
index 477ea6f..f537b80 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyAgentUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyAgentUpdateEvent.java
@@ -29,7 +29,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
  */
 @JsonInclude(JsonInclude.Include.NON_EMPTY)
 public class TopologyAgentUpdateEvent extends TopologyUpdateEvent {
-  public TopologyAgentUpdateEvent(SortedMap<String, TopologyCluster> clusters, String hash, EventType eventType) {
+  public TopologyAgentUpdateEvent(SortedMap<String, TopologyCluster> clusters, String hash, UpdateEventType eventType) {
     super(Type.AGENT_TOPOLOGY, clusters, hash, eventType);
   }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyUpdateEvent.java
index 9bdb078..6faa80d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/TopologyUpdateEvent.java
@@ -50,13 +50,13 @@ public class TopologyUpdateEvent extends STOMPEvent implements Hashable {
    * Type of update, is used to differ full current topology (CREATE), adding new or update existing topology
    * elements (UPDATE) and removing existing topology elements (DELETE).
    */
-  private final EventType eventType;
+  private final UpdateEventType eventType;
 
-  public TopologyUpdateEvent(SortedMap<String, TopologyCluster> clusters, EventType eventType) {
+  public TopologyUpdateEvent(SortedMap<String, TopologyCluster> clusters, UpdateEventType eventType) {
     this(Type.UI_TOPOLOGY, clusters, null, eventType);
   }
 
-  public TopologyUpdateEvent(Type type, SortedMap<String, TopologyCluster> clusters, String hash, EventType eventType) {
+  public TopologyUpdateEvent(Type type, SortedMap<String, TopologyCluster> clusters, String hash, UpdateEventType eventType) {
     super(type);
     this.clusters = clusters;
     this.hash = hash;
@@ -77,7 +77,7 @@ public class TopologyUpdateEvent extends STOMPEvent implements Hashable {
     return copiedEvent;
   }
 
-  public EventType getEventType() {
+  public UpdateEventType getEventType() {
     return eventType;
   }
 
@@ -93,12 +93,6 @@ public class TopologyUpdateEvent extends STOMPEvent implements Hashable {
     return new TopologyUpdateEvent(null, null);
   }
 
-  public enum EventType {
-    CREATE,
-    DELETE,
-    UPDATE
-  }
-
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/UpdateEventType.java b/ambari-server/src/main/java/org/apache/ambari/server/events/UpdateEventType.java
index 8cf9729..46b4bf6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/UpdateEventType.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/UpdateEventType.java
@@ -21,7 +21,6 @@ package org.apache.ambari.server.events;
 /**
  * Is used to inform the agent about update assignment.
  */
-//TODO refactor other update events to use this class instead own update types.
 public enum UpdateEventType {
   CREATE,
   UPDATE,
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
index c9efa92..4e5fba5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
@@ -2025,10 +2025,17 @@ public class ConfigHelper {
    * @throws AmbariException
    */
   public AgentConfigsUpdateEvent getHostActualConfigs(Long hostId) throws AmbariException {
+    return getHostActualConfigsExcludeCluster(hostId, null);
+  }
+
+  public AgentConfigsUpdateEvent getHostActualConfigsExcludeCluster(Long hostId, Long clusterId) throws AmbariException {
     TreeMap<String, ClusterConfigs> clustersConfigs = new TreeMap<>();
 
     Host host = clusters.getHostById(hostId);
     for (Cluster cl : clusters.getClusters().values()) {
+      if (clusterId != null && cl.getClusterId() == clusterId) {
+        continue;
+      }
       Map<String, Map<String, String>> configurations = new HashMap<>();
       Map<String, Map<String, Map<String, String>>> configurationAttributes = new HashMap<>();
       if (LOG.isInfoEnabled()) {
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 a71e7c8..95fa9c8 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
@@ -144,7 +144,7 @@ import org.apache.ambari.server.state.repository.ClusterVersionSummary;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.scheduler.RequestExecution;
 import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
-import org.apache.ambari.server.topology.TopologyDeleteFormer;
+import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
 import org.apache.ambari.server.topology.TopologyRequest;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
@@ -278,7 +278,7 @@ public class ClusterImpl implements Cluster {
   private TopologyRequestDAO topologyRequestDAO;
 
   @Inject
-  private TopologyDeleteFormer topologyDeleteFormer;
+  private STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler;
 
   /**
    * Data access object used for looking up stacks from the database.
@@ -1280,9 +1280,9 @@ public class ClusterImpl implements Cluster {
       DeleteHostComponentStatusMetaData deleteMetaData = new DeleteHostComponentStatusMetaData();
       for (Service service : services.values()) {
         deleteService(service, deleteMetaData);
-        topologyDeleteFormer.processDeleteMetaDataException(deleteMetaData);
+        STOMPComponentsDeleteHandler.processDeleteByMetaDataException(deleteMetaData);
       }
-      topologyDeleteFormer.processDeleteCluster(Long.toString(getClusterId()));
+      STOMPComponentsDeleteHandler.processDeleteCluster(getClusterId());
       services.clear();
     } finally {
       clusterGlobalLock.writeLock().unlock();
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 cad7e0c..50101a7 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
@@ -47,6 +47,7 @@ import org.apache.ambari.server.events.HostRegisteredEvent;
 import org.apache.ambari.server.events.HostsAddedEvent;
 import org.apache.ambari.server.events.HostsRemovedEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.dao.HostConfigMappingDAO;
@@ -380,7 +381,7 @@ public class ClustersImpl implements Clusters {
     TopologyCluster addedCluster = new TopologyCluster();
     addedClusters.put(Long.toString(cluster.getClusterId()), addedCluster);
     TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(addedClusters,
-        TopologyUpdateEvent.EventType.UPDATE);
+        UpdateEventType.UPDATE);
     m_topologyHolder.get().updateData(topologyUpdateEvent);
     m_metadataHolder.get().updateData(m_ambariManagementController.get().getClusterMetadata(cluster));
   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 5678c78..75bde86 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -47,6 +47,7 @@ import org.apache.ambari.server.events.ServiceComponentInstalledEvent;
 import org.apache.ambari.server.events.ServiceComponentUninstalledEvent;
 import org.apache.ambari.server.events.StaleConfigsUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.events.publishers.STOMPUpdatePublisher;
 import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
@@ -976,7 +977,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
           .setHostNames(new HashSet<>(Collections.singletonList(hostName)))
           .build());
       TopologyUpdateEvent hostComponentVersionUpdate = new TopologyUpdateEvent(topologyUpdates,
-          TopologyUpdateEvent.EventType.UPDATE);
+          UpdateEventType.UPDATE);
       m_topologyHolder.get().updateData(hostComponentVersionUpdate);
     } else {
       LOG.warn("Setting a member on an entity object that may have been "
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyDeleteFormer.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
similarity index 55%
rename from ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyDeleteFormer.java
rename to ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
index c39fb14..c48d4cf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyDeleteFormer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
@@ -19,56 +19,100 @@ package org.apache.ambari.server.topology;
 
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Set;
 import java.util.TreeMap;
+import java.util.stream.Collectors;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.agent.stomp.AgentConfigsHolder;
+import org.apache.ambari.server.agent.stomp.AlertDefinitionsHolder;
+import org.apache.ambari.server.agent.stomp.HostLevelParamsHolder;
+import org.apache.ambari.server.agent.stomp.MetadataHolder;
 import org.apache.ambari.server.agent.stomp.TopologyHolder;
 import org.apache.ambari.server.agent.stomp.dto.TopologyCluster;
 import org.apache.ambari.server.agent.stomp.dto.TopologyComponent;
 import org.apache.ambari.server.controller.internal.DeleteHostComponentStatusMetaData;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
+import org.apache.ambari.server.events.UpdateEventType;
+import org.apache.ambari.server.state.Clusters;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 
 @Singleton
-public class TopologyDeleteFormer {
+public class STOMPComponentsDeleteHandler {
 
   @Inject
   private Provider<TopologyHolder> m_topologyHolder;
 
-  public void processDeleteMetaDataException(DeleteHostComponentStatusMetaData metaData) throws AmbariException {
-    if (metaData.getAmbariException() != null) {
+  @Inject
+  private Provider<AgentConfigsHolder> agentConfigsHolder;
+
+  @Inject
+  private Provider<MetadataHolder> metadataHolder;
+
+  @Inject
+  private Provider<HostLevelParamsHolder> hostLevelParamsHolder;
 
-      TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(
-          createUpdateFromDeleteMetaData(metaData),
-          TopologyUpdateEvent.EventType.DELETE
-      );
-      m_topologyHolder.get().updateData(topologyUpdateEvent);
+  @Inject
+  private Provider<AlertDefinitionsHolder> alertDefinitionsHolder;
 
+  @Inject
+  private Clusters clusters;
+
+  public void processDeleteByMetaDataException(DeleteHostComponentStatusMetaData metaData) throws AmbariException {
+    if (metaData.getAmbariException() != null) {
+      processDeleteByMetaData(metaData);
       throw metaData.getAmbariException();
     }
   }
-  public void processDeleteMetaData(DeleteHostComponentStatusMetaData metaData) throws AmbariException {
+  public void processDeleteByMetaData(DeleteHostComponentStatusMetaData metaData) throws AmbariException {
     TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(
-        createUpdateFromDeleteMetaData(metaData),
-        TopologyUpdateEvent.EventType.DELETE
+        createUpdateFromDeleteByMetaData(metaData),
+        UpdateEventType.DELETE
     );
     m_topologyHolder.get().updateData(topologyUpdateEvent);
+
+    // on components remove we should remove appropriate metadata/configs/hostlevelparams on agents
+    updateNonTopologyAgentInfo(metaData.getRemovedHostComponents().stream().map(hc -> hc.getHostId()).collect(Collectors.toSet()),
+        null);
   }
 
-  public void processDeleteCluster(String clusterId) throws AmbariException {
+  public void processDeleteCluster(Long clusterId) throws AmbariException {
     TreeMap<String, TopologyCluster> topologyUpdates = new TreeMap<>();
-    topologyUpdates.put(clusterId, new TopologyCluster());
+    topologyUpdates.put(Long.toString(clusterId), new TopologyCluster(null, null));
     TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(
         topologyUpdates,
-        TopologyUpdateEvent.EventType.DELETE
+        UpdateEventType.DELETE
     );
     m_topologyHolder.get().updateData(topologyUpdateEvent);
+
+    // on cluster remove we should remove appropriate metadata/configs/hostlevelparams on agents
+    updateNonTopologyAgentInfo(clusters.getCluster(clusterId).getHosts().stream().map(h -> h.getHostId()).collect(Collectors.toSet()),
+        clusterId);
+  }
+
+  private void updateNonTopologyAgentInfo(Set<Long> changedHosts, Long clusterId) throws AmbariException {
+
+    for (Long hostId : changedHosts) {
+      if (clusterId != null) {
+        alertDefinitionsHolder.get().updateData(alertDefinitionsHolder.get().getDeleteCluster(clusterId, hostId));
+        agentConfigsHolder.get().updateData(agentConfigsHolder.get().getCurrentDataExcludeCluster(hostId, clusterId));
+        hostLevelParamsHolder.get().updateData(hostLevelParamsHolder.get().getCurrentDataExcludeCluster(hostId, clusterId));
+      } else {
+        agentConfigsHolder.get().updateData(agentConfigsHolder.get().getCurrentData(hostId));
+        hostLevelParamsHolder.get().updateData(hostLevelParamsHolder.get().getCurrentData(hostId));
+      }
+    }
+    if (clusterId != null) {
+      metadataHolder.get().updateData(metadataHolder.get().getDeleteMetadata(clusterId));
+    } else {
+      metadataHolder.get().updateData(metadataHolder.get().getCurrentData());
+    }
   }
 
-  public TreeMap<String, TopologyCluster> createUpdateFromDeleteMetaData(DeleteHostComponentStatusMetaData metaData) {
+  public TreeMap<String, TopologyCluster> createUpdateFromDeleteByMetaData(DeleteHostComponentStatusMetaData metaData) {
     TreeMap<String, TopologyCluster> topologyUpdates = new TreeMap<>();
 
     for (DeleteHostComponentStatusMetaData.HostComponent hostComponent : metaData.getRemovedHostComponents()) {
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ComponentResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ComponentResourceProviderTest.java
index 29ff7cc..1283e76 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ComponentResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ComponentResourceProviderTest.java
@@ -48,6 +48,7 @@ import java.util.Set;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.ServiceComponentNotFoundException;
+import org.apache.ambari.server.agent.stomp.MetadataHolder;
 import org.apache.ambari.server.agent.stomp.TopologyHolder;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
@@ -79,7 +80,7 @@ import org.apache.ambari.server.state.ServiceComponentFactory;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.topology.TopologyDeleteFormer;
+import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.junit.Assert;
@@ -587,21 +588,30 @@ public class ComponentResourceProviderTest {
     ComponentResourceProvider provider = new ComponentResourceProvider(managementController,
         maintenanceStateHelper);
 
-    Field topologyDeleteFormerField = ComponentResourceProvider.class.getDeclaredField("topologyDeleteFormer");
-    topologyDeleteFormerField.setAccessible(true);
-    TopologyDeleteFormer topologyDeleteFormer = new TopologyDeleteFormer();
-    topologyDeleteFormerField.set(provider, topologyDeleteFormer);
+    Field STOMPComponentsDeleteHandlerField = ComponentResourceProvider.class.getDeclaredField("STOMPComponentsDeleteHandler");
+    STOMPComponentsDeleteHandlerField.setAccessible(true);
+    STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler = new STOMPComponentsDeleteHandler();
+    STOMPComponentsDeleteHandlerField.set(provider, STOMPComponentsDeleteHandler);
 
-    Field topologyHolderProviderField = TopologyDeleteFormer.class.getDeclaredField("m_topologyHolder");
+    Field topologyHolderProviderField = STOMPComponentsDeleteHandler.class.getDeclaredField("m_topologyHolder");
     topologyHolderProviderField.setAccessible(true);
     Provider<TopologyHolder> m_topologyHolder = createMock(Provider.class);
-    topologyHolderProviderField.set(topologyDeleteFormer, m_topologyHolder);
+    topologyHolderProviderField.set(STOMPComponentsDeleteHandler, m_topologyHolder);
 
     TopologyHolder topologyHolder = createNiceMock(TopologyHolder.class);
 
     expect(m_topologyHolder.get()).andReturn(topologyHolder).anyTimes();
 
-    replay(m_topologyHolder, topologyHolder);
+    Field metadataHolderProviderField = STOMPComponentsDeleteHandler.class.getDeclaredField("metadataHolder");
+    metadataHolderProviderField.setAccessible(true);
+    Provider<MetadataHolder> m_metadataHolder = createMock(Provider.class);
+    metadataHolderProviderField.set(STOMPComponentsDeleteHandler, m_metadataHolder);
+
+    MetadataHolder metadataHolder = createNiceMock(MetadataHolder.class);
+
+    expect(m_metadataHolder.get()).andReturn(metadataHolder).anyTimes();
+
+    replay(m_metadataHolder, metadataHolder, m_topologyHolder, topologyHolder);
     return provider;
   }
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
index 9a26b44..6e4e0fa 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
@@ -77,7 +77,7 @@ import org.apache.ambari.server.state.ServiceFactory;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.topology.TopologyDeleteFormer;
+import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.junit.Assert;
@@ -1421,11 +1421,11 @@ public class ServiceResourceProviderTest {
     ServiceResourceProvider serviceResourceProvider =
         new ServiceResourceProvider(managementController, maintenanceStateHelper, repositoryVersionDAO);
 
-    Field topologyDeleteFormerField = ServiceResourceProvider.class.getDeclaredField("topologyDeleteFormer");
-    topologyDeleteFormerField.setAccessible(true);
-    TopologyDeleteFormer topologyDeleteFormer = createNiceMock(TopologyDeleteFormer.class);
-    topologyDeleteFormerField.set(serviceResourceProvider, topologyDeleteFormer);
-    replay(topologyDeleteFormer);
+    Field STOMPComponentsDeleteHandlerField = ServiceResourceProvider.class.getDeclaredField("STOMPComponentsDeleteHandler");
+    STOMPComponentsDeleteHandlerField.setAccessible(true);
+    STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler = createNiceMock(STOMPComponentsDeleteHandler.class);
+    STOMPComponentsDeleteHandlerField.set(serviceResourceProvider, STOMPComponentsDeleteHandler);
+    replay(STOMPComponentsDeleteHandler);
     return serviceResourceProvider;
   }
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java
index 130c254..454f6c1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java
@@ -126,6 +126,7 @@ public class EventsTest {
     m_repositoryVersion = m_helper.getOrCreateRepositoryVersion(stackId, REPO_VERSION);
 
     m_clusters.mapHostToCluster(HOSTNAME, m_clusterName);
+    m_clusters.updateHostMappings(host);
   }
 
   /**
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClustersTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClustersTest.java
index 78cb855..8a7b18b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClustersTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClustersTest.java
@@ -413,16 +413,20 @@ public class ClustersTest {
     clusters.addHost(h1);
     clusters.addHost(h2);
 
+
     Host host1 = clusters.getHost(h1);
+    Host host2 = clusters.getHost(h2);
 
-    setOsFamily(clusters.getHost(h1), "centos", "5.9");
-    setOsFamily(clusters.getHost(h2), "centos", "5.9");
+    setOsFamily(host1, "centos", "5.9");
+    setOsFamily(host2, "centos", "5.9");
 
     clusters.mapAndPublishHostsToCluster(new HashSet<String>() {
       {
         addAll(Arrays.asList(h1, h2));
       }
     }, c1);
+    clusters.updateHostMappings(host1);
+    clusters.updateHostMappings(host2);
 
     // host config override
     host1.addDesiredConfig(cluster.getClusterId(), true, "_test", config2);

-- 
To stop receiving notification emails like this one, please contact
mpapirkovskyy@apache.org.