You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2013/03/28 20:48:35 UTC

svn commit: r1462273 - in /incubator/ambari/trunk: ./ ambari-agent/src/main/python/ambari_agent/ ambari-agent/src/test/python/ ambari-server/src/main/java/org/apache/ambari/server/agent/ ambari-server/src/main/java/org/apache/ambari/server/controller/ ...

Author: ncole
Date: Thu Mar 28 19:48:35 2013
New Revision: 1462273

URL: http://svn.apache.org/r1462273
Log:
AMBARI-1704. Add ability for host components to report actual configs from agent

Added:
    incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActualConfigHandler.py
    incubator/ambari/trunk/ambari-agent/src/test/python/TestActualConfigHandler.py
Modified:
    incubator/ambari/trunk/CHANGES.txt
    incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
    incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/LiveStatus.py
    incubator/ambari/trunk/ambari-agent/src/test/python/TestActionQueue.py
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
    incubator/ambari/trunk/ambari-server/src/main/resources/properties.json
    incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
    incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
    incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java

Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Thu Mar 28 19:48:35 2013
@@ -35,6 +35,8 @@ Trunk (unreleased changes):
 
  AMBARI-1658. Implement API/Service Provider for HDFS mirroring. (tbeerbower)
 
+ AMBARI-1704. Add ability for host components to provide their current actual configs. (ncole)
+
  AMBARI-1422. Allow client to specify a "context" value for asynchronous requests (jspeidel)
 
  AMBARI-1599. Add ability to report actual configuration applied to a host. (ncole)

Modified: incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActionQueue.py?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActionQueue.py (original)
+++ incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActionQueue.py Thu Mar 28 19:48:35 2013
@@ -38,6 +38,7 @@ import UpgradeExecutor
 import PythonExecutor
 import tempfile
 from Grep import Grep
+from ActualConfigHandler import ActualConfigHandler
 
 logger = logging.getLogger()
 installScriptHash = -1
@@ -127,6 +128,7 @@ class ActionQueue(threading.Thread):
             logger.debug(pprint.pformat(result))
             if result is not None:
               self.resultQueue.put((ActionQueue.STATUS_COMMAND, result))
+
           except Exception, err:
             traceback.print_exc()
             logger.warn(err)
@@ -231,8 +233,15 @@ class ActionQueue(threading.Thread):
       roleResult['stderr'] = 'None'
 
     # let ambari know that configuration tags were applied
-    if status == "COMPLETED" and command.has_key('configurationTags'):
-      roleResult['configurationTags'] = command['configurationTags']
+    if status == 'COMPLETED':
+      configHandler = ActualConfigHandler(self.config)
+      if command.has_key('configurationTags'):
+        configHandler.write_actual(command['configurationTags'])
+        roleResult['configurationTags'] = command['configurationTags']
+
+      if command.has_key('roleCommand') and command['roleCommand'] == 'START':
+        configHandler.copy_to_component(command['role'])
+        roleResult['configurationTags'] = configHandler.read_actual_component(command['role'])
 
     result.append(roleResult)
     return result

Added: incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActualConfigHandler.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActualConfigHandler.py?rev=1462273&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActualConfigHandler.py (added)
+++ incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/ActualConfigHandler.py Thu Mar 28 19:48:35 2013
@@ -0,0 +1,71 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+import json
+import logging
+import os
+import shutil
+
+logger = logging.getLogger()
+
+class ActualConfigHandler:
+  CONFIG_NAME = 'config.json'
+
+  def __init__(self, config):
+    self.config = config;
+
+  def findRunDir(self):
+    runDir = '/var/run/ambari-agent'
+    if self.config.has_option('agent', 'prefix'):
+      runDir = self.config.get('agent', 'prefix')
+    if not os.path.exists(runDir):
+      runDir = '/tmp'
+    return runDir
+
+  def write_actual(self, configTags):
+    runDir = self.findRunDir()
+    conf_file = open(os.path.join(runDir, self.CONFIG_NAME), 'w')
+    json.dump(configTags, conf_file)
+    conf_file.close()
+
+  def copy_to_component(self, componentName):
+    runDir = self.findRunDir()
+    srcfile = os.path.join(runDir, self.CONFIG_NAME)
+    if os.path.isfile(srcfile):
+      dstfile = os.path.join(runDir, componentName + "_" + self.CONFIG_NAME)
+      shutil.copy(srcfile, dstfile)
+
+  def read_file(self, filename):
+    runDir = self.findRunDir()
+    fullname = os.path.join(runDir, filename)
+    if os.path.isfile(fullname):
+      conf_file = open(os.path.join(runDir, filename), 'r')
+      res = json.load(conf_file)
+      conf_file.close()
+      return res
+    return None
+
+  def read_actual(self):
+    return self.read_file(self.CONFIG_NAME)
+
+  def read_actual_component(self, componentName):
+    return self.read_file(componentName + "_" + self.CONFIG_NAME)
+    
+

Modified: incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/LiveStatus.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/LiveStatus.py?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/LiveStatus.py (original)
+++ incubator/ambari/trunk/ambari-agent/src/main/python/ambari_agent/LiveStatus.py Thu Mar 28 19:48:35 2013
@@ -27,6 +27,7 @@ import time
 import traceback
 from pprint import pprint, pformat
 from StackVersionsFileHandler import StackVersionsFileHandler
+from ActualConfigHandler import ActualConfigHandler
 
 logger = logging.getLogger()
 
@@ -99,7 +100,7 @@ class LiveStatus:
     self.globalConfig = globalConfig
     versionsFileDir = config.get('agent', 'prefix')
     self.versionsHandler = StackVersionsFileHandler(versionsFileDir)
-
+    self.actualConfigHandler = ActualConfigHandler(config)
 
   def belongsToService(self, component):
     #TODO: Should also check belonging of server to cluster
@@ -123,7 +124,10 @@ class LiveStatus:
                        "serviceName" : self.service,
                        "stackVersion": self.versionsHandler.
                                     read_stack_version(component["componentName"])
-        }
+                    }
+        active_config = self.actualConfigHandler.read_actual_component(component['componentName'])
+        if not active_config is None:
+          livestatus['configurationTags'] = active_config
         break
     logger.debug("The live status for component " + str(self.component) +\
                 " of service " + str(self.service) + " is " + str(livestatus))

Modified: incubator/ambari/trunk/ambari-agent/src/test/python/TestActionQueue.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-agent/src/test/python/TestActionQueue.py?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-agent/src/test/python/TestActionQueue.py (original)
+++ incubator/ambari/trunk/ambari-agent/src/test/python/TestActionQueue.py Thu Mar 28 19:48:35 2013
@@ -111,7 +111,6 @@ class TestActionQueue(TestCase):
     executor_started_event = threading.Event()
     end_executor_event = threading.Event()
     actionQueue.puppetExecutor = FakeExecutor(executor_started_event, end_executor_event)
-    # before_start_result = actionQueue.result()
 
     command = {
       'commandId': 17,
@@ -134,12 +133,13 @@ class TestActionQueue(TestCase):
     actionQueue.start()
     executor_started_event.wait()
 
-
     end_executor_event.set()
     actionQueue.stop()
     actionQueue.join()
     after_start_result = actionQueue.result()
 
+    configname = os.path.join(tmpfile, 'config.json')
+
     self.assertEquals(len(after_start_result['componentStatus']), 0)
     self.assertEquals(len(after_start_result['reports']), 1)
     self.assertEquals(after_start_result['reports'][0]['status'], "COMPLETED")
@@ -147,6 +147,9 @@ class TestActionQueue(TestCase):
     self.assertEquals(after_start_result['reports'][0]['exitCode'], 0)
     self.assertEquals(after_start_result['reports'][0]['stderr'], 'returned stderr')
     self.assertEquals(len(after_start_result['reports'][0]['configurationTags']), 1)
+    self.assertEquals(True, os.path.isfile(configname))
+
+    os.remove(configname)
 
   @patch.object(ActionQueue, "executeCommand")
   @patch.object(ActionQueue, "stopped")

Added: incubator/ambari/trunk/ambari-agent/src/test/python/TestActualConfigHandler.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-agent/src/test/python/TestActualConfigHandler.py?rev=1462273&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-agent/src/test/python/TestActualConfigHandler.py (added)
+++ incubator/ambari/trunk/ambari-agent/src/test/python/TestActualConfigHandler.py Thu Mar 28 19:48:35 2013
@@ -0,0 +1,64 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+from unittest import TestCase
+from ambari_agent.AmbariConfig import AmbariConfig
+from ambari_agent.ActualConfigHandler import ActualConfigHandler
+import os
+import logging
+import json
+
+class TestActualConfigHandler(TestCase):
+
+  logger = logging.getLogger()
+
+  def test_read_write(self):
+    config = AmbariConfig().getConfig()
+    config.set('agent', 'prefix', "/tmp")
+    handler = ActualConfigHandler(config)
+    
+    tags = { "global": "version1", "core-site": "version2" }
+    handler.write_actual(tags)
+    output = handler.read_actual()
+    self.assertEquals(tags, output)
+
+  def test_read_write_component(self):
+    config = AmbariConfig().getConfig()
+    config.set('agent', 'prefix', "/tmp")
+    handler = ActualConfigHandler(config)
+
+    tags1 = { "global": "version1", "core-site": "version2" }
+    handler.write_actual(tags1)
+    handler.copy_to_component('FOO')
+
+    output1 = handler.read_actual_component('FOO')
+    output2 = handler.read_actual_component('GOO') 
+
+    self.assertEquals(tags1, output1)
+    self.assertEquals(None, output2)
+    
+    tags2 = { "global": "version1", "core-site": "version2" }
+    handler.write_actual(tags2)
+
+    output3 = handler.read_actual()
+    output4 = handler.read_actual_component('FOO')
+    self.assertEquals(tags2, output3)
+    self.assertEquals(tags1, output4)
+

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/CommandReport.java Thu Mar 28 19:48:35 2013
@@ -51,7 +51,7 @@ public class CommandReport {
     this.clusterName = clusterName;
   }
   
-  @JsonProperty("clusterName") 
+  @JsonProperty("clusterName")
   public String getClusterName() {
     return this.clusterName;
   }
@@ -127,7 +127,7 @@ public class CommandReport {
   }
 
   /**
-  * @param tags the config tags that match this command
+   * @param tags the config tags that match this command
    */
   public void setConfigTags(Map<String, Map<String,String>> tags) {
     configurationTags = tags;

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/ComponentStatus.java Thu Mar 28 19:48:35 2013
@@ -17,6 +17,8 @@
  */
 package org.apache.ambari.server.agent;
 
+import java.util.Map;
+
 
 
 public class ComponentStatus {
@@ -26,6 +28,7 @@ public class ComponentStatus {
   String serviceName;
   String clusterName;
   String stackVersion;
+  private Map<String, Map<String, String>> configurationTags;
 
   public String getComponentName() {
     return this.componentName;
@@ -82,6 +85,21 @@ public class ComponentStatus {
   public void setClusterName(String clusterName) {
     this.clusterName = clusterName;
   }
+  
+  /**
+   * @param tags the config tags that match this status
+   */
+  public void setConfigTags(Map<String, Map<String,String>> tags) {
+    configurationTags = tags;
+  }
+  
+  /**
+   * @return the config tags that match this command, or <code>null</code>
+   * if none are present
+   */
+  public Map<String, Map<String,String>> getConfigTags() {
+    return configurationTags;
+  }
 
   @Override
   public String toString() {

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java Thu Mar 28 19:48:35 2013
@@ -85,7 +85,7 @@ public class HeartBeatHandler {
     injector.injectMembers(this);
   }
 
-  public void start() {     
+  public void start() {
     heartbeatMonitor.start();
   }
 
@@ -140,7 +140,7 @@ public class HeartBeatHandler {
             && hostObject.getState().equals(HostState.WAITING_FOR_HOST_STATUS_UPDATES)) {
       try {
         LOG.debug("Got component status updates");
-        hostObject.handleEvent(new HostStatusUpdatesReceivedEvent(hostname, now));   
+        hostObject.handleEvent(new HostStatusUpdatesReceivedEvent(hostname, now));
       } catch (InvalidStateTransitionException e) {
         LOG.warn("Failed to notify the host about component status updates", e);
       }
@@ -152,7 +152,7 @@ public class HeartBeatHandler {
             heartbeat.getAgentEnv()));
       } else {
         hostObject.handleEvent(new HostUnhealthyHeartbeatEvent(hostname, now,
-            null));       
+            null));
       }
       if(hostState != hostObject.getState()) scanner.updateHBaseMaster(hostObject);
     } catch (InvalidStateTransitionException ex) {
@@ -198,11 +198,16 @@ public class HeartBeatHandler {
           ServiceComponentHost scHost = svcComp.getServiceComponentHost(hostname);
           String schName = scHost.getServiceComponentName();
           State state = scHost.getState();
+          
           if (report.getStatus().equals("COMPLETED")) {
             // Updating stack version, if needed
             if (scHost.getState().equals(State.UPGRADING)) {
               scHost.setStackVersion(scHost.getDesiredStackVersion());
             }
+            else if (scHost.getState().equals(State.STARTING) && null != report.getConfigTags()) {
+              scHost.updateActualConfigs(report.getConfigTags());
+            }
+            
             scHost.handleEvent(new ServiceComponentHostOpSucceededEvent(schName,
                     hostname, now));
           } else if (report.getStatus().equals("FAILED")) {
@@ -266,8 +271,11 @@ public class HeartBeatHandler {
               if (null != status.getStackVersion() && !status.getStackVersion().isEmpty()) {
                 scHost.setStackVersion(gson.fromJson(status.getStackVersion(), StackId.class));
               }
+              
+              if (null != status.getConfigTags()) {
+                scHost.updateActualConfigs(status.getConfigTags());
+              }
 
-              // TODO need to get config version and stack version from live state
             } else {
               // TODO: What should be done otherwise?
             }

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceComponentHostResponse.java Thu Mar 28 19:48:35 2013
@@ -20,6 +20,8 @@ package org.apache.ambari.server.control
 
 import java.util.Map;
 
+import org.apache.ambari.server.state.DesiredConfig;
+
 public class ServiceComponentHostResponse {
 
   private String clusterName; // REF
@@ -34,6 +36,9 @@ public class ServiceComponentHostRespons
   private Map<String, String> configs;
 
   private Map<String, String> desiredConfigs;
+  
+  // type -> desired config
+  private Map<String, DesiredConfig> actualConfigs;
 
   private String liveState;
 
@@ -252,4 +257,18 @@ public class ServiceComponentHostRespons
     return desiredConfigs;
   }
 
+  /**
+   * @param actualConfigs the actual configs
+   */
+  public void setActualConfigs(Map<String, DesiredConfig> configs) {
+    actualConfigs = configs;
+  }
+  
+  /**
+   * @return the actual configs
+   */
+  public Map<String, DesiredConfig> getActualConfigs() {
+    return actualConfigs;
+  }
+
 }

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java Thu Mar 28 19:48:35 2013
@@ -26,6 +26,7 @@ import org.apache.ambari.server.controll
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -62,6 +63,23 @@ class HostComponentResourceProvider exte
       = PropertyHelper.getPropertyId("HostRoles", "stack_id");
   protected static final String HOST_COMPONENT_DESIRED_STACK_ID_PROPERTY_ID
       = PropertyHelper.getPropertyId("HostRoles", "desired_stack_id");
+  protected static final String HOST_COMPONENT_ACTUAL_CONFIGS_PROPERTY_ID
+    = PropertyHelper.getPropertyId("HostRoles", "actual_configs");
+  
+  //Component name mappings
+  private static final Map<String, PropertyProvider> HOST_COMPONENT_PROPERTIES_PROVIDER = new HashMap<String, PropertyProvider>();
+  
+  private static final int HOST_COMPONENT_HTTP_PROPERTY_REQUEST_TIMEOUT = 1500;
+  
+  static {
+    HOST_COMPONENT_PROPERTIES_PROVIDER.put(
+        "NAGIOS_SERVER",
+        new HttpProxyPropertyProvider(new URLStreamProvider(
+            HOST_COMPONENT_HTTP_PROPERTY_REQUEST_TIMEOUT), PropertyHelper
+            .getPropertyId("HostRoles", "cluster_name"), PropertyHelper
+            .getPropertyId("HostRoles", "host_name"), PropertyHelper
+            .getPropertyId("HostRoles", "component_name")));
+  }
 
   //Parameters from the predicate
   private static final String QUERY_PARAMETERS_RUN_SMOKE_TEST_ID =
@@ -158,6 +176,17 @@ class HostComponentResourceProvider exte
           response.getConfigs(), requestedIds);
       setResourceProperty(resource, HOST_COMPONENT_DESIRED_CONFIGS_PROPERTY_ID,
           response.getDesiredConfigs(), requestedIds);
+      setResourceProperty(resource, HOST_COMPONENT_ACTUAL_CONFIGS_PROPERTY_ID,
+          response.getActualConfigs(), requestedIds);
+      
+      String componentName = (String)resource.getPropertyValue(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+      PropertyProvider propertyProvider = HOST_COMPONENT_PROPERTIES_PROVIDER.get(componentName);
+      if (propertyProvider != null) {
+        Set<Resource> resourcesToPopulate = new HashSet<Resource>();
+        resourcesToPopulate.add(resource);
+        propertyProvider.populateResources(resourcesToPopulate, request, predicate);
+      }
+      
       resources.add(resource);
     }
     return resources;

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java Thu Mar 28 19:48:35 2013
@@ -108,4 +108,17 @@ public interface ServiceComponentHost {
   public boolean canBeRemoved();
 
   public void delete() throws AmbariException;
+
+  /**
+   * Updates the tags that have been recognized by a START action.
+   * @param configTags
+   */
+  public void updateActualConfigs(Map<String, Map<String, String>> configTags);
+  
+  /**
+   * Gets the actual config tags, if known.
+   * @return the actual config map
+   */
+  public Map<String, DesiredConfig> getActualConfigs();
+  
 }

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java Thu Mar 28 19:48:35 2013
@@ -41,16 +41,8 @@ import org.apache.ambari.server.orm.enti
 import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntityPK;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import org.apache.ambari.server.state.ServiceComponentHostEventType;
-import org.apache.ambari.server.state.StackId;
-import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.state.DesiredConfig.HostOverride;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.apache.ambari.server.state.fsm.SingleArcTransition;
 import org.apache.ambari.server.state.fsm.StateMachine;
@@ -108,6 +100,7 @@ public class ServiceComponentHostImpl im
   private long lastOpEndTime;
   private long lastOpLastUpdateTime;
   private String ha_status = "passive";
+  private Map<String, DesiredConfig> actualConfigs = new HashMap<String, DesiredConfig>();
 
   private static final StateMachineFactory
   <ServiceComponentHostImpl, State,
@@ -1136,7 +1129,9 @@ public class ServiceComponentHostImpl im
           getStackVersion().getStackId(),
           getDesiredState().toString(),
           getDesiredStackVersion().getStackId());
-          r.setHa_status(ha_status);
+      
+      r.setHa_status(ha_status);
+      r.setActualConfigs(actualConfigs);
       return r;
     }
     finally {
@@ -1310,5 +1305,34 @@ public class ServiceComponentHostImpl im
 
     hostComponentDesiredStateDAO.removeByPK(desiredPK);
   }
+  
+  @Override
+  public void updateActualConfigs(Map<String, Map<String, String>> configTags) {
+    actualConfigs = new HashMap<String, DesiredConfig>();
+    
+    String hostName = getHostName();
+    
+    for (Entry<String, Map<String,String>> entry : configTags.entrySet()) {
+      String type = entry.getKey();
+      Map<String, String> values = entry.getValue();
+      
+      String tag = values.get("tag");
+      String hostTag = values.get("host_override_tag");
+      
+      DesiredConfig dc = new DesiredConfig();
+      dc.setVersion(tag);
+      actualConfigs.put(type, dc);
+      if (null != hostTag && null != hostName) {
+        List<HostOverride> list = new ArrayList<HostOverride>();
+        list.add (new HostOverride(hostName, hostTag));
+        dc.setHostOverrides(list);
+      }
+    }
+  }
+  
+  @Override
+  public Map<String, DesiredConfig> getActualConfigs() {
+    return actualConfigs;
+  }
 
 }

Modified: incubator/ambari/trunk/ambari-server/src/main/resources/properties.json
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/resources/properties.json?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/resources/properties.json (original)
+++ incubator/ambari/trunk/ambari-server/src/main/resources/properties.json Thu Mar 28 19:48:35 2013
@@ -63,6 +63,7 @@
         "HostRoles/desired_configs",
         "HostRoles/stack_id",
         "HostRoles/desired_stack_id",
+        "HostRoles/actual_configs",
         "params/run_smoke_test",
         "_"
     ],

Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java Thu Mar 28 19:48:35 2013
@@ -217,7 +217,7 @@ public class TestHeartbeatHandler {
     // the heartbeat test passed if actual configs is populated
     Assert.assertNotNull(cluster.getActualConfigs());
     Assert.assertEquals(cluster.getActualConfigs().size(), 1);
-  }  
+  }
 
   @Test
   public void testStatusHeartbeat() throws Exception {
@@ -373,6 +373,12 @@ public class TestHeartbeatHandler {
     cr.setStdErr("");
     cr.setStdOut("");
     cr.setExitCode(215);
+    
+    cr.setConfigTags(new HashMap<String, Map<String,String>>() {{
+        put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
+      }});
+    
+    
     reports.add(cr);
     am.processTaskResponse(DummyHostname1, reports);
     assertEquals(215,

Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java Thu Mar 28 19:48:35 2013
@@ -1911,6 +1911,11 @@ public class AmbariManagementControllerT
     sch1.setStackVersion(new StackId("HDP-0.1"));
 
     sch1.persist();
+    
+    sch1.updateActualConfigs(new HashMap<String, Map<String,String>>() {{
+      put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
+    }});
+    
 
     ServiceComponentHostRequest r =
         new ServiceComponentHostRequest(c1.getClusterName(),
@@ -1931,6 +1936,8 @@ public class AmbariManagementControllerT
         resp.getLiveState());
     Assert.assertEquals(sch1.getStackVersion().getStackId(),
         resp.getStackVersion());
+    Assert.assertNotNull(resp.getActualConfigs());
+    Assert.assertEquals(1, resp.getActualConfigs().size());
 
   }
 

Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java?rev=1462273&r1=1462272&r2=1462273&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java Thu Mar 28 19:48:35 2013
@@ -255,7 +255,7 @@ public class ServiceComponentHostTest {
       startTime = timestamp;
     // We need to allow install on a install.
       Assert.assertTrue("Exception not thrown on invalid event", !exceptionThrown);
-    } 
+    }
     else {
       Assert.assertTrue("Exception not thrown on invalid event", exceptionThrown);
     }
@@ -468,7 +468,33 @@ public class ServiceComponentHostTest {
     Assert.assertEquals("HDP-1.1.0",
         sch.getDesiredStackVersion().getStackId());
   }
-
+  
+  @Test
+  public void testActualConfigs() throws Exception {
+    ServiceComponentHost sch =
+        createNewServiceComponentHost("HDFS", "NAMENODE", "h1", false);
+    sch.setDesiredState(State.INSTALLED);
+    sch.setState(State.INSTALLING);
+    sch.setStackVersion(new StackId("HDP-1.0.0"));
+    sch.setDesiredStackVersion(new StackId("HDP-1.1.0"));
+    
+    Map<String, Map<String,String>> actual =
+        new HashMap<String, Map<String, String>>() {{
+          put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
+          put("core-site", new HashMap<String,String>() {{ put("tag", "version1"); put ("host_override_tag", "version2"); }});
+        }};
+        
+    sch.updateActualConfigs(actual);
+    
+    Map<String, DesiredConfig> confirm = sch.getActualConfigs();
+    
+    Assert.assertEquals(2, confirm.size());
+    Assert.assertTrue(confirm.containsKey("global"));
+    Assert.assertTrue(confirm.containsKey("core-site"));
+    Assert.assertEquals(1, confirm.get("core-site").getHostOverrides().size());
+    Assert.assertEquals("h1", confirm.get("core-site").getHostOverrides().get(0).getName());
+  }
+  
   @Test
   public void testConvertToResponse() throws AmbariException {
     ServiceComponentHost sch =