ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mpapirkovs...@apache.org
Subject [3/5] ambari git commit: AMBARI-21591. Send execution commands to agents user topic via STOMP. (mpapirkovskyy)
Date Thu, 03 Aug 2017 16:07:15 GMT
http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/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 134979e..80c3623 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
@@ -25,6 +25,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLUSTER_NAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CUSTOM_FOLDER;
@@ -47,7 +48,6 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_V
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
@@ -102,6 +102,9 @@ import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
+import org.apache.ambari.server.agent.stomp.AgentConfigsHolder;
+import org.apache.ambari.server.agent.stomp.MetadataHolder;
+import org.apache.ambari.server.agent.stomp.TopologyHolder;
 import org.apache.ambari.server.agent.stomp.dto.MetadataCluster;
 import org.apache.ambari.server.agent.stomp.dto.MetadataServiceInfo;
 import org.apache.ambari.server.agent.stomp.dto.TopologyCluster;
@@ -127,7 +130,6 @@ 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.publishers.AmbariEventPublisher;
-import org.apache.ambari.server.events.publishers.StateUpdateEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.metadata.RoleCommandOrderProvider;
@@ -226,6 +228,7 @@ 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;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
@@ -242,6 +245,7 @@ import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.persist.Transactional;
 
@@ -340,14 +344,20 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   private StackDAO stackDAO;
 
   @Inject
-  private StateUpdateEventPublisher stateUpdateEventPublisher;
-
-  @Inject
   private TopologyDeleteFormer topologyDeleteFormer;
 
   @Inject
   private AmbariCustomCommandExecutionHelper ambariCustomCommandExecutionHelper;
 
+  @Inject
+  private Provider<TopologyHolder> m_topologyHolder;
+
+  @Inject
+  private Provider<MetadataHolder> m_metadataHolder;
+
+  @Inject
+  private Provider<AgentConfigsHolder> m_agentConfigsHolder;
+
   /**
    * The KerberosHelper to help setup for enabling for disabling Kerberos
    */
@@ -708,7 +718,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     setMonitoringServicesRestartRequired(requests);
     // now doing actual work
     persistServiceComponentHosts(requests);
-    stateUpdateEventPublisher.publish(getAddedComponentsTopologyEvent(requests));
+    m_topologyHolder.get().updateData(getAddedComponentsTopologyEvent(requests));
   }
 
   void persistServiceComponentHosts(Set<ServiceComponentHostRequest> requests)
@@ -772,6 +782,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
           .setHostNames(hostNames)
           .setPublicHostNames(publicHostNames)
           .setComponentLevelParams(getTopologyComponentLevelParams(stackId, serviceName, componentName, cluster.getSecurityType()))
+          .setCommandParams(getTopologyCommandParams(stackId, serviceName, componentName))
           .build();
       String clusterId = Long.toString(cluster.getClusterId());
       if (!topologyUpdates.containsKey(clusterId)) {
@@ -1791,6 +1802,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         }
       }
     }
+    m_metadataHolder.get().updateData(getClusterMetadataOnConfigsUpdate(cluster));
+    m_agentConfigsHolder.get().updateData(cluster.getClusterId(), null);
 
     StackId currentVersion = cluster.getCurrentStackVersion();
     StackId desiredVersion = cluster.getDesiredStackVersion();
@@ -2421,9 +2434,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     }
 
     commandParams.put(COMMAND_TIMEOUT, actualTimeout);
-    commandParams.put(SERVICE_PACKAGE_FOLDER,
-      serviceInfo.getServicePackageFolder());
-    commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
 
     String customCacheDirectory = componentInfo.getCustomFolder();
     if (customCacheDirectory != null) {
@@ -2438,7 +2448,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       commandParams.put(ExecutionCommand.KeyNames.REFRESH_TOPOLOGY, "True");
     }
 
-    String repoInfo = customCommandExecutionHelper.getRepoInfo(cluster, hostEntity.getOsType(), osFamily , hostname);
+    String repoInfo = ambariMetaInfo.getRepoInfoString(cluster, hostEntity.getOsType(), osFamily , hostname);
     if (LOG.isDebugEnabled()) {
       LOG.debug("Sending repo information to agent"
         + ", hostname=" + scHost.getHostName()
@@ -2479,10 +2489,12 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       hostParams.put(KeyNames.REPO_VERSION_ID, repoVersion.getId().toString());
     }
 
-    List<ServiceOsSpecific.Package> packages =
-            getPackagesForServiceHost(serviceInfo, hostParams, osFamily);
-    String packageList = gson.toJson(packages);
-    hostParams.put(PACKAGE_LIST, packageList);
+    if (roleCommand.equals(RoleCommand.INSTALL)) {
+      List<ServiceOsSpecific.Package> packages =
+          getPackagesForServiceHost(serviceInfo, hostParams, osFamily);
+      String packageList = gson.toJson(packages);
+      commandParams.put(PACKAGE_LIST, packageList);
+    }
 
     Set<PropertyInfo> stackProperties = ambariMetaInfo.getStackProperties(stackInfo.getName(), stackInfo.getVersion());
 
@@ -5677,7 +5689,56 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
     }
 
-    MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters);
+    MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
+        getMetadataAmbariLevelParams());
+    return metadataUpdateEvent;
+  }
+
+  public MetadataUpdateEvent getClusterMetadata(Cluster cl) throws AmbariException {
+    TreeMap<String, MetadataCluster> metadataClusters = new TreeMap<>();
+    StackId stackId = cl.getDesiredStackVersion();
+
+    SecurityType securityType = cl.getSecurityType();
+
+    TreeMap<String, MetadataServiceInfo> serviceLevelParams = new TreeMap<>();
+    Collection<ServiceInfo> servicesInfo = ambariMetaInfo.getServices(stackId.getStackName(),
+        stackId.getStackVersion()).values();
+    for (ServiceInfo serviceInfo : servicesInfo) {
+      Long statusCommandTimeout = null;
+      if (serviceInfo.getCommandScript() != null) {
+        statusCommandTimeout = new Long(ambariCustomCommandExecutionHelper.getStatusCommandTimeout(serviceInfo));
+      }
+
+      String servicePackageFolder = serviceInfo.getServicePackageFolder();
+
+      serviceLevelParams.put(serviceInfo.getName(),
+          new MetadataServiceInfo(serviceInfo.getVersion(),
+              serviceInfo.isCredentialStoreEnabled(),
+              statusCommandTimeout,
+              servicePackageFolder));
+    }
+
+    MetadataCluster metadataCluster = new MetadataCluster(securityType,
+        serviceLevelParams,
+        getMetadataClusterLevelParams(cl, stackId));
+    metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
+
+    MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
+        null);
+    return metadataUpdateEvent;
+  }
+
+  public MetadataUpdateEvent getClusterMetadataOnConfigsUpdate(Cluster cl) throws AmbariException {
+    TreeMap<String, MetadataCluster> metadataClusters = new TreeMap<>();
+    StackId stackId = cl.getDesiredStackVersion();
+
+    MetadataCluster metadataCluster = new MetadataCluster(null,
+        new TreeMap<>(),
+        getMetadataClusterLevelConfigsParams(cl, stackId));
+    metadataClusters.put(Long.toString(cl.getClusterId()), metadataCluster);
+
+    MetadataUpdateEvent metadataUpdateEvent = new MetadataUpdateEvent(metadataClusters,
+        null);
     return metadataUpdateEvent;
   }
 
@@ -5706,6 +5767,20 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   //TODO will be a need to change to multi-instance usage
   public TreeMap<String, String> getTopologyComponentLevelParams(StackId stackId, String serviceName, String componentName,
                                                              SecurityType clusterSecurityType) throws AmbariException {
+    ComponentInfo componentInfo = ambariMetaInfo.getComponent(
+        stackId.getStackName(), stackId.getStackVersion(),
+        serviceName, componentName);
+
+    TreeMap<String, String> statusCommandParams = new TreeMap<>();
+    statusCommandParams.put(ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS,
+        getClientsToUpdateConfigs(componentInfo));
+    statusCommandParams.put(ExecutionCommand.KeyNames.UNLIMITED_KEY_JCE_REQUIRED,
+         Boolean.toString(getUnlimitedKeyJCERequirement(componentInfo, clusterSecurityType)));
+    return statusCommandParams;
+  }
+
+  //TODO will be a need to change to multi-instance usage
+  public TreeMap<String, String> getTopologyCommandParams(StackId stackId, String serviceName, String componentName) throws AmbariException {
     ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
         stackId.getStackVersion(), serviceName);
     ComponentInfo componentInfo = ambariMetaInfo.getComponent(
@@ -5713,73 +5788,115 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         serviceName, componentName);
 
     String scriptName = null;
+    String scriptCommandTimeout = "";
     CommandScriptDefinition script = componentInfo.getCommandScript();
     if (serviceInfo.getSchemaVersion().equals(AmbariMetaInfo.SCHEMA_VERSION_2)) {
       if (script != null) {
         scriptName = script.getScript();
+        if (script.getTimeout() > 0) {
+          scriptCommandTimeout = String.valueOf(script.getTimeout());
+        }
       } else {
         String message = String.format("Component %s of service %s has not " +
             "command script defined", componentName, serviceName);
         throw new AmbariException(message);
       }
     }
+    String agentDefaultCommandTimeout = configs.getDefaultAgentTaskTimeout(false);
+    String actualTimeout = (!scriptCommandTimeout.equals("") ? scriptCommandTimeout : agentDefaultCommandTimeout);
 
-    TreeMap<String, String> statusCommandParams = new TreeMap<>();
-    statusCommandParams.put(ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS,
-        getClientsToUpdateConfigs(componentInfo));
-    statusCommandParams.put(ExecutionCommand.KeyNames.UNLIMITED_KEY_JCE_REQUIRED,
-         Boolean.toString(getUnlimitedKeyJCERequirement(componentInfo, clusterSecurityType)));
-    statusCommandParams.put(KeyNames.SCRIPT, scriptName);
-    return statusCommandParams;
+    TreeMap<String, String> commandParams = new TreeMap<>();
+    commandParams.put(COMMAND_TIMEOUT, actualTimeout);
+    commandParams.put(SCRIPT, scriptName);
+    commandParams.put(SCRIPT_TYPE, script.getScriptType().toString());
+    return commandParams;
   }
 
   public TreeMap<String, String> getMetadataClusterLevelParams(Cluster cluster, StackId stackId) throws AmbariException {
     TreeMap<String, String> clusterLevelParams = new TreeMap<>();
-    clusterLevelParams.put(JDK_LOCATION, getJdkResourceUrl());
-    clusterLevelParams.put(JAVA_HOME, getJavaHome());
-    clusterLevelParams.put(JAVA_VERSION, String.valueOf(configs.getJavaVersion()));
-    clusterLevelParams.put(JDK_NAME, getJDKName());
-    clusterLevelParams.put(JCE_NAME, getJCEName());
     clusterLevelParams.put(STACK_NAME, stackId.getStackName());
     clusterLevelParams.put(STACK_VERSION, stackId.getStackVersion());
-    clusterLevelParams.put(DB_NAME, getServerDB());
-    clusterLevelParams.put(MYSQL_JDBC_URL, getMysqljdbcUrl());
-    clusterLevelParams.put(ORACLE_JDBC_URL, getOjdbcUrl());
-    clusterLevelParams.put(DB_DRIVER_FILENAME, configs.getMySQLJarName());
-    clusterLevelParams.putAll(getRcaParameters());
-    clusterLevelParams.put(HOST_SYS_PREPPED, configs.areHostsSysPrepped());
-    clusterLevelParams.put(AGENT_STACK_RETRY_ON_UNAVAILABILITY, configs.isAgentStackRetryOnInstallEnabled());
-    clusterLevelParams.put(AGENT_STACK_RETRY_COUNT, configs.getAgentStackRetryOnInstallCount());
+
+    Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
+    if (MapUtils.isNotEmpty(desiredConfigs)) {
+
+      Set<String> userSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.USER, cluster, desiredConfigs);
+      String userList = gson.toJson(userSet);
+      clusterLevelParams.put(USER_LIST, userList);
+
+      //Create a user_group mapping and send it as part of the hostLevelParams
+      Map<String, Set<String>> userGroupsMap = configHelper.createUserGroupsMap(
+          stackId, cluster, desiredConfigs);
+      String userGroups = gson.toJson(userGroupsMap);
+      clusterLevelParams.put(USER_GROUPS, userGroups);
+
+      Set<String> groupSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.GROUP, cluster, desiredConfigs);
+      String groupList = gson.toJson(groupSet);
+      clusterLevelParams.put(GROUP_LIST, groupList);
+    }
+    Set<String> notManagedHdfsPathSet = configHelper.getPropertyValuesWithPropertyType(stackId,
+        PropertyType.NOT_MANAGED_HDFS_PATH, cluster, desiredConfigs);
+    String notManagedHdfsPathList = gson.toJson(notManagedHdfsPathSet);
+    clusterLevelParams.put(NOT_MANAGED_HDFS_PATH_LIST, notManagedHdfsPathList);
+
+    clusterLevelParams.put(CLUSTER_NAME, cluster.getClusterName());
 
     StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
     clusterLevelParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
 
+    return clusterLevelParams;
+  }
+
+  public TreeMap<String, String> getMetadataClusterLevelConfigsParams(Cluster cluster, StackId stackId) throws AmbariException {
+    TreeMap<String, String> clusterLevelParams = new TreeMap<>();
+
     Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
+    if (MapUtils.isNotEmpty(desiredConfigs)) {
+
+      Set<String> userSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.USER, cluster, desiredConfigs);
+      String userList = gson.toJson(userSet);
+      clusterLevelParams.put(USER_LIST, userList);
+
+      //Create a user_group mapping and send it as part of the hostLevelParams
+      Map<String, Set<String>> userGroupsMap = configHelper.createUserGroupsMap(
+          stackId, cluster, desiredConfigs);
+      String userGroups = gson.toJson(userGroupsMap);
+      clusterLevelParams.put(USER_GROUPS, userGroups);
+
+      Set<String> groupSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.GROUP, cluster, desiredConfigs);
+      String groupList = gson.toJson(groupSet);
+      clusterLevelParams.put(GROUP_LIST, groupList);
+    }
     Set<String> notManagedHdfsPathSet = configHelper.getPropertyValuesWithPropertyType(stackId,
         PropertyType.NOT_MANAGED_HDFS_PATH, cluster, desiredConfigs);
     String notManagedHdfsPathList = gson.toJson(notManagedHdfsPathSet);
     clusterLevelParams.put(NOT_MANAGED_HDFS_PATH_LIST, notManagedHdfsPathList);
 
-    Set<String> userSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.USER, cluster, desiredConfigs);
-    String userList = gson.toJson(userSet);
-    clusterLevelParams.put(USER_LIST, userList);
-
-    //Create a user_group mapping and send it as part of the hostLevelParams
-    Map<String, Set<String>> userGroupsMap = configHelper.createUserGroupsMap(
-        stackId, cluster, desiredConfigs);
-    String userGroups = gson.toJson(userGroupsMap);
-    clusterLevelParams.put(USER_GROUPS, userGroups);
+    return clusterLevelParams;
+  }
 
-    Set<String> groupSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.GROUP, cluster, desiredConfigs);
-    String groupList = gson.toJson(groupSet);
-    clusterLevelParams.put(GROUP_LIST, groupList);
+  public TreeMap<String, String> getMetadataAmbariLevelParams() throws AmbariException {
+    TreeMap<String, String> clusterLevelParams = new TreeMap<>();
+    clusterLevelParams.put(JDK_LOCATION, getJdkResourceUrl());
+    clusterLevelParams.put(JAVA_HOME, getJavaHome());
+    clusterLevelParams.put(JAVA_VERSION, String.valueOf(configs.getJavaVersion()));
+    clusterLevelParams.put(JDK_NAME, getJDKName());
+    clusterLevelParams.put(JCE_NAME, getJCEName());
+    clusterLevelParams.put(DB_NAME, getServerDB());
+    clusterLevelParams.put(MYSQL_JDBC_URL, getMysqljdbcUrl());
+    clusterLevelParams.put(ORACLE_JDBC_URL, getOjdbcUrl());
+    clusterLevelParams.put(DB_DRIVER_FILENAME, configs.getMySQLJarName());
+    clusterLevelParams.putAll(getRcaParameters());
+    clusterLevelParams.put(HOST_SYS_PREPPED, configs.areHostsSysPrepped());
+    clusterLevelParams.put(AGENT_STACK_RETRY_ON_UNAVAILABILITY, configs.isAgentStackRetryOnInstallEnabled());
+    clusterLevelParams.put(AGENT_STACK_RETRY_COUNT, configs.getAgentStackRetryOnInstallCount());
 
     return clusterLevelParams;
   }
 
   public TreeMap<String, String> getTopologyHostLevelParams(Cluster cluster, Host host) throws AmbariException {
     TreeMap<String, String> hostLevelParams = new TreeMap<>();
-    String repoInfo = customCommandExecutionHelper.getRepoInfo(cluster, host);
+    String repoInfo = ambariMetaInfo.getRepoInfoString(cluster, host);
 
     hostLevelParams.put(REPO_INFO, repoInfo);
     return hostLevelParams;

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
index 32f1fd8..2dc0732 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
@@ -789,7 +789,8 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
       AlertExecutionCommand command = new AlertExecutionCommand(
           cluster.getClusterName(), hostName, definition);
 
-      actionQueue.enqueue(hostName, command);
+      //TODO implement alert execution commands logic
+      //actionQueue.enqueue(hostName, command);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
index e42bd45..cc5b6c0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
@@ -391,7 +391,6 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv
           packages.addAll(hostOs.getPackages());
         }
         String packageList = gson.toJson(packages);
-        hostLevelParams.put(PACKAGE_LIST, packageList);
 
         Set<String> userSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.USER, cluster, desiredClusterConfigs);
         String userList = gson.toJson(userSet);
@@ -430,6 +429,7 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv
           }
         }
 
+        commandParams.put(PACKAGE_LIST, packageList);
         commandParams.put("xml_configs_list", xmlConfigs);
         commandParams.put("env_configs_list", envConfigs);
         commandParams.put("properties_configs_list", propertiesConfigs);

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 1d278d0..ae2fa25 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -43,11 +43,13 @@ import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
+import org.apache.ambari.server.agent.stomp.MetadataHolder;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.ActionExecutionContext;
 import org.apache.ambari.server.controller.AmbariActionExecutionHelper;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -193,6 +195,12 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
   @Inject
   private static HostComponentStateDAO hostComponentStateDAO;
 
+  @Inject
+  private static Provider<MetadataHolder> m_metadataHolder;
+
+  @Inject
+  private static Provider<AmbariManagementControllerImpl> m_ambariManagementController;
+
   /**
    * We have to include such a hack here, because if we
    * make finalizeUpgradeAction field static and request injection
@@ -815,6 +823,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       StackId stackId = rve.getStackId();
       Cluster cluster = getManagementController().getClusters().getCluster(clName);
       cluster.setDesiredStackVersion(stackId);
+      m_metadataHolder.get().updateData(m_ambariManagementController.get().getClusterMetadata(cluster));
 
       String forceCurrent = (String) propertyMap.get(CLUSTER_STACK_VERSION_FORCE);
       boolean force = false;

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
index 477add7..4a65272 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/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 74508c1..c62b4ce 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
@@ -37,10 +37,13 @@ import org.apache.ambari.server.HostNotFoundException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.agent.RecoveryConfigHelper;
+import org.apache.ambari.server.agent.stomp.HostLevelParamsHolder;
+import org.apache.ambari.server.agent.stomp.TopologyHolder;
+import org.apache.ambari.server.agent.stomp.dto.HostLevelParamsCluster;
 import org.apache.ambari.server.agent.stomp.dto.TopologyCluster;
 import org.apache.ambari.server.agent.stomp.dto.TopologyHost;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
 import org.apache.ambari.server.controller.ConfigurationRequest;
 import org.apache.ambari.server.controller.HostRequest;
 import org.apache.ambari.server.controller.HostResponse;
@@ -57,8 +60,8 @@ import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.spi.SystemException;
 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.publishers.StateUpdateEventPublisher;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 import org.apache.ambari.server.security.authorization.ResourceType;
@@ -175,13 +178,16 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
   private static TopologyManager topologyManager;
 
   @Inject
-  private StateUpdateEventPublisher stateUpdateEventPublisher;
+  private TopologyHolder topologyHolder;
+
+  @Inject
+  private HostLevelParamsHolder hostLevelParamsHolder;
 
   @Inject
   private RecoveryConfigHelper recoveryConfigHelper;
 
   @Inject
-  private AmbariManagementControllerImpl ambariManagementController;
+  private AmbariMetaInfo ambariMetaInfo;
 
   // ----- Constructors ----------------------------------------------------
 
@@ -525,6 +531,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
     Set<String> allClusterSet = new HashSet<>();
 
     TreeMap<String, TopologyCluster> addedTopologies = new TreeMap<>();
+    List<HostLevelParamsUpdateEvent> hostLevelParamsUpdateEvents = new ArrayList<>();
     for (HostRequest hostRequest : hostRequests) {
       if (hostRequest.getHostname() != null &&
           !hostRequest.getHostname().isEmpty() &&
@@ -547,10 +554,14 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
         addedTopologies.get(clusterId).addTopologyHost(new TopologyHost(addedHost.getHostId(),
             addedHost.getHostName(),
             addedHost.getRackInfo(),
-            addedHost.getIPv4(),
+            addedHost.getIPv4()));
+        HostLevelParamsUpdateEvent hostLevelParamsUpdateEvent = new HostLevelParamsUpdateEvent(clusterId, new HostLevelParamsCluster(
+            ambariMetaInfo.getRepoInfo(cl, addedHost),
             recoveryConfigHelper.getRecoveryConfig(clusters.getCluster(hostRequest.getClusterName()).getClusterName(),
-                addedHost.getHostName()),
-            ambariManagementController.getTopologyHostLevelParams(cl, addedHost)));
+                addedHost.getHostName())
+        ));
+        hostLevelParamsUpdateEvent.setHostName(addedHost.getHostName());
+        hostLevelParamsUpdateEvents.add(hostLevelParamsUpdateEvent);
       }
     }
     clusters.updateHostWithClusterAndAttributes(hostClustersMap, hostAttributes);
@@ -560,7 +571,10 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
     }
     TopologyUpdateEvent topologyUpdateEvent =
         new TopologyUpdateEvent(addedTopologies, TopologyUpdateEvent.EventType.UPDATE);
-    stateUpdateEventPublisher.publish(topologyUpdateEvent);
+    topologyHolder.updateData(topologyUpdateEvent);
+    for (HostLevelParamsUpdateEvent hostLevelParamsUpdateEvent : hostLevelParamsUpdateEvents) {
+      hostLevelParamsHolder.updateData(hostLevelParamsUpdateEvent);
+    }
   }
 
   private void createHostResource(Clusters clusters, Set<String> duplicates,
@@ -855,7 +869,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
       topologyUpdates.get(clusterId.toString()).addTopologyHost(topologyHost);
       TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(topologyUpdates,
           TopologyUpdateEvent.EventType.UPDATE);
-      stateUpdateEventPublisher.publish(topologyUpdateEvent);
+      topologyHolder.updateData(topologyUpdateEvent);
       //todo: if attempt was made to update a property other than those
       //todo: that are allowed above, should throw exception
     }
@@ -991,7 +1005,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
     }
     TopologyUpdateEvent topologyUpdateEvent = new TopologyUpdateEvent(topologyUpdates,
         TopologyUpdateEvent.EventType.DELETE);
-    stateUpdateEventPublisher.publish(topologyUpdateEvent);
+    topologyHolder.updateData(topologyUpdateEvent);
   }
 
   private void validateHostInDeleteFriendlyState(HostRequest hostRequest, Clusters clusters, boolean forceDelete) throws AmbariException {

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AgentConfigsUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AgentConfigsUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AgentConfigsUpdateEvent.java
index 23f3559..640be2d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AgentConfigsUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AgentConfigsUpdateEvent.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,11 +26,26 @@ import org.apache.ambari.server.agent.stomp.dto.Hashable;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+/**
+ * Contains info about configs update for one host. This update will be sent to single host only.
+ * Host can be identified by AgentConfigsUpdateEvent#hostName.
+ */
 @JsonInclude(JsonInclude.Include.NON_NULL)
-public class AgentConfigsUpdateEvent extends AmbariUpdateEvent implements Hashable {
+public class AgentConfigsUpdateEvent extends AmbariHostUpdateEvent implements Hashable {
 
+  /**
+   * Actual version hash.
+   */
   private String hash;
 
+  /**
+   * Host identifier.
+   */
+  private String hostName;
+
+  /**
+   * Configs grouped by cluster id as keys.
+   */
   @JsonProperty("clusters")
   private TreeMap<String, ClusterConfigs> clustersConfigs = new TreeMap<>();
 
@@ -59,4 +74,31 @@ public class AgentConfigsUpdateEvent extends AmbariUpdateEvent implements Hashab
   public static AgentConfigsUpdateEvent emptyUpdate() {
     return new AgentConfigsUpdateEvent(null);
   }
+
+  public void setHostName(String hostName) {
+    this.hostName = hostName;
+  }
+
+  @Override
+  public String getHostName() {
+    return hostName;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    AgentConfigsUpdateEvent that = (AgentConfigsUpdateEvent) o;
+
+    if (hostName != null ? !hostName.equals(that.hostName) : that.hostName != null) return false;
+    return clustersConfigs != null ? clustersConfigs.equals(that.clustersConfigs) : that.clustersConfigs == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = hostName != null ? hostName.hashCode() : 0;
+    result = 31 * result + (clustersConfigs != null ? clustersConfigs.hashCode() : 0);
+    return result;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionUpdateHolder.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionUpdateHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionUpdateHolder.java
new file mode 100644
index 0000000..e820401
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionUpdateHolder.java
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.events;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.ambari.server.events.publishers.StateUpdateEventPublisher;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class AlertDefinitionUpdateHolder {
+  private Map<Long, AlertDefinitionsUpdateEvent> cachedEvents = new ConcurrentHashMap<>();
+
+  @Inject
+  private StateUpdateEventPublisher stateUpdateEventPublisher;
+
+  public void updateIfNeeded(AlertDefinitionsUpdateEvent event) {
+    if (cachedEvents.containsKey(event.getDefinitionId())) {
+      AlertDefinitionsUpdateEvent cachedUpdate = cachedEvents.get(event.getDefinitionId());
+      AlertDefinitionsUpdateEvent updateEvent = new AlertDefinitionsUpdateEvent(event.getDefinitionId());
+      boolean updated = false;
+
+      if (event.getClusterId() != cachedUpdate.getClusterId()) {
+        cachedUpdate.setClusterId(event.getClusterId());
+        updateEvent.setClusterId(event.getClusterId());
+        updated = true;
+      }
+      if (!StringUtils.equals(event.getComponentName(), cachedUpdate.getComponentName())) {
+        cachedUpdate.setComponentName(event.getComponentName());
+        updateEvent.setComponentName(event.getComponentName());
+        updated = true;
+      }
+      if (!StringUtils.equals(event.getDescription(), cachedUpdate.getDescription())) {
+        cachedUpdate.setDescription(event.getDescription());
+        updateEvent.setDescription(event.getDescription());
+        updated = true;
+      }
+      if (!StringUtils.equals(event.getHelpURL(), cachedUpdate.getHelpURL())) {
+        cachedUpdate.setHelpURL(event.getHelpURL());
+        updateEvent.setHelpURL(event.getHelpURL());
+        updated = true;
+      }
+      if (event.getInterval() != cachedUpdate.getInterval()) {
+        cachedUpdate.setInterval(event.getInterval());
+        updateEvent.setInterval(event.getInterval());
+        updated = true;
+      }
+      if (!StringUtils.equals(event.getLabel(), cachedUpdate.getLabel())) {
+        cachedUpdate.setLabel(event.getLabel());
+        updateEvent.setLabel(event.getLabel());
+        updated = true;
+      }
+      if (!StringUtils.equals(event.getName(), cachedUpdate.getName())) {
+        cachedUpdate.setName(event.getName());
+        updateEvent.setName(event.getName());
+        updated = true;
+      }
+      if (event.getRepeatTolerance() != cachedUpdate.getRepeatTolerance()) {
+        cachedUpdate.setRepeatTolerance(event.getRepeatTolerance());
+        updateEvent.setRepeatTolerance(event.getRepeatTolerance());
+        updated = true;
+      }
+      if (!event.getScope().equals(cachedUpdate.getScope())) {
+        cachedUpdate.setScope(event.getScope());
+        updateEvent.setScope(event.getScope());
+        updated = true;
+      }
+      if (!StringUtils.equals(event.getServiceName(), cachedUpdate.getServiceName())) {
+        cachedUpdate.setServiceName(event.getServiceName());
+        updateEvent.setServiceName(event.getServiceName());
+        updated = true;
+      }
+      if (!event.getSource().equals(cachedUpdate.getSource())) {
+        cachedUpdate.setSource(event.getSource());
+        updateEvent.setSource(event.getSource());
+        updated = true;
+      }
+      if (!event.getEnabled().equals(cachedUpdate.getEnabled())) {
+        cachedUpdate.setEnabled(event.getEnabled());
+        updateEvent.setEnabled(event.getEnabled());
+        updated = true;
+      }
+      if (!event.getRepeatToleranceEnabled().equals(cachedUpdate.getRepeatToleranceEnabled())) {
+        cachedUpdate.setRepeatToleranceEnabled(event.getRepeatToleranceEnabled());
+        updateEvent.setRepeatToleranceEnabled(event.getRepeatToleranceEnabled());
+        updated = true;
+      }
+      if (updated) {
+        stateUpdateEventPublisher.publish(updateEvent);
+      }
+    } else {
+      cachedEvents.put(event.getDefinitionId(), event);
+      stateUpdateEventPublisher.publish(event);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
new file mode 100644
index 0000000..cbe6e37
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
@@ -0,0 +1,284 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.events;
+
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.Source;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Contains info about alert definitions update. This update will be sent to all subscribed recipients.
+ */
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public class AlertDefinitionsUpdateEvent extends AmbariUpdateEvent {
+
+  @JsonProperty("clusterId")
+  private Long clusterId;
+
+  @JsonProperty("componentName")
+  private String componentName;
+
+  @JsonProperty("description")
+  private String description;
+
+  @JsonProperty("enabled")
+  private Boolean enabled;
+
+  @JsonProperty("helpUrl")
+  private String helpURL;
+
+  @JsonProperty("id")
+  private Long definitionId;
+
+  @JsonProperty("ignoreHost")
+  private Boolean ignoreHost;
+
+  @JsonProperty("interval")
+  private Integer interval;
+
+  @JsonProperty("label")
+  private String label;
+
+  @JsonProperty("name")
+  private String name;
+
+  @JsonProperty("repeatTolerance")
+  private Integer repeatTolerance;
+
+  @JsonProperty("repeatToleranceEnabled")
+  private Boolean repeatToleranceEnabled;
+
+  @JsonProperty("scope")
+  private Scope scope;
+
+  @JsonProperty("serviceName")
+  private String serviceName;
+
+  @JsonProperty("source")
+  private Source source;
+
+  public AlertDefinitionsUpdateEvent(Long clusterId, String componentName, String description, Boolean enabled,
+                               String helpURL, Long definitionId, Boolean ignoreHost, Integer interval, String label,
+                               String name, Integer repeatTolerance, Boolean repeatToleranceEnabled, Scope scope,
+                               String serviceName, Source source) {
+    super(Type.ALERT_DEFINITIONS);
+    this.clusterId = clusterId;
+    this.componentName = componentName;
+    this.description = description;
+    this.enabled = enabled;
+    this.helpURL = helpURL;
+    this.definitionId = definitionId;
+    this.ignoreHost = ignoreHost;
+    this.interval = interval;
+    this.label = label;
+    this.name = name;
+    this.repeatTolerance = repeatTolerance;
+    this.repeatToleranceEnabled = repeatToleranceEnabled;
+    this.scope = scope;
+    this.serviceName = serviceName;
+    this.source = source;
+  }
+
+  public AlertDefinitionsUpdateEvent(AlertDefinition alertDefinition, Integer repeatTolerance, Boolean repeatToleranceEnabled) {
+    this(alertDefinition.getClusterId(), alertDefinition.getComponentName(), alertDefinition.getDescription(),
+        alertDefinition.isEnabled(), alertDefinition.getHelpURL(), alertDefinition.getDefinitionId(),
+        alertDefinition.isHostIgnored(), alertDefinition.getInterval(), alertDefinition.getLabel(),
+        alertDefinition.getName(), repeatTolerance, repeatToleranceEnabled, alertDefinition.getScope(),
+        alertDefinition.getServiceName(), alertDefinition.getSource());
+  }
+
+  public AlertDefinitionsUpdateEvent(long definitionId) {
+    super(Type.ALERT_DEFINITIONS);
+    this.definitionId = definitionId;
+  }
+
+  public AlertDefinitionsUpdateEvent(AlertDefinitionEntity alertDefinitionEntity) {
+    super(Type.ALERT_DEFINITIONS);
+  }
+
+  public Long getClusterId() {
+    return clusterId;
+  }
+
+  public void setClusterId(Long clusterId) {
+    this.clusterId = clusterId;
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public void setComponentName(String componentName) {
+    this.componentName = componentName;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  public Boolean getEnabled() {
+    return enabled;
+  }
+
+  public void setEnabled(Boolean enabled) {
+    this.enabled = enabled;
+  }
+
+  public String getHelpURL() {
+    return helpURL;
+  }
+
+  public void setHelpURL(String helpURL) {
+    this.helpURL = helpURL;
+  }
+
+  public Long getDefinitionId() {
+    return definitionId;
+  }
+
+  public void setDefinitionId(Long definitionId) {
+    this.definitionId = definitionId;
+  }
+
+  public Boolean getIgnoreHost() {
+    return ignoreHost;
+  }
+
+  public void setIgnoreHost(Boolean ignoreHost) {
+    this.ignoreHost = ignoreHost;
+  }
+
+  public Integer getInterval() {
+    return interval;
+  }
+
+  public void setInterval(Integer interval) {
+    this.interval = interval;
+  }
+
+  public String getLabel() {
+    return label;
+  }
+
+  public void setLabel(String label) {
+    this.label = label;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public Integer getRepeatTolerance() {
+    return repeatTolerance;
+  }
+
+  public void setRepeatTolerance(Integer repeatTolerance) {
+    this.repeatTolerance = repeatTolerance;
+  }
+
+  public Boolean getRepeatToleranceEnabled() {
+    return repeatToleranceEnabled;
+  }
+
+  public void setRepeatToleranceEnabled(Boolean repeatToleranceEnabled) {
+    this.repeatToleranceEnabled = repeatToleranceEnabled;
+  }
+
+  public Scope getScope() {
+    return scope;
+  }
+
+  public void setScope(Scope scope) {
+    this.scope = scope;
+  }
+
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  public void setServiceName(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+  public Source getSource() {
+    return source;
+  }
+
+  public void setSource(Source source) {
+    this.source = source;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    AlertDefinitionsUpdateEvent that = (AlertDefinitionsUpdateEvent) o;
+
+    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
+    if (componentName != null ? !componentName.equals(that.componentName) : that.componentName != null) return false;
+    if (description != null ? !description.equals(that.description) : that.description != null) return false;
+    if (enabled != null ? !enabled.equals(that.enabled) : that.enabled != null) return false;
+    if (helpURL != null ? !helpURL.equals(that.helpURL) : that.helpURL != null) return false;
+    if (definitionId != null ? !definitionId.equals(that.definitionId) : that.definitionId != null) return false;
+    if (ignoreHost != null ? !ignoreHost.equals(that.ignoreHost) : that.ignoreHost != null) return false;
+    if (interval != null ? !interval.equals(that.interval) : that.interval != null) return false;
+    if (label != null ? !label.equals(that.label) : that.label != null) return false;
+    if (name != null ? !name.equals(that.name) : that.name != null) return false;
+    if (repeatTolerance != null ? !repeatTolerance.equals(that.repeatTolerance) : that.repeatTolerance != null)
+      return false;
+    if (repeatToleranceEnabled != null ? !repeatToleranceEnabled.equals(that.repeatToleranceEnabled) : that.repeatToleranceEnabled != null)
+      return false;
+    if (scope != that.scope) return false;
+    if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false;
+    return source != null ? source.equals(that.source) : that.source == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = clusterId != null ? clusterId.hashCode() : 0;
+    result = 31 * result + (componentName != null ? componentName.hashCode() : 0);
+    result = 31 * result + (description != null ? description.hashCode() : 0);
+    result = 31 * result + (enabled != null ? enabled.hashCode() : 0);
+    result = 31 * result + (helpURL != null ? helpURL.hashCode() : 0);
+    result = 31 * result + (definitionId != null ? definitionId.hashCode() : 0);
+    result = 31 * result + (ignoreHost != null ? ignoreHost.hashCode() : 0);
+    result = 31 * result + (interval != null ? interval.hashCode() : 0);
+    result = 31 * result + (label != null ? label.hashCode() : 0);
+    result = 31 * result + (name != null ? name.hashCode() : 0);
+    result = 31 * result + (repeatTolerance != null ? repeatTolerance.hashCode() : 0);
+    result = 31 * result + (repeatToleranceEnabled != null ? repeatToleranceEnabled.hashCode() : 0);
+    result = 31 * result + (scope != null ? scope.hashCode() : 0);
+    result = 31 * result + (serviceName != null ? serviceName.hashCode() : 0);
+    result = 31 * result + (source != null ? source.hashCode() : 0);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AlertUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertUpdateEvent.java
index 52e2180..c2c202a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertUpdateEvent.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,19 +23,40 @@ import java.util.Map;
 
 import org.apache.ambari.server.api.query.render.AlertSummaryGroupedRenderer;
 
+/**
+ * Contains info about alerts update. This update will be sent to all subscribed recipients.
+ */
 public class AlertUpdateEvent extends AmbariUpdateEvent {
-  private Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary> summaries = new HashMap<>();
+  /**
+   * Alert summaries grouped by cluster id.
+   */
+  private Map<Long, Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary>> summaries = new HashMap<>();
 
-  public AlertUpdateEvent(Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary> summaries) {
+  public AlertUpdateEvent(Map<Long, Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary>> summaries) {
     super(Type.ALERT);
     this.summaries = summaries;
   }
 
-  public Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary> getSummaries() {
+  public Map<Long, Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary>> getSummaries() {
     return summaries;
   }
 
-  public void setSummaries(Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary> summaries) {
+  public void setSummaries(Map<Long, Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary>> summaries) {
     this.summaries = summaries;
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    AlertUpdateEvent that = (AlertUpdateEvent) o;
+
+    return summaries != null ? summaries.equals(that.summaries) : that.summaries == null;
+  }
+
+  @Override
+  public int hashCode() {
+    return summaries != null ? summaries.hashCode() : 0;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index 868ce3f..60f29bb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -140,7 +140,22 @@ public abstract class AmbariEvent {
     /**
      * Local user has been created.
      */
-    USER_CREATED;
+    USER_CREATED,
+
+    /**
+     * Host status has been changed.
+     */
+    HOST_STATUS_CHANGE,
+
+    /**
+     * Host state has been changed.
+     */
+    HOST_STATE_CHANGE,
+
+    /**
+     * Received new heartbeat with host info.
+     */
+    HOST_HEARTBEAT_UPDATED;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariHostUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariHostUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariHostUpdateEvent.java
new file mode 100644
index 0000000..495e4c8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariHostUpdateEvent.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.events;
+
+import java.beans.Transient;
+
+/**
+ * Update data from server side, will be sent as STOMP message only to specified recipient.
+ */
+public abstract class AmbariHostUpdateEvent extends AmbariUpdateEvent {
+
+  /**
+   * Host name message will sent to.
+   * @return host name.
+   */
+  @Transient
+  public abstract String getHostName();
+
+  public AmbariHostUpdateEvent(Type type) {
+    super(type);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
index b075179..90aa704 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,14 @@ package org.apache.ambari.server.events;
 
 import java.beans.Transient;
 
+/**
+ * Update data from server side, will be sent as STOMP message to recipients from all hosts.
+ */
 public abstract class AmbariUpdateEvent {
+
+  /**
+   * Update type.
+   */
   protected final Type type;
 
   public AmbariUpdateEvent(Type type) {
@@ -44,15 +51,27 @@ public abstract class AmbariUpdateEvent {
   public enum Type {
     ALERT("/events/alerts", "events.alerts"),
     METADATA("/events/metadata", "events.metadata"),
-    TOPOLOGY("/events/topologies", "events.topology_update"),
-    AGENT_CONFIGS("/events/configs", "events.agent.configs"),
+    HOSTLEVELPARAMS("/host_level_params", "events.hostlevelparams"),
+    UI_TOPOLOGY("/events/ui_topologies", "events.topology_update"),
+    AGENT_TOPOLOGY("/events/topologies", "events.topology_update"),
+    AGENT_CONFIGS("/configs", "events.agent.configs"),
     CONFIGS("/events/configs", "events.configs"),
     HOSTCOMPONENT("/events/hostcomponents", "events.hostcomponents"),
     NAMEDHOSTCOMPONENT("/events/tasks/", "events.hostrolecommands.named"),
     REQUEST("/events/requests", "events.requests"),
-    COMMAND("/user/commands", "events.commands");
+    SERVICE("/events/services", "events.services"),
+    HOST("/events/hosts", "events.hosts"),
+    ALERT_DEFINITIONS("/events/alert_definitions", "events.alert_definitions"),
+    COMMAND("/commands", "events.commands");
 
+    /**
+     * Destination is used for delivery message to recipients.
+     */
     private String destination;
+
+    /**
+     * Is used to collect info about event appearing frequency.
+     */
     private String metricName;
 
     Type(String destination, String metricName) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/CommandEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/CommandEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/CommandEvent.java
deleted file mode 100644
index 80245aa..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/CommandEvent.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ambari.server.events;
-
-public class CommandEvent extends AmbariUpdateEvent {
-  public CommandEvent() {
-    super(Type.COMMAND);
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/ConfigsUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ConfigsUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ConfigsUpdateEvent.java
index 26f6622..eefca6b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/ConfigsUpdateEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ConfigsUpdateEvent.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,13 +19,21 @@
 package org.apache.ambari.server.events;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
 import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
+import org.apache.ambari.server.state.Cluster;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * Contains info about configs update. This update will be sent to all subscribed recipients.
+ */
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
 public class ConfigsUpdateEvent extends AmbariUpdateEvent {
 
   private Long serviceConfigId;
@@ -64,6 +72,17 @@ public class ConfigsUpdateEvent extends AmbariUpdateEvent {
     this.changedConfigTypes = changedConfigTypes;
   }
 
+  public ConfigsUpdateEvent(Cluster cluster, Collection<ClusterConfigEntity> configs) {
+    super(Type.CONFIGS);
+    this.clusterId = cluster.getClusterId();
+    for (ClusterConfigEntity clusterConfigEntity : configs) {
+      this.configs.add(new ClusterConfig(clusterConfigEntity.getClusterId(),
+          clusterConfigEntity.getType(),
+          clusterConfigEntity.getTag(),
+          clusterConfigEntity.getVersion()));
+    }
+  }
+
   public Long getServiceConfigId() {
     return serviceConfigId;
   }
@@ -204,5 +223,66 @@ public class ConfigsUpdateEvent extends AmbariUpdateEvent {
     public void setType(String type) {
       this.type = type;
     }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      ClusterConfig that = (ClusterConfig) o;
+
+      if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
+      if (type != null ? !type.equals(that.type) : that.type != null) return false;
+      if (tag != null ? !tag.equals(that.tag) : that.tag != null) return false;
+      return version != null ? version.equals(that.version) : that.version == null;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = clusterId != null ? clusterId.hashCode() : 0;
+      result = 31 * result + (type != null ? type.hashCode() : 0);
+      result = 31 * result + (tag != null ? tag.hashCode() : 0);
+      result = 31 * result + (version != null ? version.hashCode() : 0);
+      return result;
+    }
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ConfigsUpdateEvent that = (ConfigsUpdateEvent) o;
+
+    if (serviceConfigId != null ? !serviceConfigId.equals(that.serviceConfigId) : that.serviceConfigId != null)
+      return false;
+    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
+    if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false;
+    if (groupId != null ? !groupId.equals(that.groupId) : that.groupId != null) return false;
+    if (version != null ? !version.equals(that.version) : that.version != null) return false;
+    if (user != null ? !user.equals(that.user) : that.user != null) return false;
+    if (note != null ? !note.equals(that.note) : that.note != null) return false;
+    if (hostNames != null ? !hostNames.equals(that.hostNames) : that.hostNames != null) return false;
+    if (createTime != null ? !createTime.equals(that.createTime) : that.createTime != null) return false;
+    if (groupName != null ? !groupName.equals(that.groupName) : that.groupName != null) return false;
+    if (configs != null ? !configs.equals(that.configs) : that.configs != null) return false;
+    return changedConfigTypes != null ? changedConfigTypes.equals(that.changedConfigTypes) : that.changedConfigTypes == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = serviceConfigId != null ? serviceConfigId.hashCode() : 0;
+    result = 31 * result + (clusterId != null ? clusterId.hashCode() : 0);
+    result = 31 * result + (serviceName != null ? serviceName.hashCode() : 0);
+    result = 31 * result + (groupId != null ? groupId.hashCode() : 0);
+    result = 31 * result + (version != null ? version.hashCode() : 0);
+    result = 31 * result + (user != null ? user.hashCode() : 0);
+    result = 31 * result + (note != null ? note.hashCode() : 0);
+    result = 31 * result + (hostNames != null ? hostNames.hashCode() : 0);
+    result = 31 * result + (createTime != null ? createTime.hashCode() : 0);
+    result = 31 * result + (groupName != null ? groupName.hashCode() : 0);
+    result = 31 * result + (configs != null ? configs.hashCode() : 0);
+    result = 31 * result + (changedConfigTypes != null ? changedConfigTypes.hashCode() : 0);
+    return result;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/ExecutionCommandEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ExecutionCommandEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ExecutionCommandEvent.java
new file mode 100644
index 0000000..8f8b5a0
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ExecutionCommandEvent.java
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.events;
+
+import java.util.TreeMap;
+
+import org.apache.ambari.server.agent.stomp.dto.ExecutionCommandsCluster;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Event to send execution commands to agent.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ExecutionCommandEvent extends AmbariHostUpdateEvent {
+
+  /**
+   * Host name with agent execution commands will be send to.
+   */
+  private String hostName;
+
+  /**
+   * Execution commands grouped by cluster id.
+   */
+  @JsonProperty("clusters")
+  private TreeMap<String, ExecutionCommandsCluster> clusters;
+
+  public ExecutionCommandEvent(TreeMap<String, ExecutionCommandsCluster> clusters) {
+    super(Type.COMMAND);
+    this.clusters = clusters;
+  }
+
+  public TreeMap<String, ExecutionCommandsCluster> getClusters() {
+    return clusters;
+  }
+
+  public void setClusters(TreeMap<String, ExecutionCommandsCluster> clusters) {
+    this.clusters = clusters;
+  }
+
+  public void setHostName(String hostName) {
+    this.hostName = hostName;
+  }
+
+  @Override
+  public String getHostName() {
+    return hostName;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ExecutionCommandEvent that = (ExecutionCommandEvent) o;
+
+    if (hostName != null ? !hostName.equals(that.hostName) : that.hostName != null) return false;
+    return clusters != null ? clusters.equals(that.clusters) : that.clusters == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = hostName != null ? hostName.hashCode() : 0;
+    result = 31 * result + (clusters != null ? clusters.hashCode() : 0);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdate.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdate.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdate.java
new file mode 100644
index 0000000..e480146
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdate.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.events;
+
+import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
+import org.apache.ambari.server.state.State;
+
+public class HostComponentUpdate {
+
+  private Long id;
+  private Long clusterId;
+  private String serviceName;
+  private String hostName;
+  private String componentName;
+  private State currentState;
+  private State previousState;
+
+  public HostComponentUpdate(HostComponentStateEntity stateEntity, State previousState) {
+    this.id = stateEntity.getId();
+    this.clusterId = stateEntity.getClusterId();
+    this.serviceName = stateEntity.getServiceName();
+    this.hostName = stateEntity.getHostEntity().getHostName();
+    this.currentState = stateEntity.getCurrentState();
+    this.componentName = stateEntity.getComponentName();
+    this.previousState = previousState;
+  }
+
+  public Long getId() {
+    return id;
+  }
+
+  public void setId(Long id) {
+    this.id = id;
+  }
+
+  public Long getClusterId() {
+    return clusterId;
+  }
+
+  public void setClusterId(Long clusterId) {
+    this.clusterId = clusterId;
+  }
+
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  public void setServiceName(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+  public String getHostName() {
+    return hostName;
+  }
+
+  public void setHostName(String hostName) {
+    this.hostName = hostName;
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public void setComponentName(String componentName) {
+    this.componentName = componentName;
+  }
+
+  public State getCurrentState() {
+    return currentState;
+  }
+
+  public void setCurrentState(State currentState) {
+    this.currentState = currentState;
+  }
+
+  public State getPreviousState() {
+    return previousState;
+  }
+
+  public void setPreviousState(State previousState) {
+    this.previousState = previousState;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    HostComponentUpdate that = (HostComponentUpdate) o;
+
+    if (id != null ? !id.equals(that.id) : that.id != null) return false;
+    if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
+    if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) return false;
+    if (hostName != null ? !hostName.equals(that.hostName) : that.hostName != null) return false;
+    if (componentName != null ? !componentName.equals(that.componentName) : that.componentName != null) return false;
+    if (currentState != that.currentState) return false;
+    return previousState == that.previousState;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = id != null ? id.hashCode() : 0;
+    result = 31 * result + (clusterId != null ? clusterId.hashCode() : 0);
+    result = 31 * result + (serviceName != null ? serviceName.hashCode() : 0);
+    result = 31 * result + (hostName != null ? hostName.hashCode() : 0);
+    result = 31 * result + (componentName != null ? componentName.hashCode() : 0);
+    result = 31 * result + (currentState != null ? currentState.hashCode() : 0);
+    result = 31 * result + (previousState != null ? previousState.hashCode() : 0);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdateEvent.java
deleted file mode 100644
index 08ed9e0..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentUpdateEvent.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.events;
-
-import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
-import org.apache.ambari.server.state.State;
-
-public class HostComponentUpdateEvent extends AmbariUpdateEvent {
-
-  private Long id;
-  private Long clusterId;
-  private String serviceName;
-  private String hostName;
-  private String componentName;
-  private State currentState;
-
-  public HostComponentUpdateEvent(HostComponentStateEntity stateEntity) {
-    super(Type.HOSTCOMPONENT);
-    this.id = stateEntity.getId();
-    this.clusterId = stateEntity.getClusterId();
-    this.serviceName = stateEntity.getServiceName();
-    this.hostName = stateEntity.getHostEntity().getHostName();
-    this.currentState = stateEntity.getCurrentState();
-    this.componentName = stateEntity.getComponentName();
-  }
-
-  public Long getId() {
-    return id;
-  }
-
-  public void setId(Long id) {
-    this.id = id;
-  }
-
-  public Long getClusterId() {
-    return clusterId;
-  }
-
-  public void setClusterId(Long clusterId) {
-    this.clusterId = clusterId;
-  }
-
-  public String getServiceName() {
-    return serviceName;
-  }
-
-  public void setServiceName(String serviceName) {
-    this.serviceName = serviceName;
-  }
-
-  public String getHostName() {
-    return hostName;
-  }
-
-  public void setHostName(String hostName) {
-    this.hostName = hostName;
-  }
-
-  public String getComponentName() {
-    return componentName;
-  }
-
-  public void setComponentName(String componentName) {
-    this.componentName = componentName;
-  }
-
-  public State getCurrentState() {
-    return currentState;
-  }
-
-  public void setCurrentState(State currentState) {
-    this.currentState = currentState;
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentsUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentsUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentsUpdateEvent.java
new file mode 100644
index 0000000..fe725c7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostComponentsUpdateEvent.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.events;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Contains list of updated hostcomponents. This update will be sent to all subscribed recipients.
+ */
+public class HostComponentsUpdateEvent extends AmbariUpdateEvent {
+
+  @JsonProperty("hostComponents")
+  private List<HostComponentUpdate> hostComponentUpdates = new ArrayList<>();
+
+  public HostComponentsUpdateEvent(List<HostComponentUpdate> hostComponentUpdates) {
+    super(Type.HOSTCOMPONENT);
+    this.hostComponentUpdates = hostComponentUpdates;
+  }
+
+  public List<HostComponentUpdate> getHostComponentUpdates() {
+    return hostComponentUpdates;
+  }
+
+  public void setHostComponentUpdates(List<HostComponentUpdate> hostComponentUpdates) {
+    this.hostComponentUpdates = hostComponentUpdates;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    HostComponentsUpdateEvent that = (HostComponentsUpdateEvent) o;
+
+    return hostComponentUpdates != null ? hostComponentUpdates.equals(that.hostComponentUpdates) : that.hostComponentUpdates == null;
+  }
+
+  @Override
+  public int hashCode() {
+    return hostComponentUpdates != null ? hostComponentUpdates.hashCode() : 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/HostLevelParamsUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostLevelParamsUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostLevelParamsUpdateEvent.java
new file mode 100644
index 0000000..66ab38e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostLevelParamsUpdateEvent.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.events;
+
+import java.util.TreeMap;
+
+import org.apache.ambari.server.agent.stomp.dto.Hashable;
+import org.apache.ambari.server.agent.stomp.dto.HostLevelParamsCluster;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Contains info about host level parameters for single host. This update will be sent to single host only.
+ * Host can be identified by AgentConfigsUpdateEvent#hostName.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class HostLevelParamsUpdateEvent extends AmbariHostUpdateEvent implements Hashable {
+
+  /**
+   * Actual version hash.
+   */
+  private String hash;
+
+  /**
+   * Host identifier.
+   */
+  private String hostName;
+
+  /**
+   * Host level parameters by clusters.
+   */
+  @JsonProperty("clusters")
+  private TreeMap<String, HostLevelParamsCluster> hostLevelParamsClusters = new TreeMap<>();
+
+  public HostLevelParamsUpdateEvent(TreeMap<String, HostLevelParamsCluster> hostLevelParamsClusters) {
+    super(Type.HOSTLEVELPARAMS);
+    this.hostLevelParamsClusters = hostLevelParamsClusters;
+  }
+
+  public HostLevelParamsUpdateEvent(String clusterId, HostLevelParamsCluster hostLevelParamsCluster) {
+    this(new TreeMap<String, HostLevelParamsCluster>(){{put(clusterId, hostLevelParamsCluster);}});
+  }
+
+  @Override
+  public String getHash() {
+    return hash;
+  }
+
+  @Override
+  public void setHash(String hash) {
+    this.hash = hash;
+  }
+
+  public TreeMap<String, HostLevelParamsCluster> getHostLevelParamsClusters() {
+    return hostLevelParamsClusters;
+  }
+
+  public void setHostLevelParamsClusters(TreeMap<String, HostLevelParamsCluster> hostLevelParamsClusters) {
+    this.hostLevelParamsClusters = hostLevelParamsClusters;
+  }
+
+  public static HostLevelParamsUpdateEvent emptyUpdate() {
+    return new HostLevelParamsUpdateEvent(null);
+  }
+
+  public void setHostName(String hostName) {
+    this.hostName = hostName;
+  }
+
+  @Override
+  public String getHostName() {
+    return hostName;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    HostLevelParamsUpdateEvent that = (HostLevelParamsUpdateEvent) o;
+
+    if (hostName != null ? !hostName.equals(that.hostName) : that.hostName != null) return false;
+    return hostLevelParamsClusters != null ? hostLevelParamsClusters.equals(that.hostLevelParamsClusters) : that.hostLevelParamsClusters == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = hostName != null ? hostName.hashCode() : 0;
+    result = 31 * result + (hostLevelParamsClusters != null ? hostLevelParamsClusters.hashCode() : 0);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c1cb51/ambari-server/src/main/java/org/apache/ambari/server/events/HostStateUpdateEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostStateUpdateEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostStateUpdateEvent.java
new file mode 100644
index 0000000..d09e4e2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostStateUpdateEvent.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.events;
+
+import org.apache.ambari.server.state.HostState;
+
+public class HostStateUpdateEvent extends AmbariEvent {
+
+  private String hostName;
+  private HostState hostState;
+
+  public HostStateUpdateEvent(String hostName, HostState hostState) {
+    super(AmbariEventType.HOST_STATE_CHANGE);
+    this.hostName = hostName;
+    this.hostState = hostState;
+  }
+
+  public String getHostName() {
+    return hostName;
+  }
+
+  public void setHostName(String hostName) {
+    this.hostName = hostName;
+  }
+
+  public HostState getHostState() {
+    return hostState;
+  }
+
+  public void setHostState(HostState hostState) {
+    this.hostState = hostState;
+  }
+}


Mime
View raw message