Ver código fonte

AMBARI-16830 - Desired Configuration Cache Expiration Caused 10,000's of Database Hits In Large Deployments (jonathanhurley)

Jonathan Hurley 9 anos atrás
pai
commit
1ab16f764e
21 arquivos alterados com 370 adições e 242 exclusões
  1. 6 1
      ambari-server/src/main/java/org/apache/ambari/annotations/TransactionalLock.java
  2. 6 4
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
  3. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
  4. 4 2
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
  5. 22 18
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
  6. 19 13
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
  7. 0 7
      ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
  8. 120 28
      ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
  9. 10 10
      ambari-server/src/main/java/org/apache/ambari/server/state/Host.java
  10. 13 1
      ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
  11. 15 17
      ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
  12. 12 20
      ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
  13. 3 2
      ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
  14. 0 1
      ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java
  15. 15 15
      ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
  16. 1 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java
  17. 46 29
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java
  18. 14 9
      ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerActionTest.java
  19. 7 7
      ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java
  20. 2 2
      ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterDeadlockTest.java
  21. 54 54
      ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java

+ 6 - 1
ambari-server/src/main/java/org/apache/ambari/annotations/TransactionalLock.java

@@ -65,7 +65,12 @@ public @interface TransactionalLock {
      * Joinpoint lock around work performed on caching the host role command
      * Joinpoint lock around work performed on caching the host role command
      * status in a given stage and request.
      * status in a given stage and request.
      */
      */
-    HRC_STATUS_CACHE(Configuration.SERVER_HRC_STATUS_SUMMARY_CACHE_ENABLED);
+    HRC_STATUS_CACHE(Configuration.SERVER_HRC_STATUS_SUMMARY_CACHE_ENABLED),
+
+    /**
+     * Joinpoint lock around work performed on caching config staleness.
+     */
+    STALE_CONFIG_CACHE(Configuration.SERVER_STALE_CONFIG_CACHE_ENABLED_KEY);
 
 
     /**
     /**
      * Logger.
      * Logger.

+ 6 - 4
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java

@@ -45,6 +45,7 @@ import org.apache.ambari.server.state.CommandScriptDefinition;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.Service;
@@ -110,7 +111,7 @@ public class HeartbeatMonitor implements Runnable {
   }
   }
 
 
   public AgentRequests getAgentRequests() {
   public AgentRequests getAgentRequests() {
-    return this.agentRequests;
+    return agentRequests;
   }
   }
 
 
   @Override
   @Override
@@ -211,6 +212,7 @@ public class HeartbeatMonitor implements Runnable {
     List<StatusCommand> cmds = new ArrayList<StatusCommand>();
     List<StatusCommand> cmds = new ArrayList<StatusCommand>();
 
 
     for (Cluster cl : clusters.getClustersForHost(hostname)) {
     for (Cluster cl : clusters.getClustersForHost(hostname)) {
+      Map<String, DesiredConfig> desiredConfigs = cl.getDesiredConfigs();
       for (ServiceComponentHost sch : cl.getServiceComponentHosts(hostname)) {
       for (ServiceComponentHost sch : cl.getServiceComponentHosts(hostname)) {
         switch (sch.getState()) {
         switch (sch.getState()) {
           case INIT:
           case INIT:
@@ -220,7 +222,7 @@ public class HeartbeatMonitor implements Runnable {
             //don't send commands until component is installed at least
             //don't send commands until component is installed at least
             continue;
             continue;
           default:
           default:
-            StatusCommand statusCmd = createStatusCommand(hostname, cl, sch);
+            StatusCommand statusCmd = createStatusCommand(hostname, cl, sch, desiredConfigs);
             cmds.add(statusCmd);
             cmds.add(statusCmd);
         }
         }
 
 
@@ -234,7 +236,7 @@ public class HeartbeatMonitor implements Runnable {
    * @throws AmbariException
    * @throws AmbariException
    */
    */
   private StatusCommand createStatusCommand(String hostname, Cluster cluster,
   private StatusCommand createStatusCommand(String hostname, Cluster cluster,
-                               ServiceComponentHost sch) throws AmbariException {
+      ServiceComponentHost sch, Map<String, DesiredConfig> desiredConfigs) throws AmbariException {
     String serviceName = sch.getServiceName();
     String serviceName = sch.getServiceName();
     String componentName = sch.getServiceComponentName();
     String componentName = sch.getServiceComponentName();
     StackId stackId = cluster.getDesiredStackVersion();
     StackId stackId = cluster.getDesiredStackVersion();
@@ -306,7 +308,7 @@ public class HeartbeatMonitor implements Runnable {
 
 
     // If Agent wants the command and the States differ
     // If Agent wants the command and the States differ
     statusCmd.setDesiredState(sch.getDesiredState());
     statusCmd.setDesiredState(sch.getDesiredState());
-    statusCmd.setHasStaleConfigs(configHelper.isStaleConfigs(sch));
+    statusCmd.setHasStaleConfigs(configHelper.isStaleConfigs(sch, desiredConfigs));
     if (getAgentRequests().shouldSendExecutionDetails(hostname, componentName)) {
     if (getAgentRequests().shouldSendExecutionDetails(hostname, componentName)) {
       LOG.info(componentName + " is at " + sch.getState() + " adding more payload per agent ask");
       LOG.info(componentName + " is at " + sch.getState() + " adding more payload per agent ask");
       statusCmd.setPayloadLevel(StatusCommand.StatusCommandPayload.EXECUTION_COMMAND);
       statusCmd.setPayloadLevel(StatusCommand.StatusCommandPayload.EXECUTION_COMMAND);

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -450,7 +450,7 @@ public class Configuration {
 
 
   private static final long SERVER_EC_CACHE_SIZE_DEFAULT = 10000L;
   private static final long SERVER_EC_CACHE_SIZE_DEFAULT = 10000L;
   private static final String SERVER_STALE_CONFIG_CACHE_ENABLED_DEFAULT = "true";
   private static final String SERVER_STALE_CONFIG_CACHE_ENABLED_DEFAULT = "true";
-  private static final String SERVER_STALE_CONFIG_CACHE_EXPIRATION_DEFAULT = "60";
+  private static final String SERVER_STALE_CONFIG_CACHE_EXPIRATION_DEFAULT = "300";
   private static final String SERVER_JDBC_USER_NAME_DEFAULT = "ambari";
   private static final String SERVER_JDBC_USER_NAME_DEFAULT = "ambari";
   private static final String SERVER_JDBC_USER_PASSWD_DEFAULT = "bigdata";
   private static final String SERVER_JDBC_USER_PASSWD_DEFAULT = "bigdata";
   private static final String SERVER_JDBC_RCA_USER_NAME_DEFAULT = "mapred";
   private static final String SERVER_JDBC_RCA_USER_NAME_DEFAULT = "mapred";

+ 4 - 2
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java

@@ -136,6 +136,7 @@ import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.ConfigFactory;
 import org.apache.ambari.server.state.ConfigFactory;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.HostState;
@@ -1164,6 +1165,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       checkState = true;
       checkState = true;
     }
     }
 
 
+    Map<String, DesiredConfig> desiredConfigs = cluster.getDesiredConfigs();
     Map<String, Host> hosts = clusters.getHostsForCluster(cluster.getClusterName());
     Map<String, Host> hosts = clusters.getHostsForCluster(cluster.getClusterName());
 
 
     for (Service s : services) {
     for (Service s : services) {
@@ -1218,7 +1220,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
               }
               }
             }
             }
 
 
-            ServiceComponentHostResponse r = sch.convertToResponse();
+            ServiceComponentHostResponse r = sch.convertToResponse(desiredConfigs);
             if (null == r || (filterBasedConfigStaleness && r.isStaleConfig() != staleConfig)) {
             if (null == r || (filterBasedConfigStaleness && r.isStaleConfig() != staleConfig)) {
               continue;
               continue;
             }
             }
@@ -1269,7 +1271,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
               }
               }
             }
             }
 
 
-            ServiceComponentHostResponse r = sch.convertToResponse();
+            ServiceComponentHostResponse r = sch.convertToResponse(desiredConfigs);
             if (null == r || (filterBasedConfigStaleness && r.isStaleConfig() != staleConfig)) {
             if (null == r || (filterBasedConfigStaleness && r.isStaleConfig() != staleConfig)) {
               continue;
               continue;
             }
             }

+ 22 - 18
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java

@@ -18,7 +18,21 @@
 
 
 package org.apache.ambari.server.controller.internal;
 package org.apache.ambari.server.controller.internal;
 
 
-import com.google.inject.Inject;
+import static org.apache.ambari.server.controller.metrics.MetricsServiceProvider.MetricsService.GANGLIA;
+import static org.apache.ambari.server.controller.metrics.MetricsServiceProvider.MetricsService.TIMELINE_METRICS;
+
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
@@ -54,23 +68,11 @@ import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.State;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 
 
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static org.apache.ambari.server.controller.metrics.MetricsServiceProvider.MetricsService.GANGLIA;
-import static org.apache.ambari.server.controller.metrics.MetricsServiceProvider.MetricsService.TIMELINE_METRICS;
+import com.google.inject.Inject;
 
 
 /**
 /**
  * An abstract provider module implementation.
  * An abstract provider module implementation.
@@ -286,6 +288,7 @@ public abstract class AbstractProviderModule implements ProviderModule,
    * Get type of Metrics system installed.
    * Get type of Metrics system installed.
    * @return @MetricsService, null if none found.
    * @return @MetricsService, null if none found.
    */
    */
+  @Override
   public MetricsService getMetricsServiceType() {
   public MetricsService getMetricsServiceType() {
     try {
     try {
       checkInit();
       checkInit();
@@ -540,7 +543,7 @@ public abstract class AbstractProviderModule implements ProviderModule,
         // Since concurrent thread access is expected we err on the side of
         // Since concurrent thread access is expected we err on the side of
         // performance with a ConcurrentHashMap and maybe get default/existing
         // performance with a ConcurrentHashMap and maybe get default/existing
         // ports for a few calls.
         // ports for a few calls.
-        if (!currVersion.equals(oldVersion) ||
+        if (!StringUtils.equals(currVersion, oldVersion) ||
             !(clusterJmxPorts.containsKey(hostName) && clusterJmxPorts.get(hostName).containsKey(componentName))) {
             !(clusterJmxPorts.containsKey(hostName) && clusterJmxPorts.get(hostName).containsKey(componentName))) {
 
 
           serviceConfigVersions.put(configType, currVersion);
           serviceConfigVersions.put(configType, currVersion);
@@ -1199,10 +1202,11 @@ public abstract class AbstractProviderModule implements ProviderModule,
   }
   }
 
 
   private String getJMXProtocolString(String value) {
   private String getJMXProtocolString(String value) {
-    if (value.equals(PROPERTY_HDFS_HTTP_POLICY_VALUE_HTTPS_ONLY))
+    if (value.equals(PROPERTY_HDFS_HTTP_POLICY_VALUE_HTTPS_ONLY)) {
       return "https";
       return "https";
-    else
+    } else {
       return "http";
       return "http";
+    }
   }
   }
 
 
   @Override
   @Override

+ 19 - 13
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java

@@ -100,7 +100,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
   public static final String HOST_CPU_COUNT_PROPERTY_ID =
   public static final String HOST_CPU_COUNT_PROPERTY_ID =
       PropertyHelper.getPropertyId("Hosts", "cpu_count");
       PropertyHelper.getPropertyId("Hosts", "cpu_count");
   public static final String HOST_PHYSICAL_CPU_COUNT_PROPERTY_ID =
   public static final String HOST_PHYSICAL_CPU_COUNT_PROPERTY_ID =
-      PropertyHelper.getPropertyId("Hosts", "ph_cpu_count");  
+      PropertyHelper.getPropertyId("Hosts", "ph_cpu_count");
   public static final String HOST_OS_ARCH_PROPERTY_ID =
   public static final String HOST_OS_ARCH_PROPERTY_ID =
       PropertyHelper.getPropertyId("Hosts", "os_arch");
       PropertyHelper.getPropertyId("Hosts", "os_arch");
   public static final String HOST_OS_TYPE_PROPERTY_ID =
   public static final String HOST_OS_TYPE_PROPERTY_ID =
@@ -115,8 +115,8 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
       PropertyHelper.getPropertyId("Hosts", "last_registration_time");
       PropertyHelper.getPropertyId("Hosts", "last_registration_time");
   public static final String HOST_DISK_INFO_PROPERTY_ID =
   public static final String HOST_DISK_INFO_PROPERTY_ID =
       PropertyHelper.getPropertyId("Hosts", "disk_info");
       PropertyHelper.getPropertyId("Hosts", "disk_info");
-  
-  
+
+
   public static final String HOST_HOST_STATUS_PROPERTY_ID =
   public static final String HOST_HOST_STATUS_PROPERTY_ID =
       PropertyHelper.getPropertyId("Hosts", "host_status");
       PropertyHelper.getPropertyId("Hosts", "host_status");
   public static final String HOST_MAINTENANCE_STATE_PROPERTY_ID =
   public static final String HOST_MAINTENANCE_STATE_PROPERTY_ID =
@@ -259,7 +259,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
       setResourceProperty(resource, HOST_CPU_COUNT_PROPERTY_ID,
       setResourceProperty(resource, HOST_CPU_COUNT_PROPERTY_ID,
           (long) response.getCpuCount(), requestedIds);
           (long) response.getCpuCount(), requestedIds);
       setResourceProperty(resource, HOST_PHYSICAL_CPU_COUNT_PROPERTY_ID,
       setResourceProperty(resource, HOST_PHYSICAL_CPU_COUNT_PROPERTY_ID,
-          (long) response.getPhCpuCount(), requestedIds);      
+          (long) response.getPhCpuCount(), requestedIds);
       setResourceProperty(resource, HOST_OS_ARCH_PROPERTY_ID,
       setResourceProperty(resource, HOST_OS_ARCH_PROPERTY_ID,
           response.getOsArch(), requestedIds);
           response.getOsArch(), requestedIds);
       setResourceProperty(resource, HOST_OS_TYPE_PROPERTY_ID,
       setResourceProperty(resource, HOST_OS_TYPE_PROPERTY_ID,
@@ -295,13 +295,13 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
           response.getHostState(), requestedIds);
           response.getHostState(), requestedIds);
       setResourceProperty(resource, HOST_DESIRED_CONFIGS_PROPERTY_ID,
       setResourceProperty(resource, HOST_DESIRED_CONFIGS_PROPERTY_ID,
           response.getDesiredHostConfigs(), requestedIds);
           response.getDesiredHostConfigs(), requestedIds);
-      
+
       // only when a cluster request
       // only when a cluster request
       if (null != response.getMaintenanceState()) {
       if (null != response.getMaintenanceState()) {
         setResourceProperty(resource, HOST_MAINTENANCE_STATE_PROPERTY_ID,
         setResourceProperty(resource, HOST_MAINTENANCE_STATE_PROPERTY_ID,
             response.getMaintenanceState(), requestedIds);
             response.getMaintenanceState(), requestedIds);
       }
       }
-      
+
       resources.add(resource);
       resources.add(resource);
     }
     }
     return resources;
     return resources;
@@ -420,14 +420,14 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
     hostRequest.setRackInfo(rackInfo);
     hostRequest.setRackInfo(rackInfo);
     hostRequest.setBlueprintName((String) properties.get(BLUEPRINT_PROPERTY_ID));
     hostRequest.setBlueprintName((String) properties.get(BLUEPRINT_PROPERTY_ID));
     hostRequest.setHostGroupName((String) properties.get(HOSTGROUP_PROPERTY_ID));
     hostRequest.setHostGroupName((String) properties.get(HOSTGROUP_PROPERTY_ID));
-    
+
     Object o = properties.get(HOST_MAINTENANCE_STATE_PROPERTY_ID);
     Object o = properties.get(HOST_MAINTENANCE_STATE_PROPERTY_ID);
     if (null != o) {
     if (null != o) {
       hostRequest.setMaintenanceState(o.toString());
       hostRequest.setMaintenanceState(o.toString());
     }
     }
-    
+
     List<ConfigurationRequest> cr = getConfigurationRequests("Hosts", properties);
     List<ConfigurationRequest> cr = getConfigurationRequests("Hosts", properties);
-    
+
     hostRequest.setDesiredConfigs(cr);
     hostRequest.setDesiredConfigs(cr);
 
 
     return hostRequest;
     return hostRequest;
@@ -643,13 +643,19 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
       }
       }
     }
     }
 
 
+    // retrieve the cluster desired configs once instead of per host
+    Map<String, DesiredConfig> desiredConfigs = null;
+    if (null != cluster) {
+      cluster.getDesiredConfigs();
+    }
+
     for (Host h : hosts) {
     for (Host h : hosts) {
       if (clusterName != null) {
       if (clusterName != null) {
         if (clusters.getClustersForHost(h.getHostName()).contains(cluster)) {
         if (clusters.getClustersForHost(h.getHostName()).contains(cluster)) {
           HostResponse r = h.convertToResponse();
           HostResponse r = h.convertToResponse();
-          
+
           r.setClusterName(clusterName);
           r.setClusterName(clusterName);
-          r.setDesiredHostConfigs(h.getDesiredHostConfigs(cluster));
+          r.setDesiredHostConfigs(h.getDesiredHostConfigs(cluster, desiredConfigs));
           r.setMaintenanceState(h.getMaintenanceState(cluster.getClusterId()));
           r.setMaintenanceState(h.getMaintenanceState(cluster.getClusterId()));
 
 
           response.add(r);
           response.add(r);
@@ -664,7 +670,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
         if (clustersForHost != null && clustersForHost.size() != 0) {
         if (clustersForHost != null && clustersForHost.size() != 0) {
           Cluster clusterForHost = clustersForHost.iterator().next();
           Cluster clusterForHost = clustersForHost.iterator().next();
           r.setClusterName(clusterForHost.getClusterName());
           r.setClusterName(clusterForHost.getClusterName());
-          r.setDesiredHostConfigs(h.getDesiredHostConfigs(clusterForHost));
+          r.setDesiredHostConfigs(h.getDesiredHostConfigs(clusterForHost, desiredConfigs));
           r.setMaintenanceState(h.getMaintenanceState(clusterForHost.getClusterId()));
           r.setMaintenanceState(h.getMaintenanceState(clusterForHost.getClusterId()));
         }
         }
 
 
@@ -736,7 +742,7 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
         }
         }
         host.setPublicHostName(request.getPublicHostName());
         host.setPublicHostName(request.getPublicHostName());
       }
       }
-      
+
       if (null != clusterName && null != request.getMaintenanceState()) {
       if (null != clusterName && null != request.getMaintenanceState()) {
         if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, resourceId, RoleAuthorization.HOST_TOGGLE_MAINTENANCE)) {
         if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, resourceId, RoleAuthorization.HOST_TOGGLE_MAINTENANCE)) {
           throw new AuthorizationException("The authenticated user is not authorized to update host maintenance state");
           throw new AuthorizationException("The authenticated user is not authorized to update host maintenance state");

+ 0 - 7
ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java

@@ -456,13 +456,6 @@ public interface Cluster {
    */
    */
   Map<String, DesiredConfig> getDesiredConfigs();
   Map<String, DesiredConfig> getDesiredConfigs();
 
 
-  /**
-   * Gets the active desired configurations for the cluster.
-   * @param bypassCache don't use cached values
-   * @return a map of type-to-configuration information.
-   */
-  Map<String, DesiredConfig> getDesiredConfigs(boolean bypassCache);
-
   /**
   /**
    * Gets all versions of the desired configurations for the cluster.
    * Gets all versions of the desired configurations for the cluster.
    * @return a map of type-to-configuration information.
    * @return a map of type-to-configuration information.

+ 120 - 28
ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java

@@ -30,6 +30,30 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import org.apache.ambari.annotations.TransactionalLock;
+import org.apache.ambari.annotations.TransactionalLock.LockArea;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ConfigurationRequest;
+import org.apache.ambari.server.orm.TransactionalLocks;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
+import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
+import org.apache.ambari.server.state.PropertyInfo.PropertyType;
+import org.apache.ambari.server.state.configgroup.ConfigGroup;
+import org.apache.ambari.server.upgrade.UpgradeCatalog170;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
 
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -85,6 +109,15 @@ public class ConfigHelper {
   public static final String HTTP_ONLY = "HTTP_ONLY";
   public static final String HTTP_ONLY = "HTTP_ONLY";
   public static final String HTTPS_ONLY = "HTTPS_ONLY";
   public static final String HTTPS_ONLY = "HTTPS_ONLY";
 
 
+  /**
+   * Used to ensure that methods which rely on the completion of
+   * {@link Transactional} can detect when they are able to run.
+   *
+   * @see TransactionalLock
+   */
+  @Inject
+  private final TransactionalLocks transactionLocks = null;
+
   @Inject
   @Inject
   public ConfigHelper(Clusters c, AmbariMetaInfo metaInfo, Configuration configuration, ClusterDAO clusterDAO) {
   public ConfigHelper(Clusters c, AmbariMetaInfo metaInfo, Configuration configuration, ClusterDAO clusterDAO) {
     clusters = c;
     clusters = c;
@@ -107,38 +140,61 @@ public class ConfigHelper {
   public Map<String, Map<String, String>> getEffectiveDesiredTags(
   public Map<String, Map<String, String>> getEffectiveDesiredTags(
       Cluster cluster, String hostName) throws AmbariException {
       Cluster cluster, String hostName) throws AmbariException {
 
 
-    return getEffectiveDesiredTags(cluster, hostName, false);
+    return getEffectiveDesiredTags(cluster, hostName, null);
   }
   }
 
 
   /**
   /**
    * Gets the desired tags for a cluster and host
    * Gets the desired tags for a cluster and host
    *
    *
-   * @param cluster  the cluster
-   * @param hostName the host name
-   * @param bypassCache don't use cached values
+   * @param cluster
+   *          the cluster
+   * @param hostName
+   *          the host name
    * @return a map of tag type to tag names with overrides
    * @return a map of tag type to tag names with overrides
    * @throws AmbariException
    * @throws AmbariException
    */
    */
-  public Map<String, Map<String, String>> getEffectiveDesiredTags(
-      Cluster cluster, String hostName, boolean bypassCache) throws AmbariException {
+  public Map<String, Map<String, String>> getEffectiveDesiredTags(Cluster cluster, String hostName,
+      Map<String, DesiredConfig> desiredConfigs) throws AmbariException {
 
 
     Host host = (hostName == null) ? null : clusters.getHost(hostName);
     Host host = (hostName == null) ? null : clusters.getHost(hostName);
-    Map<String, HostConfig> desiredHostConfigs = (host == null) ? null : host.getDesiredHostConfigs(cluster, bypassCache);
-    return getEffectiveDesiredTags(cluster, desiredHostConfigs, bypassCache);
+    Map<String, HostConfig> desiredHostConfigs = (host == null) ? null
+        : host.getDesiredHostConfigs(cluster, desiredConfigs);
+
+    return getEffectiveDesiredTags(cluster, desiredConfigs, desiredHostConfigs);
   }
   }
 
 
   /**
   /**
    * Gets the desired tags for a cluster and overrides for a host
    * Gets the desired tags for a cluster and overrides for a host
    *
    *
-   * @param cluster             the cluster
-   * @param hostConfigOverrides the host overrides applied using config groups
-   * @param bypassCache         don't use cached values
+   * @param cluster
+   *          the cluster
+   * @param hostConfigOverrides
+   *          the host overrides applied using config groups
+   * @param desiredConfigs
+   *          the desired configurations for the cluster. Obtaining these can be
+   *          expensive, ans since this method could be called 10,000's of times
+   *          when generating cluster/host responses. Therefore, the caller
+   *          should build these once and pass them in. If {@code null}, then
+   *          this method will retrieve them at runtime, incurring a performance
+   *          penality.
    * @return a map of tag type to tag names with overrides
    * @return a map of tag type to tag names with overrides
    */
    */
   private Map<String, Map<String, String>> getEffectiveDesiredTags(
   private Map<String, Map<String, String>> getEffectiveDesiredTags(
-      Cluster cluster, Map<String, HostConfig> hostConfigOverrides, boolean bypassCache) {
+      Cluster cluster, Map<String, DesiredConfig> clusterDesired,
+      Map<String, HostConfig> hostConfigOverrides) {
 
 
-    Map<String, DesiredConfig> clusterDesired = (cluster == null) ? new HashMap<String, DesiredConfig>() : cluster.getDesiredConfigs(bypassCache);
+    if (null == cluster) {
+      clusterDesired = new HashMap<>();
+    }
+
+    // per method contract, lookup if not supplied
+    if (null == clusterDesired) {
+      clusterDesired = cluster.getDesiredConfigs();
+    }
+
+    if (null == clusterDesired) {
+      clusterDesired = new HashMap<>();
+    }
 
 
     Map<String, Map<String, String>> resolved = new TreeMap<String, Map<String, String>>();
     Map<String, Map<String, String>> resolved = new TreeMap<String, Map<String, String>>();
 
 
@@ -364,18 +420,18 @@ public class ConfigHelper {
   }
   }
 
 
   /**
   /**
-   * The purpose of this method is to determine if a {@link ServiceComponentHost}'s
-   * known actual configs are different than what is set on the cluster (the desired).
-   * The following logic is applied:
+   * The purpose of this method is to determine if a
+   * {@link ServiceComponentHost}'s known actual configs are different than what
+   * is set on the cluster (the desired). The following logic is applied:
    * <ul>
    * <ul>
    * <li>Desired type does not exist on the SCH (actual)
    * <li>Desired type does not exist on the SCH (actual)
    * <ul>
    * <ul>
    * <li>Type does not exist on the stack: <code>false</code></li>
    * <li>Type does not exist on the stack: <code>false</code></li>
-   * <li>Type exists on the stack: <code>true</code> if the config key is on the stack.
-   * otherwise <code>false</code></li>
+   * <li>Type exists on the stack: <code>true</code> if the config key is on the
+   * stack. otherwise <code>false</code></li>
    * </ul>
    * </ul>
    * </li>
    * </li>
-   * <li> Desired type exists for the SCH
+   * <li>Desired type exists for the SCH
    * <ul>
    * <ul>
    * <li>Desired tags already set for the SCH (actual): <code>false</code></li>
    * <li>Desired tags already set for the SCH (actual): <code>false</code></li>
    * <li>Desired tags DO NOT match SCH: <code>true</code> if the changed keys
    * <li>Desired tags DO NOT match SCH: <code>true</code> if the changed keys
@@ -384,22 +440,40 @@ public class ConfigHelper {
    * </li>
    * </li>
    * </ul>
    * </ul>
    *
    *
-   * @param @ServiceComponentHost
+   * @param sch
+   *          the SCH to calcualte config staleness for (not {@code null}).
+   * @param desiredConfigs
+   *          the desired configurations for the cluster. Obtaining these can be
+   *          expensive and since this method operates on SCH's, it could be
+   *          called 10,000's of times when generating cluster/host responses.
+   *          Therefore, the caller should build these once and pass them in. If
+   *          {@code null}, then this method will retrieve them at runtime,
+   *          incurring a performance penality.
+   *
    * @return <code>true</code> if the actual configs are stale
    * @return <code>true</code> if the actual configs are stale
    */
    */
-  public boolean isStaleConfigs(ServiceComponentHost sch) throws AmbariException {
+  public boolean isStaleConfigs(ServiceComponentHost sch, Map<String, DesiredConfig> desiredConfigs)
+      throws AmbariException {
     Boolean stale = null;
     Boolean stale = null;
 
 
+    // try the cache
     if (STALE_CONFIGS_CACHE_ENABLED) {
     if (STALE_CONFIGS_CACHE_ENABLED) {
       stale = staleConfigsCache.getIfPresent(sch);
       stale = staleConfigsCache.getIfPresent(sch);
     }
     }
 
 
     if (stale == null) {
     if (stale == null) {
-      stale = calculateIsStaleConfigs(sch);
-      staleConfigsCache.put(sch, stale);
-      if(LOG.isDebugEnabled()) {
-        LOG.debug("Config staleness for " +
-                  sch.getServiceComponentName() + " on host " + sch.getHostName() + " - " + stale);
+      ReadWriteLock lock = transactionLocks.getLock(LockArea.STALE_CONFIG_CACHE);
+      lock.readLock().lock();
+
+      try {
+        stale = calculateIsStaleConfigs(sch, desiredConfigs);
+        staleConfigsCache.put(sch, stale);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Cache configuration staleness for host {} and component {} as {}",
+              sch.getHostName(), sch.getServiceComponentName(), stale);
+        }
+      } finally {
+        lock.readLock().unlock();
       }
       }
     }
     }
     return stale;
     return stale;
@@ -985,7 +1059,23 @@ public class ConfigHelper {
     return defaultPropertiesByType;
     return defaultPropertiesByType;
   }
   }
 
 
-  private boolean calculateIsStaleConfigs(ServiceComponentHost sch) throws AmbariException {
+  /**
+   * Gets whether configurations are stale for a given service host component.
+   *
+   * @param sch
+   *          the SCH to calcualte config staleness for (not {@code null}).
+   * @param desiredConfigs
+   *          the desired configurations for the cluster. Obtaining these can be
+   *          expensive and since this method operates on SCH's, it could be
+   *          called 10,000's of times when generating cluster/host responses.
+   *          Therefore, the caller should build these once and pass them in. If
+   *          {@code null}, then this method will retrieve them at runtime,
+   *          incurring a performance penality.
+   * @return
+   * @throws AmbariException
+   */
+  private boolean calculateIsStaleConfigs(ServiceComponentHost sch,
+      Map<String, DesiredConfig> desiredConfigs) throws AmbariException {
 
 
     if (sch.isRestartRequired()) {
     if (sch.isRestartRequired()) {
       return true;
       return true;
@@ -999,10 +1089,12 @@ public class ConfigHelper {
     Cluster cluster = clusters.getClusterById(sch.getClusterId());
     Cluster cluster = clusters.getClusterById(sch.getClusterId());
     StackId stackId = cluster.getDesiredStackVersion();
     StackId stackId = cluster.getDesiredStackVersion();
 
 
-    Map<String, Map<String, String>> desired = getEffectiveDesiredTags(cluster, sch.getHostName(), true);
+    Map<String, Map<String, String>> desired = getEffectiveDesiredTags(cluster, sch.getHostName(),
+        desiredConfigs);
 
 
     ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
     ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(),
         stackId.getStackVersion(), sch.getServiceName());
         stackId.getStackVersion(), sch.getServiceName());
+
     ComponentInfo componentInfo = serviceInfo.getComponentByName(sch.getServiceComponentName());
     ComponentInfo componentInfo = serviceInfo.getComponentByName(sch.getServiceComponentName());
     // Configs are considered stale when:
     // Configs are considered stale when:
     // - desired type DOES NOT exist in actual
     // - desired type DOES NOT exist in actual

+ 10 - 10
ambari-server/src/main/java/org/apache/ambari/server/state/Host.java

@@ -366,20 +366,20 @@ public interface Host extends Comparable {
 
 
   /**
   /**
    * Get the desired configurations for the host including overrides
    * Get the desired configurations for the host including overrides
+   *
    * @param cluster
    * @param cluster
+   * @param clusterDesiredConfigs
+   *          the desired configurations for the cluster. Obtaining these can be
+   *          expensive and since this method operates on hosts, it could be
+   *          called 1,000's of times when generating host responses. Therefore,
+   *          the caller should build these once and pass them in. If
+   *          {@code null}, then this method will retrieve them at runtime,
+   *          incurring a performance penality.
    * @return
    * @return
    * @throws AmbariException
    * @throws AmbariException
    */
    */
-  Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster) throws AmbariException;
-
-  /**
-   * Get the desired configurations for the host including overrides
-   * @param cluster
-   * @param bypassCache
-   * @return
-   * @throws AmbariException
-   */
-  Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster, boolean bypassCache) throws AmbariException;
+  Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster,
+      Map<String, DesiredConfig> clusterDesiredConfigs) throws AmbariException;
 
 
   /**
   /**
    * Sets the maintenance state for the host.
    * Sets the maintenance state for the host.

+ 13 - 1
ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java

@@ -166,7 +166,19 @@ public interface ServiceComponentHost {
 
 
   void setComponentAdminState(HostComponentAdminState attribute);
   void setComponentAdminState(HostComponentAdminState attribute);
 
 
-  ServiceComponentHostResponse convertToResponse();
+  /**
+   * Builds a {@link ServiceComponentHostResponse}.
+   *
+   * @param desiredConfigs
+   *          the desired configurations for the cluster. Obtaining these can be
+   *          expensive and since this method operates on SCH's, it could be
+   *          called 10,000's of times when generating cluster/host responses.
+   *          Therefore, the caller should build these once and pass them in. If
+   *          {@code null}, then this method will retrieve them at runtime,
+   *          incurring a performance penality.
+   * @return
+   */
+  ServiceComponentHostResponse convertToResponse(Map<String, DesiredConfig> desiredConfigs);
 
 
   boolean isPersisted();
   boolean isPersisted();
 
 

+ 15 - 17
ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java

@@ -41,6 +41,9 @@ import javax.annotation.Nullable;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManager;
 import javax.persistence.RollbackException;
 import javax.persistence.RollbackException;
 
 
+import org.apache.ambari.annotations.TransactionalLock;
+import org.apache.ambari.annotations.TransactionalLock.LockArea;
+import org.apache.ambari.annotations.TransactionalLock.LockType;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ConfigGroupNotFoundException;
 import org.apache.ambari.server.ConfigGroupNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -2346,21 +2349,13 @@ public class ClusterImpl implements Cluster {
    */
    */
   @Override
   @Override
   public Map<String, Set<DesiredConfig>> getAllDesiredConfigVersions() {
   public Map<String, Set<DesiredConfig>> getAllDesiredConfigVersions() {
-    return getDesiredConfigs(true, false);
+    return getDesiredConfigs(true);
   }
   }
 
 
-  /**
-   * Gets the active desired configurations for the cluster.
-   * @return a map of type-to-configuration information.
-   */
-  @Override
-  public Map<String, DesiredConfig> getDesiredConfigs() {
-    return getDesiredConfigs(false);
-  }
 
 
   @Override
   @Override
-  public Map<String, DesiredConfig> getDesiredConfigs(boolean bypassCache) {
-    Map<String, Set<DesiredConfig>> activeConfigsByType = getDesiredConfigs(false, bypassCache);
+  public Map<String, DesiredConfig> getDesiredConfigs() {
+    Map<String, Set<DesiredConfig>> activeConfigsByType = getDesiredConfigs(false);
     return Maps.transformEntries(
     return Maps.transformEntries(
         activeConfigsByType,
         activeConfigsByType,
         new Maps.EntryTransformer<String, Set<DesiredConfig>, DesiredConfig>() {
         new Maps.EntryTransformer<String, Set<DesiredConfig>, DesiredConfig>() {
@@ -2378,16 +2373,14 @@ public class ClusterImpl implements Cluster {
    *                    desired configuration per config type.
    *                    desired configuration per config type.
    * @return a map of type-to-configuration information.
    * @return a map of type-to-configuration information.
    */
    */
-  private Map<String, Set<DesiredConfig>> getDesiredConfigs(boolean allVersions, boolean bypassCache) {
+  private Map<String, Set<DesiredConfig>> getDesiredConfigs(boolean allVersions) {
     loadConfigurations();
     loadConfigurations();
     clusterGlobalLock.readLock().lock();
     clusterGlobalLock.readLock().lock();
     try {
     try {
       Map<String, Set<DesiredConfig>> map = new HashMap<>();
       Map<String, Set<DesiredConfig>> map = new HashMap<>();
       Collection<String> types = new HashSet<>();
       Collection<String> types = new HashSet<>();
-      Collection<ClusterConfigMappingEntity> entities =
-          bypassCache ?
-              clusterDAO.getClusterConfigMappingEntitiesByCluster(getClusterId()) :
-              getClusterEntity().getConfigMappingEntities();
+      Collection<ClusterConfigMappingEntity> entities = getClusterEntity().getConfigMappingEntities();
+
       for (ClusterConfigMappingEntity e : entities) {
       for (ClusterConfigMappingEntity e : entities) {
         if (allVersions || e.isSelected() > 0) {
         if (allVersions || e.isSelected() > 0) {
           DesiredConfig c = new DesiredConfig();
           DesiredConfig c = new DesiredConfig();
@@ -2801,6 +2794,7 @@ public class ClusterImpl implements Cluster {
   }
   }
 
 
   @Transactional
   @Transactional
+  @TransactionalLock(lockArea = LockArea.STALE_CONFIG_CACHE, lockType = LockType.WRITE)
   void selectConfig(String type, String tag, String user) {
   void selectConfig(String type, String tag, String user) {
     Collection<ClusterConfigMappingEntity> entities =
     Collection<ClusterConfigMappingEntity> entities =
         clusterDAO.getClusterConfigMappingEntitiesByCluster(getClusterId());
         clusterDAO.getClusterConfigMappingEntitiesByCluster(getClusterId());
@@ -2829,6 +2823,7 @@ public class ClusterImpl implements Cluster {
   }
   }
 
 
   @Transactional
   @Transactional
+  @TransactionalLock(lockArea = LockArea.STALE_CONFIG_CACHE, lockType = LockType.WRITE)
   ServiceConfigVersionResponse applyConfigs(Set<Config> configs, String user, String serviceConfigVersionNote) {
   ServiceConfigVersionResponse applyConfigs(Set<Config> configs, String user, String serviceConfigVersionNote) {
 
 
     String serviceName = null;
     String serviceName = null;
@@ -3145,6 +3140,9 @@ public class ClusterImpl implements Cluster {
     int alertStatusHosts = 0;
     int alertStatusHosts = 0;
     int heartbeatLostStateHosts = 0;
     int heartbeatLostStateHosts = 0;
 
 
+    // look this up once so it can be reused in the loop for every SCH
+    Map<String, DesiredConfig> desiredConfigs = getDesiredConfigs();
+
     Collection<Host> hosts = clusterHosts.values();
     Collection<Host> hosts = clusterHosts.values();
     Iterator<Host> iterator = hosts.iterator();
     Iterator<Host> iterator = hosts.iterator();
     while (iterator.hasNext()) {
     while (iterator.hasNext()) {
@@ -3186,7 +3184,7 @@ public class ClusterImpl implements Cluster {
 
 
       if (serviceComponentHostsByHost.containsKey(hostName)) {
       if (serviceComponentHostsByHost.containsKey(hostName)) {
         for (ServiceComponentHost sch : serviceComponentHostsByHost.get(hostName)) {
         for (ServiceComponentHost sch : serviceComponentHostsByHost.get(hostName)) {
-          staleConfig = staleConfig || configHelper.isStaleConfigs(sch);
+          staleConfig = staleConfig || configHelper.isStaleConfigs(sch, desiredConfigs);
           maintenanceState = maintenanceState ||
           maintenanceState = maintenanceState ||
             maintenanceStateHelper.getEffectiveState(sch) != MaintenanceState.OFF;
             maintenanceStateHelper.getEffectiveState(sch) != MaintenanceState.OFF;
         }
         }

+ 12 - 20
ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java

@@ -1330,29 +1330,21 @@ public class HostImpl implements Host {
   }
   }
 
 
   /**
   /**
-   * Get a map of configType with all applicable config tags.
-   *
-   * @param cluster  the cluster
-   *
-   * @return Map of configType -> HostConfig
+   * {@inheritDoc}
    */
    */
   @Override
   @Override
-  public Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster) throws AmbariException {
-    return getDesiredHostConfigs(cluster, false);
-  }
-
-  /**
-   * Get a map of configType with all applicable config tags.
-   *
-   * @param cluster  the cluster
-   * @param bypassCache don't use cached values
-   *
-   * @return Map of configType -> HostConfig
-   */
-  @Override
-  public Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster, boolean bypassCache) throws AmbariException {
+  public Map<String, HostConfig> getDesiredHostConfigs(Cluster cluster,
+      Map<String, DesiredConfig> clusterDesiredConfigs) throws AmbariException {
     Map<String, HostConfig> hostConfigMap = new HashMap<String, HostConfig>();
     Map<String, HostConfig> hostConfigMap = new HashMap<String, HostConfig>();
-    Map<String, DesiredConfig> clusterDesiredConfigs = (cluster == null) ? new HashMap<String, DesiredConfig>() : cluster.getDesiredConfigs(bypassCache);
+
+    if( null == cluster ){
+      clusterDesiredConfigs = new HashMap<String, DesiredConfig>();
+    }
+
+    // per method contract, fetch if not supplied
+    if (null == clusterDesiredConfigs) {
+      clusterDesiredConfigs = cluster.getDesiredConfigs();
+    }
 
 
     if (clusterDesiredConfigs != null) {
     if (clusterDesiredConfigs != null) {
       for (Map.Entry<String, DesiredConfig> desiredConfigEntry
       for (Map.Entry<String, DesiredConfig> desiredConfigEntry

+ 3 - 2
ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java

@@ -56,6 +56,7 @@ import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.HostConfig;
 import org.apache.ambari.server.state.HostConfig;
@@ -1323,7 +1324,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   }
   }
 
 
   @Override
   @Override
-  public ServiceComponentHostResponse convertToResponse() {
+  public ServiceComponentHostResponse convertToResponse(Map<String, DesiredConfig> desiredConfigs) {
     clusterGlobalLock.readLock().lock();
     clusterGlobalLock.readLock().lock();
     try {
     try {
       readLock.lock();
       readLock.lock();
@@ -1364,7 +1365,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
         r.setUpgradeState(upgradeState);
         r.setUpgradeState(upgradeState);
 
 
         try {
         try {
-          r.setStaleConfig(helper.isStaleConfigs(this));
+          r.setStaleConfig(helper.isStaleConfigs(this, desiredConfigs));
         } catch (Exception e) {
         } catch (Exception e) {
           LOG.error("Could not determine stale config", e);
           LOG.error("Could not determine stale config", e);
         }
         }

+ 0 - 1
ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java

@@ -780,5 +780,4 @@ public class ConfigurationTest {
     Assert.assertEquals("FooChannel", properties.getProperty("eclipselink.cache.coordination.channel"));
     Assert.assertEquals("FooChannel", properties.getProperty("eclipselink.cache.coordination.channel"));
     Assert.assertEquals("commit", properties.getProperty("eclipselink.persistence-context.flush-mode"));
     Assert.assertEquals("commit", properties.getProperty("eclipselink.persistence-context.flush-mode"));
   }
   }
-
 }
 }

+ 15 - 15
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java

@@ -1061,7 +1061,7 @@ public class AmbariManagementControllerImplTest {
         new HashMap<String, ServiceComponentHost>() {{
         new HashMap<String, ServiceComponentHost>() {{
           put("host1", componentHost);
           put("host1", componentHost);
         }});
         }});
-    expect(componentHost.convertToResponse()).andReturn(response);
+    expect(componentHost.convertToResponse(null)).andReturn(response);
     expect(componentHost.getHostName()).andReturn("host1").anyTimes();
     expect(componentHost.getHostName()).andReturn("host1").anyTimes();
     expect(maintHelper.getEffectiveState(componentHost, host)).andReturn(MaintenanceState.OFF);
     expect(maintHelper.getEffectiveState(componentHost, host)).andReturn(MaintenanceState.OFF);
 
 
@@ -1201,7 +1201,7 @@ public class AmbariManagementControllerImplTest {
     }});
     }});
 
 
     expect(componentHost1.getState()).andReturn(State.INSTALLED);
     expect(componentHost1.getState()).andReturn(State.INSTALLED);
-    expect(componentHost1.convertToResponse()).andReturn(response1);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
 
 
     // replay mocks
     // replay mocks
@@ -1288,7 +1288,7 @@ public class AmbariManagementControllerImplTest {
         new HashMap<String, ServiceComponentHost>() {{
         new HashMap<String, ServiceComponentHost>() {{
           put("host1", componentHost1);
           put("host1", componentHost1);
         }});
         }});
-    expect(componentHost1.convertToResponse()).andReturn(response1);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
 
 
     expect(ambariMetaInfo.getComponentToService("stackName", "stackVersion", "component2")).andReturn("service1");
     expect(ambariMetaInfo.getComponentToService("stackName", "stackVersion", "component2")).andReturn("service1");
@@ -1304,7 +1304,7 @@ public class AmbariManagementControllerImplTest {
         new HashMap<String, ServiceComponentHost>() {{
         new HashMap<String, ServiceComponentHost>() {{
           put("host1", componentHost2);
           put("host1", componentHost2);
         }});
         }});
-    expect(componentHost2.convertToResponse()).andReturn(response2);
+    expect(componentHost2.convertToResponse(null)).andReturn(response2);
 
 
     // replay mocks
     // replay mocks
     replay(stateHelper, injector, clusters, cluster, host, stack,
     replay(stateHelper, injector, clusters, cluster, host, stack,
@@ -1392,7 +1392,7 @@ public class AmbariManagementControllerImplTest {
                                                                HashMap<String, ServiceComponentHost>() {{
                                                                HashMap<String, ServiceComponentHost>() {{
                                                                  put("host1", componentHost1);
                                                                  put("host1", componentHost1);
                                                                }});
                                                                }});
-    expect(componentHost1.convertToResponse()).andReturn(response1);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
 
 
     expect(ambariMetaInfo.getComponentToService("stackName", "stackVersion", "component2")).andReturn("service2");
     expect(ambariMetaInfo.getComponentToService("stackName", "stackVersion", "component2")).andReturn("service2");
@@ -1406,7 +1406,7 @@ public class AmbariManagementControllerImplTest {
                                                                 HashMap<String, ServiceComponentHost>() {{
                                                                 HashMap<String, ServiceComponentHost>() {{
                                                                   put("host1", componentHost2);
                                                                   put("host1", componentHost2);
                                                                 }});
                                                                 }});
-    expect(componentHost2.convertToResponse()).andReturn(response2);
+    expect(componentHost2.convertToResponse(null)).andReturn(response2);
     expect(componentHost2.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
 
 
     // replay mocks
     // replay mocks
@@ -1498,7 +1498,7 @@ public class AmbariManagementControllerImplTest {
         new HashMap<String, ServiceComponentHost>() {{
         new HashMap<String, ServiceComponentHost>() {{
           put("host1", componentHost1);
           put("host1", componentHost1);
         }});
         }});
-    expect(componentHost1.convertToResponse()).andReturn(response1);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
 
 
     expect(ambariMetaInfo.getComponentToService("stackName", "stackVersion", "component2")).andReturn("service2");
     expect(ambariMetaInfo.getComponentToService("stackName", "stackVersion", "component2")).andReturn("service2");
@@ -1514,7 +1514,7 @@ public class AmbariManagementControllerImplTest {
         new HashMap<String, ServiceComponentHost>() {{
         new HashMap<String, ServiceComponentHost>() {{
           put("host1", componentHost2);
           put("host1", componentHost2);
         }});
         }});
-    expect(componentHost2.convertToResponse()).andReturn(response2);
+    expect(componentHost2.convertToResponse(null)).andReturn(response2);
     expect(componentHost2.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
 
 
     // replay mocks
     // replay mocks
@@ -1601,7 +1601,7 @@ public class AmbariManagementControllerImplTest {
     expect(service.getServiceComponent("component1")).andReturn(component);
     expect(service.getServiceComponent("component1")).andReturn(component);
     expect(component.getName()).andReturn("component1");
     expect(component.getName()).andReturn("component1");
     expect(component.getServiceComponentHosts()).andReturn(Collections.singletonMap("foo", componentHost1));
     expect(component.getServiceComponentHosts()).andReturn(Collections.singletonMap("foo", componentHost1));
-    expect(componentHost1.convertToResponse()).andReturn(response1);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
 
 
     expect(clusters.getClustersForHost("host2")).andThrow(new HostNotFoundException("host2"));
     expect(clusters.getClustersForHost("host2")).andThrow(new HostNotFoundException("host2"));
@@ -1611,7 +1611,7 @@ public class AmbariManagementControllerImplTest {
     expect(service.getServiceComponent("component3")).andReturn(component3);
     expect(service.getServiceComponent("component3")).andReturn(component3);
     expect(component3.getName()).andReturn("component3");
     expect(component3.getName()).andReturn("component3");
     expect(component3.getServiceComponentHosts()).andReturn(Collections.singletonMap("foo", componentHost2));
     expect(component3.getServiceComponentHosts()).andReturn(Collections.singletonMap("foo", componentHost2));
-    expect(componentHost2.convertToResponse()).andReturn(response2);
+    expect(componentHost2.convertToResponse(null)).andReturn(response2);
     expect(componentHost2.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
 
 
     // replay mocks
     // replay mocks
@@ -1802,8 +1802,8 @@ public class AmbariManagementControllerImplTest {
     expect(component.getName()).andReturn("component1").anyTimes();
     expect(component.getName()).andReturn("component1").anyTimes();
 
 
     expect(component.getServiceComponentHosts()).andReturn(mapHostComponents);
     expect(component.getServiceComponentHosts()).andReturn(mapHostComponents);
-    expect(componentHost1.convertToResponse()).andReturn(response1);
-    expect(componentHost2.convertToResponse()).andReturn(response2);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
+    expect(componentHost2.convertToResponse(null)).andReturn(response2);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
 
 
@@ -1888,14 +1888,14 @@ public class AmbariManagementControllerImplTest {
     expect(component2.getName()).andReturn("component2").anyTimes();
     expect(component2.getName()).andReturn("component2").anyTimes();
 
 
     expect(component1.getServiceComponentHosts()).andReturn(mapHostComponents);
     expect(component1.getServiceComponentHosts()).andReturn(mapHostComponents);
-    expect(componentHost1.convertToResponse()).andReturn(response1);
-    expect(componentHost2.convertToResponse()).andReturn(response2);
+    expect(componentHost1.convertToResponse(null)).andReturn(response1);
+    expect(componentHost2.convertToResponse(null)).andReturn(response2);
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost1.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
     expect(componentHost2.getHostName()).andReturn("host1");
     expect(componentHost3.getHostName()).andReturn("host1");
     expect(componentHost3.getHostName()).andReturn("host1");
 
 
     expect(component2.getServiceComponentHosts()).andReturn(Collections.singletonMap("foobar", componentHost3));
     expect(component2.getServiceComponentHosts()).andReturn(Collections.singletonMap("foobar", componentHost3));
-    expect(componentHost3.convertToResponse()).andReturn(response3);
+    expect(componentHost3.convertToResponse(null)).andReturn(response3);
 
 
     // replay mocks
     // replay mocks
     replay(maintHelper, injector, clusters, cluster, response1, response2,
     replay(maintHelper, injector, clusters, cluster, response1, response2,

+ 1 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java

@@ -105,7 +105,7 @@ public class RefreshYarnCapacitySchedulerReleaseConfigTest {
     Set<ServiceComponentHostResponse> resps = controller.getHostComponents(Collections.singleton(r));
     Set<ServiceComponentHostResponse> resps = controller.getHostComponents(Collections.singleton(r));
     Assert.assertEquals(1, resps.size());
     Assert.assertEquals(1, resps.size());
     
     
-    Assert.assertEquals(true, configHelper.isStaleConfigs(clusters.getCluster("c1").getService("YARN").getServiceComponent("RESOURCEMANAGER").getServiceComponentHost("c6401")));
+    Assert.assertEquals(true, configHelper.isStaleConfigs(clusters.getCluster("c1").getService("YARN").getServiceComponent("RESOURCEMANAGER").getServiceComponentHost("c6401"), null));
   }
   }
 
 
   @Test
   @Test

+ 46 - 29
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java

@@ -18,10 +18,28 @@
 
 
 package org.apache.ambari.server.controller.internal;
 package org.apache.ambari.server.controller.internal;
 
 
-import com.google.gson.Gson;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.HostNotFoundException;
 import org.apache.ambari.server.HostNotFoundException;
 import org.apache.ambari.server.actionmanager.ActionDBAccessor;
 import org.apache.ambari.server.actionmanager.ActionDBAccessor;
@@ -29,10 +47,10 @@ import org.apache.ambari.server.agent.ComponentRecoveryReport;
 import org.apache.ambari.server.agent.RecoveryReport;
 import org.apache.ambari.server.agent.RecoveryReport;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.HostRequest;
 import org.apache.ambari.server.controller.HostResponse;
 import org.apache.ambari.server.controller.HostResponse;
 import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
-import org.apache.ambari.server.controller.HostRequest;
 import org.apache.ambari.server.controller.ResourceProviderFactory;
 import org.apache.ambari.server.controller.ResourceProviderFactory;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.ServiceComponentHostResponse;
 import org.apache.ambari.server.controller.ServiceComponentHostResponse;
@@ -50,43 +68,26 @@ import org.apache.ambari.server.security.authorization.AuthorizationHelperInitia
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostConfig;
 import org.apache.ambari.server.state.HostConfig;
 import org.apache.ambari.server.state.HostHealthStatus;
 import org.apache.ambari.server.state.HostHealthStatus;
 import org.apache.ambari.server.state.HostHealthStatus.HealthStatus;
 import org.apache.ambari.server.state.HostHealthStatus.HealthStatus;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.MaintenanceState;
-import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.stack.OsFamily;
 import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.topology.TopologyManager;
 import org.easymock.EasyMock;
 import org.easymock.EasyMock;
 import org.easymock.EasyMockSupport;
 import org.easymock.EasyMockSupport;
 import org.junit.After;
 import org.junit.After;
-import org.apache.ambari.server.topology.TopologyManager;
 import org.junit.Assert;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.Test;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 
-import javax.persistence.EntityManager;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import com.google.gson.Gson;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 
 
 /**
 /**
  * HostResourceProvider tests.
  * HostResourceProvider tests.
@@ -127,6 +128,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     AbstractControllerResourceProvider.init(resourceProviderFactory);
     AbstractControllerResourceProvider.init(resourceProviderFactory);
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     cluster.recalculateAllClusterVersionStates();
     cluster.recalculateAllClusterVersionStates();
     EasyMock.expectLastCall().once();
     EasyMock.expectLastCall().once();
 
 
@@ -232,6 +234,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getClustersForHost("Host102")).andReturn(clusterSet).anyTimes();
     expect(clusters.getClustersForHost("Host102")).andReturn(clusterSet).anyTimes();
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     expect(healthStatus.getHealthStatus()).andReturn(HostHealthStatus.HealthStatus.HEALTHY).anyTimes();
     expect(healthStatus.getHealthStatus()).andReturn(HostHealthStatus.HealthStatus.HEALTHY).anyTimes();
     expect(healthStatus.getHealthReport()).andReturn("HEALTHY").anyTimes();
     expect(healthStatus.getHealthReport()).andReturn("HEALTHY").anyTimes();
@@ -320,6 +323,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     expect(hostResponse1.getClusterName()).andReturn("").anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
@@ -420,6 +424,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     expect(healthStatus.getHealthStatus()).andReturn(HostHealthStatus.HealthStatus.HEALTHY).anyTimes();
     expect(healthStatus.getHealthStatus()).andReturn(HostHealthStatus.HealthStatus.HEALTHY).anyTimes();
     expect(healthStatus.getHealthReport()).andReturn("HEALTHY").anyTimes();
     expect(healthStatus.getHealthReport()).andReturn("HEALTHY").anyTimes();
@@ -515,6 +520,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
@@ -598,6 +604,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
@@ -705,6 +712,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getClustersForHost("Host100")).andReturn(clusterSet).anyTimes();
     expect(clusters.getClustersForHost("Host100")).andReturn(clusterSet).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     expect(ambariMetaInfo.getComponent((String) anyObject(), (String) anyObject(),
     expect(ambariMetaInfo.getComponent((String) anyObject(), (String) anyObject(),
         (String) anyObject(), (String) anyObject())).andReturn(componentInfo).anyTimes();
         (String) anyObject(), (String) anyObject())).andReturn(componentInfo).anyTimes();
@@ -797,6 +805,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getClustersForHost("Host100")).andReturn(clusterSet).anyTimes();
     expect(clusters.getClustersForHost("Host100")).andReturn(clusterSet).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(clusters.getHosts()).andReturn(Arrays.asList(host100)).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHealthStatus()).andReturn(healthStatus).anyTimes();
     expect(hostResponse1.getHealthStatus()).andReturn(healthStatus).anyTimes();
@@ -901,6 +910,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expectLastCall().anyTimes();
     expectLastCall().anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getResourceId()).andReturn(4L).anyTimes();
     expect(cluster.getResourceId()).andReturn(4L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHealthStatus()).andReturn(healthStatus).anyTimes();
     expect(hostResponse1.getHealthStatus()).andReturn(healthStatus).anyTimes();
@@ -993,6 +1003,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expectLastCall().anyTimes();
     expectLastCall().anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getResourceId()).andReturn(4L).anyTimes();
     expect(cluster.getResourceId()).andReturn(4L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getClusterName()).andReturn("Cluster100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHostname()).andReturn("Host100").anyTimes();
     expect(hostResponse1.getHealthStatus()).andReturn(healthStatus).anyTimes();
     expect(hostResponse1.getHealthStatus()).andReturn(healthStatus).anyTimes();
@@ -1065,6 +1076,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getClustersForHost("Host100")).andReturn(clusterSet).anyTimes();
     expect(clusters.getClustersForHost("Host100")).andReturn(clusterSet).anyTimes();
     expect(cluster.getServiceComponentHosts("Host100")).andReturn(Collections.EMPTY_LIST);
     expect(cluster.getServiceComponentHosts("Host100")).andReturn(Collections.EMPTY_LIST);
     expect(cluster.getClusterId()).andReturn(100L).anyTimes();
     expect(cluster.getClusterId()).andReturn(100L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     clusters.deleteHost("Host100");
     clusters.deleteHost("Host100");
     cluster.recalculateAllClusterVersionStates();
     cluster.recalculateAllClusterVersionStates();
     expect(host1.getHostName()).andReturn("Host100").anyTimes();
     expect(host1.getHostName()).andReturn("Host100").anyTimes();
@@ -1145,6 +1157,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getClustersForHost("host1")).andReturn(setCluster);
     expect(clusters.getClustersForHost("host1")).andReturn(setCluster);
     expect(clusters.getCluster("Cluster100")).andReturn(cluster).anyTimes();
     expect(clusters.getCluster("Cluster100")).andReturn(cluster).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     expect(host.getHostName()).andReturn("host1").anyTimes();
     expect(host.getHostName()).andReturn("host1").anyTimes();
     expect(host.convertToResponse()).andReturn(response);
     expect(host.convertToResponse()).andReturn(response);
     response.setClusterName("cluster1");
     response.setClusterName("cluster1");
@@ -1215,6 +1228,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(managementController.getClusters()).andReturn(clusters).anyTimes();
     expect(managementController.getClusters()).andReturn(clusters).anyTimes();
     expect(clusters.getCluster("cluster1")).andReturn(cluster);
     expect(clusters.getCluster("cluster1")).andReturn(cluster);
     expect(clusters.getHost("host1")).andReturn(host);
     expect(clusters.getHost("host1")).andReturn(host);
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
     expect(host.getHostName()).andReturn("host1").anyTimes();
     expect(host.getHostName()).andReturn("host1").anyTimes();
     // because cluster is not in set will result in HostNotFoundException
     // because cluster is not in set will result in HostNotFoundException
     expect(clusters.getClustersForHost("host1")).andReturn(Collections.<Cluster>emptySet());
     expect(clusters.getClustersForHost("host1")).andReturn(Collections.<Cluster>emptySet());
@@ -1280,6 +1294,7 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(clusters.getHost("host4")).andThrow(new HostNotFoundException("host4"));
     expect(clusters.getHost("host4")).andThrow(new HostNotFoundException("host4"));
 
 
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
     expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+    expect(cluster.getDesiredConfigs()).andReturn(new HashMap<String, DesiredConfig>()).anyTimes();
 
 
     // replay mocks
     // replay mocks
     replayAll();
     replayAll();
@@ -1386,7 +1401,9 @@ public class HostResourceProviderTest extends EasyMockSupport {
     expect(host.convertToResponse()).andReturn(hostResponse).anyTimes();
     expect(host.convertToResponse()).andReturn(hostResponse).anyTimes();
 
 
     try {
     try {
-      expect(host.getDesiredHostConfigs(EasyMock.<Cluster>anyObject())).andReturn(desiredConfigs).anyTimes();
+      expect(host.getDesiredHostConfigs(EasyMock.<Cluster> anyObject(),
+          EasyMock.<Map> anyObject())).andReturn(desiredConfigs).anyTimes();
+
     } catch (AmbariException e) {
     } catch (AmbariException e) {
       Assert.fail(e.getMessage());
       Assert.fail(e.getMessage());
     }
     }

+ 14 - 9
ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerActionTest.java

@@ -18,27 +18,31 @@
 
 
 package org.apache.ambari.server.serveraction.kerberos;
 package org.apache.ambari.server.serveraction.kerberos;
 
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.audit.AuditLogger;
 import org.apache.ambari.server.audit.AuditLogger;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.stack.OsFamily;
 import org.easymock.EasyMockSupport;
 import org.easymock.EasyMockSupport;
 import org.junit.Before;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.rules.TemporaryFolder;
 
 
-import java.io.File;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.easymock.EasyMock.*;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 
 
 public class UpdateKerberosConfigsServerActionTest extends EasyMockSupport{
 public class UpdateKerberosConfigsServerActionTest extends EasyMockSupport{
 
 
@@ -66,6 +70,7 @@ public class UpdateKerberosConfigsServerActionTest extends EasyMockSupport{
         bind(AmbariManagementController.class).toInstance(controller);
         bind(AmbariManagementController.class).toInstance(controller);
         bind(ConfigHelper.class).toInstance(createNiceMock(ConfigHelper.class));
         bind(ConfigHelper.class).toInstance(createNiceMock(ConfigHelper.class));
         bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class));
         bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class));
+        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
       }
       }
     });
     });
 
 

+ 7 - 7
ambari-server/src/test/java/org/apache/ambari/server/state/ConfigHelperTest.java

@@ -723,7 +723,7 @@ public class ConfigHelperTest {
       expect(sch.getServiceComponentName()).andReturn("FLUME_HANDLER").anyTimes();
       expect(sch.getServiceComponentName()).andReturn("FLUME_HANDLER").anyTimes();
       replay(sch);
       replay(sch);
       // Cluster level config changes
       // Cluster level config changes
-      Assert.assertTrue(configHelper.isStaleConfigs(sch));
+      Assert.assertTrue(configHelper.isStaleConfigs(sch, null));
 
 
       HostConfig hc2 = new HostConfig();
       HostConfig hc2 = new HostConfig();
       hc2.setDefaultVersionTag("version1");
       hc2.setDefaultVersionTag("version1");
@@ -731,7 +731,7 @@ public class ConfigHelperTest {
       // invalidate cache to test new sch
       // invalidate cache to test new sch
       configHelper.invalidateStaleConfigsCache();
       configHelper.invalidateStaleConfigsCache();
       // Cluster level same configs
       // Cluster level same configs
-      Assert.assertFalse(configHelper.isStaleConfigs(sch));
+      Assert.assertFalse(configHelper.isStaleConfigs(sch, null));
 
 
       // Cluster level same configs but group specific configs for host have been updated
       // Cluster level same configs but group specific configs for host have been updated
       List<String> hosts = new ArrayList<String>();
       List<String> hosts = new ArrayList<String>();
@@ -743,7 +743,7 @@ public class ConfigHelperTest {
       addConfigGroup("configGroup1", "FLUME", hosts, configs);
       addConfigGroup("configGroup1", "FLUME", hosts, configs);
 
 
       // config group added for host - expect staleness
       // config group added for host - expect staleness
-      Assert.assertTrue(configHelper.isStaleConfigs(sch));
+      Assert.assertTrue(configHelper.isStaleConfigs(sch, null));
 
 
       HostConfig hc3 = new HostConfig();
       HostConfig hc3 = new HostConfig();
       hc3.setDefaultVersionTag("version1");
       hc3.setDefaultVersionTag("version1");
@@ -752,7 +752,7 @@ public class ConfigHelperTest {
       configHelper.invalidateStaleConfigsCache();
       configHelper.invalidateStaleConfigsCache();
 
 
       // version1 and FLUME1 - stale=false
       // version1 and FLUME1 - stale=false
-      Assert.assertFalse(configHelper.isStaleConfigs(sch));
+      Assert.assertFalse(configHelper.isStaleConfigs(sch, null));
 
 
       HostConfig hc4 = new HostConfig();
       HostConfig hc4 = new HostConfig();
       hc4.setDefaultVersionTag("version1");
       hc4.setDefaultVersionTag("version1");
@@ -761,7 +761,7 @@ public class ConfigHelperTest {
       configHelper.invalidateStaleConfigsCache();
       configHelper.invalidateStaleConfigsCache();
 
 
       // version1 and FLUME2 - stale=true
       // version1 and FLUME2 - stale=true
-      Assert.assertTrue(configHelper.isStaleConfigs(sch));
+      Assert.assertTrue(configHelper.isStaleConfigs(sch, null));
 
 
       HostConfig hc5 = new HostConfig();
       HostConfig hc5 = new HostConfig();
       hc5.setDefaultVersionTag("version3");
       hc5.setDefaultVersionTag("version3");
@@ -770,7 +770,7 @@ public class ConfigHelperTest {
       configHelper.invalidateStaleConfigsCache();
       configHelper.invalidateStaleConfigsCache();
 
 
       // version3 and FLUME1 - stale=true
       // version3 and FLUME1 - stale=true
-      Assert.assertTrue(configHelper.isStaleConfigs(sch));
+      Assert.assertTrue(configHelper.isStaleConfigs(sch, null));
 
 
       verify(sch);
       verify(sch);
     }
     }
@@ -828,7 +828,7 @@ public class ConfigHelperTest {
           while(!finished.get()){
           while(!finished.get()){
             checkLock.lock();
             checkLock.lock();
             try {
             try {
-              boolean isStale = configHelper.isStaleConfigs(sch);
+              boolean isStale = configHelper.isStaleConfigs(sch, null);
               if(mustBeStale.get() != isStale){
               if(mustBeStale.get() != isStale){
                 failed.set(true);
                 failed.set(true);
                 break;
                 break;

+ 2 - 2
ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterDeadlockTest.java

@@ -548,8 +548,8 @@ public class ClusterDeadlockTest {
           service.convertToResponse();
           service.convertToResponse();
           nameNodeComponent.convertToResponse();
           nameNodeComponent.convertToResponse();
           dataNodeComponent.convertToResponse();
           dataNodeComponent.convertToResponse();
-          nameNodeSCH.convertToResponse();
-          dataNodeSCH.convertToResponse();
+          nameNodeSCH.convertToResponse(null);
+          dataNodeSCH.convertToResponse(null);
 
 
           cluster.setProvisioningState(org.apache.ambari.server.state.State.INIT);
           cluster.setProvisioningState(org.apache.ambari.server.state.State.INIT);
           service.setMaintenanceState(MaintenanceState.OFF);
           service.setMaintenanceState(MaintenanceState.OFF);

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

@@ -594,7 +594,7 @@ public class ServiceComponentHostTest {
     sch.setDesiredState(State.INSTALLED);
     sch.setDesiredState(State.INSTALLED);
     sch.setState(State.INSTALLING);
     sch.setState(State.INSTALLING);
     sch.setStackVersion(new StackId("HDP-1.2.0"));
     sch.setStackVersion(new StackId("HDP-1.2.0"));
-    ServiceComponentHostResponse r = sch.convertToResponse();
+    ServiceComponentHostResponse r = sch.convertToResponse(null);
     Assert.assertEquals("HDFS", r.getServiceName());
     Assert.assertEquals("HDFS", r.getServiceName());
     Assert.assertEquals("DATANODE", r.getComponentName());
     Assert.assertEquals("DATANODE", r.getComponentName());
     Assert.assertEquals(hostName1, r.getHostname());
     Assert.assertEquals(hostName1, r.getHostname());
@@ -770,8 +770,8 @@ public class ServiceComponentHostTest {
     sch3.setState(State.INSTALLING);
     sch3.setState(State.INSTALLING);
     sch3.setStackVersion(new StackId(stackVersion));
     sch3.setStackVersion(new StackId(stackVersion));
 
 
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     makeConfig(cluster, "global", "version1",
     makeConfig(cluster, "global", "version1",
         new HashMap<String,String>() {{
         new HashMap<String,String>() {{
@@ -792,45 +792,45 @@ public class ServiceComponentHostTest {
         new HashMap<String,String>() {{ put("a", "c"); }}, new HashMap<String, Map<String,String>>());
         new HashMap<String,String>() {{ put("a", "c"); }}, new HashMap<String, Map<String,String>>());
 
 
     // HDP-x/HDFS does not define type 'foo', so changes do not count to stale
     // HDP-x/HDFS does not define type 'foo', so changes do not count to stale
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     makeConfig(cluster, "hdfs-site", "version1",
     makeConfig(cluster, "hdfs-site", "version1",
         new HashMap<String,String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
         new HashMap<String,String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
 
 
     // HDP-x/HDFS/hdfs-site is not on the actual, but it is defined, so it is stale
     // HDP-x/HDFS/hdfs-site is not on the actual, but it is defined, so it is stale
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
 
 
     actual.put("hdfs-site", new HashMap<String, String>() {{ put ("tag", "version1"); }});
     actual.put("hdfs-site", new HashMap<String, String>() {{ put ("tag", "version1"); }});
 
 
     sch1.updateActualConfigs(actual);
     sch1.updateActualConfigs(actual);
     // previous value from cache
     // previous value from cache
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
     //reset restartRequired flag + invalidating isStale cache
     //reset restartRequired flag + invalidating isStale cache
     // after start/restart command execution completed
     // after start/restart command execution completed
     sch1.setRestartRequired(false);
     sch1.setRestartRequired(false);
     // HDP-x/HDFS/hdfs-site up to date, only for sch1
     // HDP-x/HDFS/hdfs-site up to date, only for sch1
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
 
 
     sch2.updateActualConfigs(actual);
     sch2.updateActualConfigs(actual);
     // previous value from cache
     // previous value from cache
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
     //reset restartRequired flag + invalidating isStale cache(
     //reset restartRequired flag + invalidating isStale cache(
     // after start/restart command execution completed)
     // after start/restart command execution completed)
     sch2.setRestartRequired(false);
     sch2.setRestartRequired(false);
     // HDP-x/HDFS/hdfs-site up to date for both
     // HDP-x/HDFS/hdfs-site up to date for both
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     makeConfig(cluster, "hdfs-site", "version2",
     makeConfig(cluster, "hdfs-site", "version2",
         new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://foo"); }},
         new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://foo"); }},
         new HashMap<String, Map<String,String>>());
         new HashMap<String, Map<String,String>>());
 
 
     // HDP-x/HDFS/hdfs-site updated to changed property
     // HDP-x/HDFS/hdfs-site updated to changed property
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
 
 
     actual.get("hdfs-site").put("tag", "version2");
     actual.get("hdfs-site").put("tag", "version2");
     sch1.updateActualConfigs(actual);
     sch1.updateActualConfigs(actual);
@@ -840,8 +840,8 @@ public class ServiceComponentHostTest {
     sch1.setRestartRequired(false);
     sch1.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch2.setRestartRequired(false);
     // HDP-x/HDFS/hdfs-site updated to changed property
     // HDP-x/HDFS/hdfs-site updated to changed property
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     // make a host override
     // make a host override
     final Host host = clusters.getHostsForCluster(clusterName).get(hostName);
     final Host host = clusters.getHostsForCluster(clusterName).get(hostName);
@@ -861,29 +861,29 @@ public class ServiceComponentHostTest {
     cluster.addConfigGroup(configGroup);
     cluster.addConfigGroup(configGroup);
 
 
     // HDP-x/HDFS/hdfs-site updated host to changed property
     // HDP-x/HDFS/hdfs-site updated host to changed property
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
 
 
     actual.get("hdfs-site").put(configGroup.getId().toString(), "version3");
     actual.get("hdfs-site").put(configGroup.getId().toString(), "version3");
     sch2.updateActualConfigs(actual);
     sch2.updateActualConfigs(actual);
     // previous value from cache
     // previous value from cache
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
     //reset restartRequired flag + invalidating isStale cache
     //reset restartRequired flag + invalidating isStale cache
     // after start/restart command execution completed
     // after start/restart command execution completed
     sch2.setRestartRequired(false);
     sch2.setRestartRequired(false);
     // HDP-x/HDFS/hdfs-site updated host to changed property
     // HDP-x/HDFS/hdfs-site updated host to changed property
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     sch1.updateActualConfigs(actual);
     sch1.updateActualConfigs(actual);
     // previous value from cache
     // previous value from cache
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
     //reset restartRequired flag + invalidating isStale cache
     //reset restartRequired flag + invalidating isStale cache
     // after start/restart command execution completed
     // after start/restart command execution completed
     sch1.setRestartRequired(false);
     sch1.setRestartRequired(false);
     // HDP-x/HDFS/hdfs-site updated host to changed property
     // HDP-x/HDFS/hdfs-site updated host to changed property
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     // change 'global' property only affecting global/HDFS
     // change 'global' property only affecting global/HDFS
     makeConfig(cluster, "global", "version2",
     makeConfig(cluster, "global", "version2",
@@ -893,9 +893,9 @@ public class ServiceComponentHostTest {
         put("mapred_log_dir_prefix", "/foo2"); // MR2 only
         put("mapred_log_dir_prefix", "/foo2"); // MR2 only
       }}, new HashMap<String, Map<String,String>>());
       }}, new HashMap<String, Map<String,String>>());
 
 
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
 
 
     // Change core-site property, only HDFS property
     // Change core-site property, only HDFS property
     makeConfig(cluster, "core-site", "version1",
     makeConfig(cluster, "core-site", "version1",
@@ -904,9 +904,9 @@ public class ServiceComponentHostTest {
         put("fs.trash.interval", "360"); // HDFS only
         put("fs.trash.interval", "360"); // HDFS only
       }}, new HashMap<String, Map<String,String>>());
       }}, new HashMap<String, Map<String,String>>());
 
 
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch3.convertToResponse(null).isStaleConfig());
 
 
     actual.put("core-site", new HashMap<String, String>() {{
     actual.put("core-site", new HashMap<String, String>() {{
       put("tag", "version1");
       put("tag", "version1");
@@ -926,9 +926,9 @@ public class ServiceComponentHostTest {
     configGroup.persist();
     configGroup.persist();
     cluster.addConfigGroup(configGroup);
     cluster.addConfigGroup(configGroup);
 
 
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch3.convertToResponse(null).isStaleConfig());
 
 
     // Test actual configs are updated for deleted config group
     // Test actual configs are updated for deleted config group
     Long id = configGroup.getId();
     Long id = configGroup.getId();
@@ -938,27 +938,27 @@ public class ServiceComponentHostTest {
     actual.put("core-site", tags);
     actual.put("core-site", tags);
     sch3.updateActualConfigs(actual);
     sch3.updateActualConfigs(actual);
     // previous value from cache
     // previous value from cache
-    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch3.convertToResponse(null).isStaleConfig());
     //reset restartRequired flag + invalidating isStale cache
     //reset restartRequired flag + invalidating isStale cache
     // after start/restart command execution completed
     // after start/restart command execution completed
     sch3.setRestartRequired(false);
     sch3.setRestartRequired(false);
 
 
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
 
 
     cluster.deleteConfigGroup(id);
     cluster.deleteConfigGroup(id);
     Assert.assertNull(cluster.getConfigGroups().get(id));
     Assert.assertNull(cluster.getConfigGroups().get(id));
 
 
     sch3.updateActualConfigs(actual);
     sch3.updateActualConfigs(actual);
-    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch3.convertToResponse(null).isStaleConfig());
 
 
     tags.remove(id.toString());
     tags.remove(id.toString());
     sch3.updateActualConfigs(actual);
     sch3.updateActualConfigs(actual);
     // previous value from cache
     // previous value from cache
-    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch3.convertToResponse(null).isStaleConfig());
     //reset restartRequired flag + invalidating isStale cache
     //reset restartRequired flag + invalidating isStale cache
     // after start/restart command execution completed
     // after start/restart command execution completed
     sch3.setRestartRequired(false);
     sch3.setRestartRequired(false);
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
   }
   }
 
 
   @Test
   @Test
@@ -995,8 +995,8 @@ public class ServiceComponentHostTest {
     sch3.setState(State.INSTALLING);
     sch3.setState(State.INSTALLING);
     sch3.setStackVersion(new StackId(stackVersion));
     sch3.setStackVersion(new StackId(stackVersion));
 
 
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
 
 
     makeConfig(cluster, "global", "version1",
     makeConfig(cluster, "global", "version1",
         new HashMap<String,String>() {{
         new HashMap<String,String>() {{
@@ -1024,16 +1024,16 @@ public class ServiceComponentHostTest {
        }});
        }});
       }});
       }});
     // HDP-x/HDFS does not define type 'foo', so changes do not count to stale
     // HDP-x/HDFS does not define type 'foo', so changes do not count to stale
-    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch3.convertToResponse(null).isStaleConfig());
     actual = new HashMap<String, Map<String, String>>() {{
     actual = new HashMap<String, Map<String, String>>() {{
       put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
       put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
       put("mapred-site", new HashMap<String,String>() {{ put("tag", "version1"); }});
       put("mapred-site", new HashMap<String,String>() {{ put("tag", "version1"); }});
     }};
     }};
     sch3.setRestartRequired(false);
     sch3.setRestartRequired(false);
     sch3.updateActualConfigs(actual);
     sch3.updateActualConfigs(actual);
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
 
 
     // Now add config-attributes
     // Now add config-attributes
     Map<String, Map<String, String>> c1PropAttributes = new HashMap<String, Map<String,String>>();
     Map<String, Map<String, String>> c1PropAttributes = new HashMap<String, Map<String,String>>();
@@ -1046,9 +1046,9 @@ public class ServiceComponentHostTest {
     sch1.setRestartRequired(false);
     sch1.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch3.setRestartRequired(false);
     sch3.setRestartRequired(false);
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
 
 
     // Now change config-attributes
     // Now change config-attributes
     Map<String, Map<String, String>> c2PropAttributes = new HashMap<String, Map<String,String>>();
     Map<String, Map<String, String>> c2PropAttributes = new HashMap<String, Map<String,String>>();
@@ -1061,9 +1061,9 @@ public class ServiceComponentHostTest {
     sch1.setRestartRequired(false);
     sch1.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch3.setRestartRequired(false);
     sch3.setRestartRequired(false);
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
 
 
     // Now change config-attributes
     // Now change config-attributes
     makeConfig(cluster, "hdfs-site", "version4",
     makeConfig(cluster, "hdfs-site", "version4",
@@ -1073,9 +1073,9 @@ public class ServiceComponentHostTest {
     sch1.setRestartRequired(false);
     sch1.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch2.setRestartRequired(false);
     sch3.setRestartRequired(false);
     sch3.setRestartRequired(false);
-    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
-    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
+    Assert.assertTrue(sch1.convertToResponse(null).isStaleConfig());
+    Assert.assertTrue(sch2.convertToResponse(null).isStaleConfig());
+    Assert.assertFalse(sch3.convertToResponse(null).isStaleConfig());
   }
   }
 
 
   /**
   /**