You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2015/04/01 01:35:34 UTC

[1/2] ambari git commit: AMBARI-10207. BE: Extend stack-advisor to recommend property_value_attributes (mpapyrkovskyy via srimanth)

Repository: ambari
Updated Branches:
  refs/heads/trunk b95fe4423 -> d7fcd258d


http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/PHD/3.0.0.0/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/PHD/3.0.0.0/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/PHD/3.0.0.0/services/stack_advisor.py
index 9052509..3a2347a 100644
--- a/ambari-server/src/main/resources/stacks/PHD/3.0.0.0/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/PHD/3.0.0.0/services/stack_advisor.py
@@ -106,7 +106,7 @@ class BasePHD3000StackAdvisor(DefaultStackAdvisor):
     putMapredProperty('mapreduce.reduce.java.opts', "-Xmx" + str(int(round(0.8 * clusterData['reduceMemory']))) + "m")
     putMapredProperty('mapreduce.task.io.sort.mb', min(int(round(0.4 * clusterData['mapMemory'])), 1024))
 
-  def getConfigurationClusterSummary(self, servicesList, hosts, components):
+  def getConfigurationClusterSummary(self, servicesList, hosts, components, services):
 
     hBaseInstalled = False
     if 'HBASE' in servicesList:

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/stack_advisor.py b/ambari-server/src/main/resources/stacks/stack_advisor.py
index 42db088..c19a7ce 100644
--- a/ambari-server/src/main/resources/stacks/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/stack_advisor.py
@@ -465,7 +465,7 @@ class DefaultStackAdvisor(StackAdvisor):
   def getComponentLayoutValidations(self, services, hosts):
     return []
 
-  def getConfigurationClusterSummary(self, servicesList, hosts, components):
+  def getConfigurationClusterSummary(self, servicesList, hosts, components, services):
     pass
 
   def getConfigurationsValidationItems(self, services, hosts):
@@ -480,7 +480,7 @@ class DefaultStackAdvisor(StackAdvisor):
                   for service in services["services"]
                   for component in service["components"]]
 
-    clusterSummary = self.getConfigurationClusterSummary(servicesList, hosts, components)
+    clusterSummary = self.getConfigurationClusterSummary(servicesList, hosts, components, services)
 
     recommendations = {
       "Versions": {"stack_name": stackName, "stack_version": stackVersion},

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 051cf54..22bece8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -35,6 +35,7 @@ import java.lang.reflect.Field;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -62,6 +63,7 @@ import org.apache.ambari.server.state.AutoDeployInfo;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.CustomCommandDefinition;
 import org.apache.ambari.server.state.DependencyInfo;
 import org.apache.ambari.server.state.OperatingSystemInfo;
@@ -750,7 +752,7 @@ public class AmbariMetaInfoTest {
     PropertyInfo originalProperty = null;
 
     PropertyDependencyInfo propertyDependencyInfo =
-      new PropertyDependencyInfo("yarn-site.xml", "new-enhanced-yarn-property");
+      new PropertyDependencyInfo("yarn-site", "new-enhanced-yarn-property");
 
     for (PropertyInfo propertyInfo : redefinedService.getProperties()) {
       if (propertyInfo.getName().equals("yarn.resourcemanager.resource-tracker.address")) {
@@ -799,8 +801,8 @@ public class AmbariMetaInfoTest {
     Assert.assertEquals("some enhanced description.", newEnhancedProperty.getDescription());
     Assert.assertEquals("yarn-site.xml", newEnhancedProperty.getFilename());
     Assert.assertEquals(2, newEnhancedProperty.getDependsOnProperties().size());
-    Assert.assertTrue(newEnhancedProperty.getDependsOnProperties().contains(new PropertyDependencyInfo("yarn-site.xml", "new-yarn-property")));
-    Assert.assertTrue(newEnhancedProperty.getDependsOnProperties().contains(new PropertyDependencyInfo("global.xml", "yarn_heapsize")));
+    Assert.assertTrue(newEnhancedProperty.getDependsOnProperties().contains(new PropertyDependencyInfo("yarn-site", "new-yarn-property")));
+    Assert.assertTrue(newEnhancedProperty.getDependsOnProperties().contains(new PropertyDependencyInfo("global", "yarn_heapsize")));
     Assert.assertEquals("MB", newEnhancedProperty.getPropertyValueAttributes().getUnit());
     Assert.assertEquals("int", newEnhancedProperty.getPropertyValueAttributes().getType());
     Assert.assertEquals("512", newEnhancedProperty.getPropertyValueAttributes().getMinimum());
@@ -816,6 +818,18 @@ public class AmbariMetaInfoTest {
       originalProperty.getDescription());
     Assert.assertEquals(6, redefinedService.getConfigDependencies().size());
     Assert.assertEquals(7, redefinedService.getConfigDependenciesWithComponents().size());
+
+    // Test directed-acyclic-graph (DAG) of dependencies between configurations
+    List<PropertyDependencyInfo> changedConfigs = new LinkedList<PropertyDependencyInfo>();
+    String type = ConfigHelper.fileNameToConfigType(newProperty.getFilename());
+    String name = newProperty.getName();
+    changedConfigs.add(new PropertyDependencyInfo(type, name));
+    Set<PropertyDependencyInfo> dependedByProperties = metaInfo.getDependedByProperties(stackInfo.getName(), stackInfo.getVersion(), changedConfigs);
+    Assert.assertEquals(3, dependedByProperties.size());
+    Assert.assertTrue(dependedByProperties.contains(new PropertyDependencyInfo("yarn-site", "new-enhanced-yarn-property2")));
+    Assert.assertTrue(dependedByProperties.contains(new PropertyDependencyInfo("yarn-site", "new-enhanced-yarn-property")));
+    Assert.assertTrue(dependedByProperties.contains(new PropertyDependencyInfo("yarn-site", "new-yarn-property")));
+
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java
index 87729b1..5190dea 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java
@@ -30,9 +30,10 @@ import java.io.IOException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest.StackAdvisorRequestBuilder;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest.StackAdvisorRequestType;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetComponentLayoutRecommnedationCommand;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetComponentLayoutValidationCommand;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetConfigurationValidationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ComponentLayoutRecommendationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ComponentLayoutValidationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ConfigurationDependenciesRecommendationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ConfigurationValidationCommand;
 import org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand;
 import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
 import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse;
@@ -129,7 +130,7 @@ public class StackAdvisorHelperTest {
   }
 
   @Test
-  public void testCreateRecommendationCommand_returnsGetComponentLayoutRecommnedationCommand()
+  public void testCreateRecommendationCommand_returnsComponentLayoutRecommendationCommand()
       throws IOException, StackAdvisorException {
     Configuration configuration = mock(Configuration.class);
     StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
@@ -140,11 +141,11 @@ public class StackAdvisorHelperTest {
     StackAdvisorCommand<RecommendationResponse> command = helper
         .createRecommendationCommand(requestType);
 
-    assertEquals(GetComponentLayoutRecommnedationCommand.class, command.getClass());
+    assertEquals(ComponentLayoutRecommendationCommand.class, command.getClass());
   }
 
   @Test
-  public void testCreateValidationCommand_returnsGetComponentLayoutValidationCommand()
+  public void testCreateValidationCommand_returnsComponentLayoutValidationCommand()
       throws IOException, StackAdvisorException {
     Configuration configuration = mock(Configuration.class);
     StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
@@ -154,11 +155,11 @@ public class StackAdvisorHelperTest {
 
     StackAdvisorCommand<ValidationResponse> command = helper.createValidationCommand(requestType);
 
-    assertEquals(GetComponentLayoutValidationCommand.class, command.getClass());
+    assertEquals(ComponentLayoutValidationCommand.class, command.getClass());
   }
 
   @Test
-  public void testCreateValidationCommand_returnsGetConfigurationValidationCommand()
+  public void testCreateValidationCommand_returnsConfigurationValidationCommand()
       throws IOException, StackAdvisorException {
     Configuration configuration = mock(Configuration.class);
     StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
@@ -168,7 +169,21 @@ public class StackAdvisorHelperTest {
 
     StackAdvisorCommand<ValidationResponse> command = helper.createValidationCommand(requestType);
 
-    assertEquals(GetConfigurationValidationCommand.class, command.getClass());
+    assertEquals(ConfigurationValidationCommand.class, command.getClass());
+  }
+
+  @Test
+  public void testCreateRecommendationDependencyCommand_returnsConfigurationDependencyRecommendationCommand()
+    throws IOException, StackAdvisorException {
+    Configuration configuration = mock(Configuration.class);
+    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+    StackAdvisorHelper helper = new StackAdvisorHelper(configuration, saRunner, metaInfo);
+    StackAdvisorRequestType requestType = StackAdvisorRequestType.CONFIGURATION_DEPENDENCIES;
+
+    StackAdvisorCommand<RecommendationResponse> command = helper.createRecommendationCommand(requestType);
+
+    assertEquals(ConfigurationDependenciesRecommendationCommand.class, command.getClass());
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java
new file mode 100644
index 0000000..bc9cf77
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.stackadvisor.commands;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
+import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
+import org.junit.Test;
+
+public class ConfigurationRecommendationCommandTest {
+
+  @Test
+  public void testProcessHostGroups() throws Exception {
+    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+    File file = mock(File.class);
+    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+    ConfigurationRecommendationCommand command = new ConfigurationRecommendationCommand(file, "script", 1, saRunner, metaInfo);
+
+    StackAdvisorRequest request = mock(StackAdvisorRequest.class);
+    Map<String, Set<String>> componentHostGroupMap = new HashMap<String, Set<String>>();
+    Set<String> components1 = new HashSet<String>();
+    components1.add("component1");
+    components1.add("component4");
+    components1.add("component5");
+    componentHostGroupMap.put("group1", components1);
+    Set<String> components2 = new HashSet<String>();
+    components2.add("component2");
+    components2.add("component3");
+    componentHostGroupMap.put("group2", components2);
+    doReturn(componentHostGroupMap).when(request).getHostComponents();
+    Set<RecommendationResponse.HostGroup> hostGroups = command.processHostGroups(request);
+
+    assertNotNull(hostGroups);
+    assertEquals(2, hostGroups.size());
+    Map<String, RecommendationResponse.HostGroup> hostGroupMap =
+        new HashMap<String, RecommendationResponse.HostGroup>();
+    for (RecommendationResponse.HostGroup hostGroup : hostGroups) {
+      hostGroupMap.put(hostGroup.getName(), hostGroup);
+    }
+    RecommendationResponse.HostGroup hostGroup1 = hostGroupMap.get("group1");
+    assertNotNull(hostGroup1);
+    Set<Map<String, String>> host1Components = hostGroup1.getComponents();
+    assertNotNull(host1Components);
+    assertEquals(3, host1Components.size());
+    Set<String> componentNames1 = new HashSet<String>();
+    for (Map<String, String> host1Component : host1Components) {
+      assertNotNull(host1Component);
+      assertEquals(1, host1Component.size());
+      String componentName = host1Component.get("name");
+      assertNotNull(componentName);
+      componentNames1.add(componentName);
+    }
+    assertEquals(3, componentNames1.size());
+    assertTrue(componentNames1.contains("component1"));
+    assertTrue(componentNames1.contains("component4"));
+    assertTrue(componentNames1.contains("component5"));
+    RecommendationResponse.HostGroup hostGroup2 = hostGroupMap.get("group2");
+    assertNotNull(hostGroup2);
+    Set<Map<String, String>> host2Components = hostGroup2.getComponents();
+    assertNotNull(host2Components);
+    assertEquals(2, host2Components.size());
+    Set<String> componentNames2 = new HashSet<String>();
+    for (Map<String, String> host2Component : host2Components) {
+      assertNotNull(host2Component);
+      assertEquals(1, host2Component.size());
+      String componentName = host2Component.get("name");
+      assertNotNull(componentName);
+      componentNames2.add(componentName);
+    }
+    assertEquals(2, componentNames2.size());
+    assertTrue(componentNames2.contains("component2"));
+    assertTrue(componentNames2.contains("component3"));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommandTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommandTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommandTest.java
deleted file mode 100644
index 1bd66a4..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommandTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.api.services.stackadvisor.commands;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
-import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
-import org.junit.Test;
-
-public class GetConfigurationRecommnedationCommandTest {
-
-  @Test
-  public void testProcessHostGroups() throws Exception {
-    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
-    File file = mock(File.class);
-    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
-    GetConfigurationRecommnedationCommand command = new GetConfigurationRecommnedationCommand(file, "script", 1, saRunner, metaInfo);
-
-    StackAdvisorRequest request = mock(StackAdvisorRequest.class);
-    Map<String, Set<String>> componentHostGroupMap = new HashMap<String, Set<String>>();
-    Set<String> components1 = new HashSet<String>();
-    components1.add("component1");
-    components1.add("component4");
-    components1.add("component5");
-    componentHostGroupMap.put("group1", components1);
-    Set<String> components2 = new HashSet<String>();
-    components2.add("component2");
-    components2.add("component3");
-    componentHostGroupMap.put("group2", components2);
-    doReturn(componentHostGroupMap).when(request).getHostComponents();
-    Set<RecommendationResponse.HostGroup> hostGroups = command.processHostGroups(request);
-
-    assertNotNull(hostGroups);
-    assertEquals(2, hostGroups.size());
-    Map<String, RecommendationResponse.HostGroup> hostGroupMap =
-        new HashMap<String, RecommendationResponse.HostGroup>();
-    for (RecommendationResponse.HostGroup hostGroup : hostGroups) {
-      hostGroupMap.put(hostGroup.getName(), hostGroup);
-    }
-    RecommendationResponse.HostGroup hostGroup1 = hostGroupMap.get("group1");
-    assertNotNull(hostGroup1);
-    Set<Map<String, String>> host1Components = hostGroup1.getComponents();
-    assertNotNull(host1Components);
-    assertEquals(3, host1Components.size());
-    Set<String> componentNames1 = new HashSet<String>();
-    for (Map<String, String> host1Component : host1Components) {
-      assertNotNull(host1Component);
-      assertEquals(1, host1Component.size());
-      String componentName = host1Component.get("name");
-      assertNotNull(componentName);
-      componentNames1.add(componentName);
-    }
-    assertEquals(3, componentNames1.size());
-    assertTrue(componentNames1.contains("component1"));
-    assertTrue(componentNames1.contains("component4"));
-    assertTrue(componentNames1.contains("component5"));
-    RecommendationResponse.HostGroup hostGroup2 = hostGroupMap.get("group2");
-    assertNotNull(hostGroup2);
-    Set<Map<String, String>> host2Components = hostGroup2.getComponents();
-    assertNotNull(host2Components);
-    assertEquals(2, host2Components.size());
-    Set<String> componentNames2 = new HashSet<String>();
-    for (Map<String, String> host2Component : host2Components) {
-      assertNotNull(host2Component);
-      assertEquals(1, host2Component.size());
-      String componentName = host2Component.get("name");
-      assertNotNull(componentName);
-      componentNames2.add(componentName);
-    }
-    assertEquals(2, componentNames2.size());
-    assertTrue(componentNames2.contains("component2"));
-    assertTrue(componentNames2.contains("component3"));
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
index bae5ef8..1f5549b 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
@@ -302,7 +302,7 @@ class TestHDP206StackAdvisor(TestCase):
       "amMemory": 512
     }
 
-    result = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components)
+    result = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components, None)
 
     self.assertEquals(result, expected)
 
@@ -344,7 +344,7 @@ class TestHDP206StackAdvisor(TestCase):
       "amMemory": 3072
     }
 
-    result = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components)
+    result = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components, None)
 
     self.assertEquals(result, expected)
 
@@ -402,7 +402,7 @@ class TestHDP206StackAdvisor(TestCase):
     hosts = {
       "items" : []
     }
-    result = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components)
+    result = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components, None)
 
     expected = {
       "hBaseInstalled": False,
@@ -530,7 +530,7 @@ class TestHDP206StackAdvisor(TestCase):
       }
     }
 
-    clusterData = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components)
+    clusterData = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components, None)
     self.assertEquals(clusterData['hbaseRam'], 8)
 
     self.stackAdvisor.recommendHbaseEnvConfigurations(configurations, clusterData, None, None)

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/python/stacks/2.1/common/test_stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.1/common/test_stack_advisor.py
index 11356a2..9a6b58d 100644
--- a/ambari-server/src/test/python/stacks/2.1/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.1/common/test_stack_advisor.py
@@ -191,7 +191,7 @@ class TestHDP21StackAdvisor(TestCase):
       }
     }
 
-    clusterData = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components)
+    clusterData = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components, None)
     self.assertEquals(clusterData['hbaseRam'], 8)
 
     self.stackAdvisor.recommendHbaseEnvConfigurations(configurations, clusterData, None, None)

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
index 5fbc945..76ecc96 100644
--- a/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
@@ -644,6 +644,226 @@ class TestHDP22StackAdvisor(TestCase):
     self.stackAdvisor.recommendYARNConfigurations(configurations, clusterData, None, None)
     self.assertEquals(configurations, expected)
 
+  def test_recommendYARNConfigurationAttributes(self):
+    configurations = {
+      "yarn-env": {
+        "properties": {
+          "min_user_id": "500"
+        }
+      },
+      "yarn-site": {
+        "properties": {
+          "yarn.nodemanager.resource.memory-mb": "1280",
+          "yarn.scheduler.minimum-allocation-mb": "256",
+          "yarn.scheduler.maximum-allocation-mb": "1280",
+          "yarn.nodemanager.resource.cpu-vcores": "2"
+        },
+      }
+    }
+    clusterData = {
+      "cpu": 4,
+      "containers" : 5,
+      "ramPerContainer": 256
+    }
+    expected = {
+      "yarn-env": {
+        "properties": {
+          "min_user_id": "500"
+        }
+      },
+      "yarn-site": {
+        "properties": {
+          "yarn.nodemanager.resource.memory-mb": "1280",
+          "yarn.scheduler.minimum-allocation-mb": "256",
+          "yarn.scheduler.maximum-allocation-mb": "1280",
+          "yarn.nodemanager.resource.cpu-vcores": "2"
+        },
+        "property_attributes": {
+          'yarn.nodemanager.resource.memory-mb': {'max': '1877'},
+          'yarn.nodemanager.resource.cpu-vcores': {'max': '4'},
+          'yarn.scheduler.minimum-allocation-vcores': {'max': '2'},
+          'yarn.scheduler.maximum-allocation-vcores': {'max': '2'},
+          'yarn.scheduler.minimum-allocation-mb': {'max': '1280'},
+          'yarn.scheduler.maximum-allocation-mb': {'max': '1280'}
+        }
+      }
+    }
+    services = {
+      "services": [
+        {
+          "href": "/api/v1/stacks/HDP/versions/2.2/services/YARN",
+          "StackServices": {
+            "service_name": "YARN",
+            "service_version": "2.6.0.2.2",
+            "stack_name": "HDP",
+            "stack_version": "2.2"
+          },
+          "components": [
+            {
+              "StackServiceComponents": {
+                "advertise_version": "false",
+                "cardinality": "1",
+                "component_category": "MASTER",
+                "component_name": "APP_TIMELINE_SERVER",
+                "display_name": "App Timeline Server",
+                "is_client": "false",
+                "is_master": "true",
+                "hostnames": []
+              },
+              "dependencies": []
+            },
+            {
+              "StackServiceComponents": {
+                "advertise_version": "true",
+                "cardinality": "1+",
+                "component_category": "SLAVE",
+                "component_name": "NODEMANAGER",
+                "display_name": "NodeManager",
+                "is_client": "false",
+                "is_master": "false",
+                "hostnames": [
+                  "c6403.ambari.apache.org"
+                ]
+              },
+              "dependencies": []
+            },
+            {
+              "StackServiceComponents": {
+                "advertise_version": "true",
+                "cardinality": "1-2",
+                "component_category": "MASTER",
+                "component_name": "RESOURCEMANAGER",
+                "display_name": "ResourceManager",
+                "is_client": "false",
+                "is_master": "true",
+                "hostnames": []
+              },
+              "dependencies": []
+            },
+            {
+              "StackServiceComponents": {
+                "advertise_version": "true",
+                "cardinality": "1+",
+                "component_category": "CLIENT",
+                "component_name": "YARN_CLIENT",
+                "display_name": "YARN Client",
+                "is_client": "true",
+                "is_master": "false",
+                "hostnames": []
+              },
+              "dependencies": []
+            }
+          ]
+        },
+      ],
+      "configurations": configurations,
+      "changed-configurations": [
+        {
+          "type": "yarn-site",
+          "name": "yarn.nodemanager.resource.memory-mb"
+        },
+        {
+          "type": "yarn-site",
+          "name": "yarn.scheduler.minimum-allocation-mb"
+        },
+        {
+          "type": "yarn-site",
+          "name": "yarn.scheduler.maximum-allocation-mb"
+        },
+        {
+          "type": "yarn-site",
+          "name": "yarn.nodemanager.resource.cpu-vcores"
+        },
+        {
+          "type": "yarn-env",
+          "name": "min_user_id"
+        },
+      ],
+      "depended-configurations": [
+        {
+          "type" : "mapred-site",
+          "name" : "yarn.app.mapreduce.am.admin-command-opts"
+        }, {
+          "type" : "yarn-site",
+          "name" : "yarn.scheduler.maximum-allocation-mb"
+        }, {
+          "type" : "yarn-site",
+          "name" : "yarn.scheduler.minimum-allocation-mb"
+        }, {
+          "type" : "mapred-site",
+          "name" : "mapreduce.reduce.java.opts"
+        }, {
+          "type" : "mapred-site",
+          "name" : "mapreduce.map.java.opts"
+        }, {
+          "type" : "mapred-site",
+          "name" : "yarn.app.mapreduce.am.command-opts"
+        }, {
+          "type" : "mapred-site",
+          "name" : "yarn.app.mapreduce.am.resource.mb"
+        }, {
+          "type" : "yarn-site",
+          "name" : "yarn.nodemanager.resource.memory-mb"
+        }, {
+          "type" : "mapred-site",
+          "name" : "mapreduce.task.io.sort.mb"
+        }, {
+          "type" : "mapred-site",
+          "name" : "mapreduce.reduce.memory.mb"
+        }, {
+          "type" : "mapred-site",
+          "name" : "mapreduce.map.memory.mb"
+        }
+      ]
+
+      }
+    hosts = {
+      "items" : [
+        {
+          "href" : "/api/v1/hosts/c6401.ambari.apache.org",
+          "Hosts" : {
+            "cpu_count" : 1,
+            "host_name" : "c6401.ambari.apache.org",
+            "os_arch" : "x86_64",
+            "os_type" : "centos6",
+            "ph_cpu_count" : 1,
+            "public_host_name" : "c6401.ambari.apache.org",
+            "rack_info" : "/default-rack",
+            "total_mem" : 1922680
+          }
+        },
+        {
+          "href" : "/api/v1/hosts/c6402.ambari.apache.org",
+          "Hosts" : {
+            "cpu_count" : 1,
+            "host_name" : "c6402.ambari.apache.org",
+            "os_arch" : "x86_64",
+            "os_type" : "centos6",
+            "ph_cpu_count" : 1,
+            "public_host_name" : "c6402.ambari.apache.org",
+            "rack_info" : "/default-rack",
+            "total_mem" : 1922680
+          }
+        },
+        {
+          "href" : "/api/v1/hosts/c6403.ambari.apache.org",
+          "Hosts" : {
+            "cpu_count" : 1,
+            "host_name" : "c6403.ambari.apache.org",
+            "os_arch" : "x86_64",
+            "os_type" : "centos6",
+            "ph_cpu_count" : 1,
+            "public_host_name" : "c6403.ambari.apache.org",
+            "rack_info" : "/default-rack",
+            "total_mem" : 1922680
+          }
+        }
+      ]
+    }
+
+    self.stackAdvisor.recommendYARNConfigurations(configurations, clusterData, services, hosts)
+    self.assertEquals(configurations, expected)
+
   def test_recommendAmsConfigurations(self):
     configurations = {}
     clusterData = {}
@@ -730,7 +950,7 @@ class TestHDP22StackAdvisor(TestCase):
       }
     }
 
-    clusterData = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components)
+    clusterData = self.stackAdvisor.getConfigurationClusterSummary(servicesList, hosts, components, None)
     self.assertEquals(clusterData['hbaseRam'], 8)
 
     self.stackAdvisor.recommendHbaseEnvConfigurations(configurations, clusterData, None, None)

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/test/resources/stacks/HDP/2.0.6/services/YARN/configuration/yarn-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.6/services/YARN/configuration/yarn-site.xml b/ambari-server/src/test/resources/stacks/HDP/2.0.6/services/YARN/configuration/yarn-site.xml
index de723a3..ccad7c0 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.6/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.6/services/YARN/configuration/yarn-site.xml
@@ -69,15 +69,28 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>new-yarn-property</name>
       </property>
       <property>
-        <type>global.xml</type>
+        <type>global</type>
         <name>yarn_heapsize</name>
       </property>
     </depends-on>
   </property>
 
+  <property>
+    <name>new-enhanced-yarn-property2</name>
+    <value>1024</value>
+    <description>some enhanced description.</description>
+
+    <depends-on>
+      <property>
+        <type>yarn-site</type>
+        <name>new-enhanced-yarn-property</name>
+      </property>
+    </depends-on>
+  </property>
+
 
 </configuration>


[2/2] ambari git commit: AMBARI-10207. BE: Extend stack-advisor to recommend property_value_attributes (mpapyrkovskyy via srimanth)

Posted by sr...@apache.org.
AMBARI-10207. BE: Extend stack-advisor to recommend property_value_attributes (mpapyrkovskyy via srimanth)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d7fcd258
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d7fcd258
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d7fcd258

Branch: refs/heads/trunk
Commit: d7fcd258d9788923a03d0d121320e0d39636a2cd
Parents: b95fe44
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Tue Mar 31 16:31:37 2015 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Tue Mar 31 16:31:44 2015 -0700

----------------------------------------------------------------------
 .../server/api/services/AmbariMetaInfo.java     |  41 ++++
 .../stackadvisor/StackAdvisorHelper.java        |  20 +-
 .../stackadvisor/StackAdvisorRequest.java       |  21 +-
 .../ComponentLayoutRecommendationCommand.java   |  67 ++++++
 .../ComponentLayoutValidationCommand.java       |  63 ++++++
 ...rationDependenciesRecommendationCommand.java | 119 ++++++++++
 .../ConfigurationRecommendationCommand.java     | 113 ++++++++++
 .../ConfigurationValidationCommand.java         |  62 ++++++
 ...GetComponentLayoutRecommnedationCommand.java |  64 ------
 .../GetComponentLayoutValidationCommand.java    |  63 ------
 .../GetConfigurationRecommnedationCommand.java  | 113 ----------
 .../GetConfigurationValidationCommand.java      |  62 ------
 .../commands/StackAdvisorCommand.java           |  39 ++--
 .../commands/StackAdvisorCommandType.java       |   2 +
 .../recommendations/RecommendationResponse.java |  36 ++-
 .../internal/StackAdvisorResourceProvider.java  |  34 ++-
 .../apache/ambari/server/stack/StackModule.java |  14 +-
 .../configuration-mapred/mapred-site.xml        |  16 +-
 .../YARN/2.1.0.2.0/configuration/yarn-site.xml  |   4 +-
 .../src/main/resources/properties.json          |   1 +
 .../src/main/resources/scripts/stack_advisor.py |  50 ++++-
 .../stacks/BIGTOP/0.8/services/stack_advisor.py |   2 +-
 .../stacks/HDP/2.0.6/services/stack_advisor.py  |  58 ++++-
 .../services/YARN/configuration/yarn-site.xml   |   4 +-
 .../stacks/HDP/2.2/services/stack_advisor.py    |  28 ++-
 .../stacks/HDPWIN/2.1/services/stack_advisor.py |   2 +-
 .../PHD/3.0.0.0/services/stack_advisor.py       |   2 +-
 .../src/main/resources/stacks/stack_advisor.py  |   4 +-
 .../server/api/services/AmbariMetaInfoTest.java |  20 +-
 .../stackadvisor/StackAdvisorHelperTest.java    |  33 ++-
 .../ConfigurationRecommendationCommandTest.java | 103 +++++++++
 ...tConfigurationRecommnedationCommandTest.java | 103 ---------
 .../stacks/2.0.6/common/test_stack_advisor.py   |   8 +-
 .../stacks/2.1/common/test_stack_advisor.py     |   2 +-
 .../stacks/2.2/common/test_stack_advisor.py     | 222 ++++++++++++++++++-
 .../services/YARN/configuration/yarn-site.xml   |  17 +-
 36 files changed, 1123 insertions(+), 489 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 0cb8fa4..3a7fb6a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -59,8 +59,10 @@ import org.apache.ambari.server.stack.StackManager;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.DependencyInfo;
 import org.apache.ambari.server.state.OperatingSystemInfo;
+import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.Service;
@@ -1221,4 +1223,43 @@ public class AmbariMetaInfo {
 
     return kerberosServiceDescriptors;
   }
+
+  /**
+   * Get set of all the depended-by properties down to directed acyclic graph(DAG)
+   * of dependencies between configuration properties
+   * @param stackName the stack name
+   * @param stackVersion the stack version
+   * @param changedConfigs the list of changed configurations
+   * @return set of all depended-by properties including all changedConfigs
+   */
+  public Set<PropertyDependencyInfo> getDependedByProperties(String stackName,
+                                                             String stackVersion,
+                                                             List<PropertyDependencyInfo> changedConfigs) {
+    StackInfo stack = getStackManager().getStack(stackName, stackVersion);
+
+    if (changedConfigs == null) {
+      return Collections.emptySet();
+    }
+    int size = 0;
+    Set<PropertyDependencyInfo> configs =
+      new HashSet<PropertyDependencyInfo>();
+
+    configs.addAll(changedConfigs);
+
+    while (size != configs.size()) {
+      size = configs.size();
+      for (ServiceInfo service: stack.getServices()) {
+        for (PropertyInfo pi: service.getProperties()) {
+          String type = ConfigHelper.fileNameToConfigType(pi.getFilename());
+          String name = pi.getName();
+          PropertyDependencyInfo dep =
+            new PropertyDependencyInfo(type, name);
+          if (configs.contains(dep) && !configs.containsAll(pi.getDependedByProperties())) {
+            configs.addAll(pi.getDependedByProperties());
+          }
+        }
+      }
+    }
+    return configs;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java
index 9e683f0..a925d7d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java
@@ -23,10 +23,11 @@ import java.io.IOException;
 
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest.StackAdvisorRequestType;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetComponentLayoutRecommnedationCommand;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetComponentLayoutValidationCommand;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetConfigurationRecommnedationCommand;
-import org.apache.ambari.server.api.services.stackadvisor.commands.GetConfigurationValidationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ComponentLayoutRecommendationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ComponentLayoutValidationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ConfigurationDependenciesRecommendationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ConfigurationRecommendationCommand;
+import org.apache.ambari.server.api.services.stackadvisor.commands.ConfigurationValidationCommand;
 import org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand;
 import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
 import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse;
@@ -77,10 +78,10 @@ public class StackAdvisorHelper {
       StackAdvisorRequestType requestType) throws StackAdvisorException {
     StackAdvisorCommand<ValidationResponse> command;
     if (requestType == StackAdvisorRequestType.HOST_GROUPS) {
-      command = new GetComponentLayoutValidationCommand(recommendationsDir, stackAdvisorScript,
+      command = new ComponentLayoutValidationCommand(recommendationsDir, stackAdvisorScript,
           requestId, saRunner, metaInfo);
     } else if (requestType == StackAdvisorRequestType.CONFIGURATIONS) {
-      command = new GetConfigurationValidationCommand(recommendationsDir, stackAdvisorScript,
+      command = new ConfigurationValidationCommand(recommendationsDir, stackAdvisorScript,
           requestId, saRunner, metaInfo);
     } else {
       throw new StackAdvisorRequestException(String.format("Unsupported request type, type=%s",
@@ -112,10 +113,13 @@ public class StackAdvisorHelper {
       StackAdvisorRequestType requestType) throws StackAdvisorException {
     StackAdvisorCommand<RecommendationResponse> command;
     if (requestType == StackAdvisorRequestType.HOST_GROUPS) {
-      command = new GetComponentLayoutRecommnedationCommand(recommendationsDir, stackAdvisorScript,
+      command = new ComponentLayoutRecommendationCommand(recommendationsDir, stackAdvisorScript,
           requestId, saRunner, metaInfo);
     } else if (requestType == StackAdvisorRequestType.CONFIGURATIONS) {
-      command = new GetConfigurationRecommnedationCommand(recommendationsDir, stackAdvisorScript,
+      command = new ConfigurationRecommendationCommand(recommendationsDir, stackAdvisorScript,
+          requestId, saRunner, metaInfo);
+    } else if (requestType == StackAdvisorRequestType.CONFIGURATION_DEPENDENCIES) {
+      command = new ConfigurationDependenciesRecommendationCommand(recommendationsDir, stackAdvisorScript,
           requestId, saRunner, metaInfo);
     } else {
       throw new StackAdvisorRequestException(String.format("Unsupported request type, type=%s",

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
index 991f198..89a3570 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
@@ -21,10 +21,12 @@ package org.apache.ambari.server.api.services.stackadvisor;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.commons.lang.StringUtils;
 
 /**
@@ -41,6 +43,7 @@ public class StackAdvisorRequest {
   private Map<String, Set<String>> hostComponents = new HashMap<String, Set<String>>();
   private Map<String, Set<String>> hostGroupBindings = new HashMap<String, Set<String>>();
   private Map<String, Map<String, Map<String, String>>> configurations = new HashMap<String, Map<String, Map<String, String>>>();
+  private List<PropertyDependencyInfo> changedConfigurations = new LinkedList<PropertyDependencyInfo>();
 
   public String getStackName() {
     return stackName;
@@ -86,6 +89,14 @@ public class StackAdvisorRequest {
     return configurations;
   }
 
+  public List<PropertyDependencyInfo> getChangedConfigurations() {
+    return changedConfigurations;
+  }
+
+  public void setChangedConfigurations(List<PropertyDependencyInfo> changedConfigurations) {
+    this.changedConfigurations = changedConfigurations;
+  }
+
   private StackAdvisorRequest(String stackName, String stackVersion) {
     this.stackName = stackName;
     this.stackVersion = stackVersion;
@@ -140,13 +151,21 @@ public class StackAdvisorRequest {
       return this;
     }
 
+    public StackAdvisorRequestBuilder withChangedConfigurations(
+      List<PropertyDependencyInfo> changedConfigurations) {
+      this.instance.changedConfigurations = changedConfigurations;
+      return this;
+    }
+
     public StackAdvisorRequest build() {
       return this.instance;
     }
   }
 
   public enum StackAdvisorRequestType {
-    HOST_GROUPS("host_groups"), CONFIGURATIONS("configurations");
+    HOST_GROUPS("host_groups"),
+    CONFIGURATIONS("configurations"),
+    CONFIGURATION_DEPENDENCIES("configuration-dependencies");
 
     private String type;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java
new file mode 100644
index 0000000..0dff92b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.stackadvisor.commands;
+
+import java.io.File;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
+import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
+
+/**
+ * {@link StackAdvisorCommand} implementation for component-layout
+ * recommendation.
+ */
+public class ComponentLayoutRecommendationCommand extends
+    StackAdvisorCommand<RecommendationResponse> {
+
+  public ComponentLayoutRecommendationCommand(File recommendationsDir,
+                                              String stackAdvisorScript,
+                                              int requestId,
+                                              StackAdvisorRunner saRunner,
+                                              AmbariMetaInfo metaInfo) {
+    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
+  }
+
+  @Override
+  protected StackAdvisorCommandType getCommandType() {
+    return StackAdvisorCommandType.RECOMMEND_COMPONENT_LAYOUT;
+  }
+
+  @Override
+  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
+    if (request.getHosts() == null || request.getHosts().isEmpty()
+      || request.getServices() == null || request.getServices().isEmpty()) {
+      throw new StackAdvisorException("Hosts and services must not be empty");
+    }
+  }
+
+  @Override
+  protected RecommendationResponse updateResponse(StackAdvisorRequest request, RecommendationResponse response) {
+    return response;
+  }
+
+  @Override
+  protected String getResultFileName() {
+    return "component-layout.json";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java
new file mode 100644
index 0000000..757ebee
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.stackadvisor.commands;
+
+import java.io.File;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
+import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse;
+
+/**
+ * {@link StackAdvisorCommand} implementation for component-layout validation.
+ */
+public class ComponentLayoutValidationCommand extends StackAdvisorCommand<ValidationResponse> {
+
+  public ComponentLayoutValidationCommand(File recommendationsDir, String stackAdvisorScript,
+                                          int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
+    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
+  }
+
+  @Override
+  protected StackAdvisorCommandType getCommandType() {
+    return StackAdvisorCommandType.VALIDATE_COMPONENT_LAYOUT;
+  }
+
+  @Override
+  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
+    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
+        || request.getServices().isEmpty() || request.getComponentHostsMap() == null
+        || request.getComponentHostsMap().isEmpty()) {
+      throw new StackAdvisorException("Hosts, services and recommendations must not be empty");
+    }
+  }
+
+  @Override
+  protected ValidationResponse updateResponse(StackAdvisorRequest request, ValidationResponse response) {
+    return response;
+  }
+
+  @Override
+  protected String getResultFileName() {
+    return "component-layout-validation.json";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java
new file mode 100644
index 0000000..ae86548
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.stackadvisor.commands;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
+import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse.BindingHostGroup;
+import static org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse.HostGroup;
+
+/**
+ * {@link StackAdvisorCommand} implementation for
+ * configuration dependencies recommendation.
+ */
+public class ConfigurationDependenciesRecommendationCommand extends
+    StackAdvisorCommand<RecommendationResponse> {
+
+  public ConfigurationDependenciesRecommendationCommand(File recommendationsDir, String stackAdvisorScript, int requestId,
+                                                        StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
+    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
+  }
+
+  @Override
+  protected StackAdvisorCommandType getCommandType() {
+    return StackAdvisorCommandType.RECOMMEND_CONFIGURATION_DEPENDENCIES;
+  }
+
+  @Override
+  protected void validate(StackAdvisorRequest request)
+    throws StackAdvisorException {
+    if (request.getHosts() == null || request.getHosts().isEmpty()
+      || request.getServices() == null || request.getServices().isEmpty()
+      || request.getChangedConfigurations() == null
+      || request.getChangedConfigurations().isEmpty()) {
+      throw new StackAdvisorException("Hosts, services and changed-configurations must not be empty");
+    }
+  }
+
+  @Override
+  protected RecommendationResponse updateResponse(StackAdvisorRequest request,
+                                                  RecommendationResponse response) {
+    response.getRecommendations().getBlueprint().setHostGroups(processHostGroups(request));
+    response.getRecommendations().getBlueprintClusterBinding().setHostGroups(processHostGroupBindings(request));
+    return response;
+  }
+
+  protected Set<HostGroup> processHostGroups(StackAdvisorRequest request) {
+    Set<HostGroup> resultSet = new HashSet<HostGroup>();
+    for (Map.Entry<String, Set<String>> componentHost : request.getHostComponents().entrySet()) {
+      String hostGroupName = componentHost.getKey();
+      Set<String> components = componentHost.getValue();
+      if (hostGroupName != null && components != null) {
+        HostGroup hostGroup = new HostGroup();
+        Set<Map<String, String>> componentsSet = new HashSet<Map<String, String>>();
+        for (String component : components) {
+          Map<String, String> componentMap = new HashMap<String, String>();
+          componentMap.put("name", component);
+          componentsSet.add(componentMap);
+        }
+        hostGroup.setComponents(componentsSet);
+        hostGroup.setName(hostGroupName);
+        resultSet.add(hostGroup);
+      }
+    }
+    return resultSet;
+  }
+
+  private Set<BindingHostGroup> processHostGroupBindings(StackAdvisorRequest request) {
+    Set<BindingHostGroup> resultSet = new HashSet<BindingHostGroup>();
+    for (Map.Entry<String, Set<String>> hostBinding : request.getHostGroupBindings().entrySet()) {
+      String hostGroupName = hostBinding.getKey();
+      Set<String> hosts = hostBinding.getValue();
+      if (hostGroupName != null && hosts != null) {
+        BindingHostGroup bindingHostGroup = new BindingHostGroup();
+        Set<Map<String, String>> hostsSet = new HashSet<Map<String, String>>();
+        for (String host : hosts) {
+          Map<String, String> hostMap = new HashMap<String, String>();
+          hostMap.put("name", host);
+          hostsSet.add(hostMap);
+        }
+        bindingHostGroup.setHosts(hostsSet);
+        bindingHostGroup.setName(hostGroupName);
+        resultSet.add(bindingHostGroup);
+      }
+    }
+    return resultSet;
+  }
+
+  @Override
+  protected String getResultFileName() {
+    return "configurations.json";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java
new file mode 100644
index 0000000..ad01b40
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.stackadvisor.commands;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
+import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
+import static org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse.*;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * {@link org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand} implementation for
+ * configuration recommendation.
+ */
+public class ConfigurationRecommendationCommand extends
+    StackAdvisorCommand<RecommendationResponse> {
+
+  public ConfigurationRecommendationCommand(File recommendationsDir, String stackAdvisorScript, int requestId,
+                                            StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
+    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
+  }
+
+  @Override
+  protected StackAdvisorCommandType getCommandType() {
+    return StackAdvisorCommandType.RECOMMEND_CONFIGURATIONS;
+  }
+
+  @Override
+  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
+    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
+        || request.getServices().isEmpty()) {
+      throw new StackAdvisorException("Hosts and services must not be empty");
+    }
+  }
+
+  @Override
+  protected RecommendationResponse updateResponse(StackAdvisorRequest request, RecommendationResponse response) {
+    response.getRecommendations().getBlueprint().setHostGroups(processHostGroups(request));
+    response.getRecommendations().getBlueprintClusterBinding().setHostGroups(processHostGroupBindings(request));
+    return response;
+  }
+
+  protected Set<HostGroup> processHostGroups(StackAdvisorRequest request) {
+    Set<HostGroup> resultSet = new HashSet<HostGroup>();
+    for (Map.Entry<String, Set<String>> componentHost : request.getHostComponents().entrySet()) {
+      String hostGroupName = componentHost.getKey();
+      Set<String> components = componentHost.getValue();
+      if (hostGroupName != null && components != null) {
+        HostGroup hostGroup = new HostGroup();
+        Set<Map<String, String>> componentsSet = new HashSet<Map<String, String>>();
+        for (String component : components) {
+          Map<String, String> componentMap = new HashMap<String, String>();
+          componentMap.put("name", component);
+          componentsSet.add(componentMap);
+        }
+        hostGroup.setComponents(componentsSet);
+        hostGroup.setName(hostGroupName);
+        resultSet.add(hostGroup);
+      }
+    }
+    return resultSet;
+  }
+
+  private Set<BindingHostGroup> processHostGroupBindings(StackAdvisorRequest request) {
+    Set<BindingHostGroup> resultSet = new HashSet<BindingHostGroup>();
+    for (Map.Entry<String, Set<String>> hostBinding : request.getHostGroupBindings().entrySet()) {
+      String hostGroupName = hostBinding.getKey();
+      Set<String> hosts = hostBinding.getValue();
+      if (hostGroupName != null && hosts != null) {
+        BindingHostGroup bindingHostGroup = new BindingHostGroup();
+        Set<Map<String, String>> hostsSet = new HashSet<Map<String, String>>();
+        for (String host : hosts) {
+          Map<String, String> hostMap = new HashMap<String, String>();
+          hostMap.put("name", host);
+          hostsSet.add(hostMap);
+        }
+        bindingHostGroup.setHosts(hostsSet);
+        bindingHostGroup.setName(hostGroupName);
+        resultSet.add(bindingHostGroup);
+      }
+    }
+    return resultSet;
+  }
+
+  @Override
+  protected String getResultFileName() {
+    return "configurations.json";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java
new file mode 100644
index 0000000..c234947
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.stackadvisor.commands;
+
+import java.io.File;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
+import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
+import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse;
+
+/**
+ * {@link StackAdvisorCommand} implementation for configuration validation.
+ */
+public class ConfigurationValidationCommand extends StackAdvisorCommand<ValidationResponse> {
+
+  public ConfigurationValidationCommand(File recommendationsDir, String stackAdvisorScript,
+                                        int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
+    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
+  }
+
+  @Override
+  protected StackAdvisorCommandType getCommandType() {
+    return StackAdvisorCommandType.VALIDATE_CONFIGURATIONS;
+  }
+
+  @Override
+  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
+    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
+        || request.getServices().isEmpty()) {
+      throw new StackAdvisorException("Hosts, services and configurations must not be empty");
+    }
+  }
+
+  @Override
+  protected ValidationResponse updateResponse(StackAdvisorRequest request,
+      ValidationResponse response) {
+    return response;
+  }
+
+  @Override
+  protected String getResultFileName() {
+    return "configurations-validation.json";
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutRecommnedationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutRecommnedationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutRecommnedationCommand.java
deleted file mode 100644
index b91f912..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutRecommnedationCommand.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.api.services.stackadvisor.commands;
-
-import java.io.File;
-
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
-import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
-
-/**
- * {@link StackAdvisorCommand} implementation for component-layout
- * recommendation.
- */
-public class GetComponentLayoutRecommnedationCommand extends
-    StackAdvisorCommand<RecommendationResponse> {
-
-  public GetComponentLayoutRecommnedationCommand(File recommendationsDir,
-      String stackAdvisorScript, int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
-    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
-  }
-
-  @Override
-  protected StackAdvisorCommandType getCommandType() {
-    return StackAdvisorCommandType.RECOMMEND_COMPONENT_LAYOUT;
-  }
-
-  @Override
-  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
-    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
-        || request.getServices().isEmpty()) {
-      throw new StackAdvisorException("Hosts and services must not be empty");
-    }
-  }
-
-  @Override
-  protected RecommendationResponse updateResponse(StackAdvisorRequest request, RecommendationResponse response) {
-    return response;
-  }
-
-  @Override
-  protected String getResultFileName() {
-    return "component-layout.json";
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutValidationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutValidationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutValidationCommand.java
deleted file mode 100644
index 1a1fc98..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetComponentLayoutValidationCommand.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.api.services.stackadvisor.commands;
-
-import java.io.File;
-
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
-import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse;
-
-/**
- * {@link StackAdvisorCommand} implementation for component-layout validation.
- */
-public class GetComponentLayoutValidationCommand extends StackAdvisorCommand<ValidationResponse> {
-
-  public GetComponentLayoutValidationCommand(File recommendationsDir, String stackAdvisorScript,
-      int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
-    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
-  }
-
-  @Override
-  protected StackAdvisorCommandType getCommandType() {
-    return StackAdvisorCommandType.VALIDATE_COMPONENT_LAYOUT;
-  }
-
-  @Override
-  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
-    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
-        || request.getServices().isEmpty() || request.getComponentHostsMap() == null
-        || request.getComponentHostsMap().isEmpty()) {
-      throw new StackAdvisorException("Hosts, services and recommendations must not be empty");
-    }
-  }
-
-  @Override
-  protected ValidationResponse updateResponse(StackAdvisorRequest request, ValidationResponse response) {
-    return response;
-  }
-
-  @Override
-  protected String getResultFileName() {
-    return "component-layout-validation.json";
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommand.java
deleted file mode 100644
index b20c966..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationRecommnedationCommand.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.api.services.stackadvisor.commands;
-
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
-import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse;
-import static org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse.*;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * {@link org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand} implementation for
- * configuration recommendation.
- */
-public class GetConfigurationRecommnedationCommand extends
-    StackAdvisorCommand<RecommendationResponse> {
-
-  public GetConfigurationRecommnedationCommand(File recommendationsDir, String stackAdvisorScript, int requestId,
-                                               StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
-    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
-  }
-
-  @Override
-  protected StackAdvisorCommandType getCommandType() {
-    return StackAdvisorCommandType.RECOMMEND_CONFIGURATIONS;
-  }
-
-  @Override
-  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
-    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
-        || request.getServices().isEmpty()) {
-      throw new StackAdvisorException("Hosts and services must not be empty");
-    }
-  }
-
-  @Override
-  protected RecommendationResponse updateResponse(StackAdvisorRequest request, RecommendationResponse response) {
-    response.getRecommendations().getBlueprint().setHostGroups(processHostGroups(request));
-    response.getRecommendations().getBlueprintClusterBinding().setHostGroups(processHostGroupBindings(request));
-    return response;
-  }
-
-  protected Set<HostGroup> processHostGroups(StackAdvisorRequest request) {
-    Set<HostGroup> resultSet = new HashSet<HostGroup>();
-    for (Map.Entry<String, Set<String>> componentHost : request.getHostComponents().entrySet()) {
-      String hostGroupName = componentHost.getKey();
-      Set<String> components = componentHost.getValue();
-      if (hostGroupName != null && components != null) {
-        HostGroup hostGroup = new HostGroup();
-        Set<Map<String, String>> componentsSet = new HashSet<Map<String, String>>();
-        for (String component : components) {
-          Map<String, String> componentMap = new HashMap<String, String>();
-          componentMap.put("name", component);
-          componentsSet.add(componentMap);
-        }
-        hostGroup.setComponents(componentsSet);
-        hostGroup.setName(hostGroupName);
-        resultSet.add(hostGroup);
-      }
-    }
-    return resultSet;
-  }
-
-  private Set<BindingHostGroup> processHostGroupBindings(StackAdvisorRequest request) {
-    Set<BindingHostGroup> resultSet = new HashSet<BindingHostGroup>();
-    for (Map.Entry<String, Set<String>> hostBinding : request.getHostGroupBindings().entrySet()) {
-      String hostGroupName = hostBinding.getKey();
-      Set<String> hosts = hostBinding.getValue();
-      if (hostGroupName != null && hosts != null) {
-        BindingHostGroup bindingHostGroup = new BindingHostGroup();
-        Set<Map<String, String>> hostsSet = new HashSet<Map<String, String>>();
-        for (String host : hosts) {
-          Map<String, String> hostMap = new HashMap<String, String>();
-          hostMap.put("name", host);
-          hostsSet.add(hostMap);
-        }
-        bindingHostGroup.setHosts(hostsSet);
-        bindingHostGroup.setName(hostGroupName);
-        resultSet.add(bindingHostGroup);
-      }
-    }
-    return resultSet;
-  }
-
-  @Override
-  protected String getResultFileName() {
-    return "configurations.json";
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationValidationCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationValidationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationValidationCommand.java
deleted file mode 100644
index 36fe6cb..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/GetConfigurationValidationCommand.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.api.services.stackadvisor.commands;
-
-import java.io.File;
-
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
-import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
-import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse;
-
-/**
- * {@link StackAdvisorCommand} implementation for configuration validation.
- */
-public class GetConfigurationValidationCommand extends StackAdvisorCommand<ValidationResponse> {
-
-  public GetConfigurationValidationCommand(File recommendationsDir, String stackAdvisorScript,
-      int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
-    super(recommendationsDir, stackAdvisorScript, requestId, saRunner, metaInfo);
-  }
-
-  @Override
-  protected StackAdvisorCommandType getCommandType() {
-    return StackAdvisorCommandType.VALIDATE_CONFIGURATIONS;
-  }
-
-  @Override
-  protected void validate(StackAdvisorRequest request) throws StackAdvisorException {
-    if (request.getHosts() == null || request.getHosts().isEmpty() || request.getServices() == null
-        || request.getServices().isEmpty()) {
-      throw new StackAdvisorException("Hosts, services and configurations must not be empty");
-    }
-  }
-
-  @Override
-  protected ValidationResponse updateResponse(StackAdvisorRequest request,
-      ValidationResponse response) {
-    return response;
-  }
-
-  @Override
-  protected String getResultFileName() {
-    return "configurations-validation.json";
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
index 2e20452..a7646a0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
@@ -44,6 +44,7 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorResponse;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.logging.Log;
@@ -75,12 +76,14 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
       + ",services/StackServices/service_name,services/StackServices/service_version"
       + ",services/components/StackServiceComponents,services/components/dependencies,services/components/auto_deploy"
       + "&services/StackServices/service_name.in(%s)";
-  private static final String SERVICES_PROPETRY = "services";
-  private static final String SERVICES_COMPONENTS_PROPETRY = "components";
-  private static final String COMPONENT_INFO_PROPETRY = "StackServiceComponents";
+  private static final String SERVICES_PROPERTY = "services";
+  private static final String SERVICES_COMPONENTS_PROPERTY = "components";
+  private static final String COMPONENT_INFO_PROPERTY = "StackServiceComponents";
   private static final String COMPONENT_NAME_PROPERTY = "component_name";
-  private static final String COMPONENT_HOSTNAMES_PROPETRY = "hostnames";
-  private static final String CONFIGURATIONS_PROPETRY = "configurations";
+  private static final String COMPONENT_HOSTNAMES_PROPERTY = "hostnames";
+  private static final String CONFIGURATIONS_PROPERTY = "configurations";
+  private static final String CHANGED_CONFIGURATIONS_PROPERTY = "changed-configurations";
+  private static final String DEPENDED_CONFIGURATIONS_PROPERTY = "depended-configurations";
 
   private File recommendationsDir;
   private String stackAdvisorScript;
@@ -140,8 +143,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
 
       populateStackHierarchy(root);
       populateComponentHostsMap(root, request.getComponentHostsMap());
-      populateConfigurations(root, request.getConfigurations());
-
+      populateConfigurations(root, request);
       data.servicesJSON = mapper.writeValueAsString(root);
     } catch (Exception e) {
       // should not happen
@@ -154,8 +156,10 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
   }
 
   private void populateConfigurations(ObjectNode root,
-      Map<String, Map<String, Map<String, String>>> configurations) {
-    ObjectNode configurationsNode = root.putObject(CONFIGURATIONS_PROPETRY);
+                                      StackAdvisorRequest request) {
+    Map<String, Map<String, Map<String, String>>> configurations =
+      request.getConfigurations();
+    ObjectNode configurationsNode = root.putObject(CONFIGURATIONS_PROPERTY);
     for (String siteName : configurations.keySet()) {
       ObjectNode siteNode = configurationsNode.putObject(siteName);
 
@@ -170,6 +174,15 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
         }
       }
     }
+    // Populating changed configs info and depended by configs info
+    Set<PropertyDependencyInfo> dependedProperties =
+      metaInfo.getDependedByProperties(request.getStackName(),
+      request.getStackVersion(), request.getChangedConfigurations());
+
+    JsonNode changedConfigs = mapper.valueToTree(request.getChangedConfigurations());
+    JsonNode dependendConfigs = mapper.valueToTree(dependedProperties);
+    root.put(CHANGED_CONFIGURATIONS_PROPERTY, changedConfigs);
+    root.put(DEPENDED_CONFIGURATIONS_PROPERTY, dependendConfigs);
   }
 
   protected void populateStackHierarchy(ObjectNode root) {
@@ -185,21 +198,21 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
   }
 
   private void populateComponentHostsMap(ObjectNode root, Map<String, Set<String>> componentHostsMap) {
-    ArrayNode services = (ArrayNode) root.get(SERVICES_PROPETRY);
+    ArrayNode services = (ArrayNode) root.get(SERVICES_PROPERTY);
     Iterator<JsonNode> servicesIter = services.getElements();
 
     while (servicesIter.hasNext()) {
       JsonNode service = servicesIter.next();
-      ArrayNode components = (ArrayNode) service.get(SERVICES_COMPONENTS_PROPETRY);
+      ArrayNode components = (ArrayNode) service.get(SERVICES_COMPONENTS_PROPERTY);
       Iterator<JsonNode> componentsIter = components.getElements();
 
       while (componentsIter.hasNext()) {
         JsonNode component = componentsIter.next();
-        ObjectNode componentInfo = (ObjectNode) component.get(COMPONENT_INFO_PROPETRY);
+        ObjectNode componentInfo = (ObjectNode) component.get(COMPONENT_INFO_PROPERTY);
         String componentName = componentInfo.get(COMPONENT_NAME_PROPERTY).getTextValue();
 
         Set<String> componentHosts = componentHostsMap.get(componentName);
-        ArrayNode hostnames = componentInfo.putArray(COMPONENT_HOSTNAMES_PROPETRY);
+        ArrayNode hostnames = componentInfo.putArray(COMPONENT_HOSTNAMES_PROPERTY);
         if (null != componentHosts) {
           for (String hostName : componentHosts) {
             hostnames.add(hostName);

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandType.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandType.java
index 380b81d..5aa1ea9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandType.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandType.java
@@ -29,6 +29,8 @@ public enum StackAdvisorCommandType {
 
   RECOMMEND_CONFIGURATIONS("recommend-configurations"),
 
+  RECOMMEND_CONFIGURATION_DEPENDENCIES("recommend-configuration-dependencies"),
+
   VALIDATE_CONFIGURATIONS("validate-configurations");
 
   private final String name;

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/recommendations/RecommendationResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/recommendations/RecommendationResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/recommendations/RecommendationResponse.java
index 1796f9a..b81320d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/recommendations/RecommendationResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/recommendations/RecommendationResponse.java
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorResponse;
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
  * Recommendation response POJO.
@@ -88,16 +89,16 @@ public class RecommendationResponse extends StackAdvisorResponse {
 
   public static class Blueprint {
     @JsonProperty
-    private Map<String, Map<String, Map<String, String>>> configurations;
+    private Map<String, BlueprintConfigurations> configurations;
 
     @JsonProperty("host_groups")
     private Set<HostGroup> hostGroups;
 
-    public Map<String, Map<String, Map<String, String>>> getConfigurations() {
+    public Map<String, BlueprintConfigurations> getConfigurations() {
       return configurations;
     }
 
-    public void setConfigurations(Map<String, Map<String, Map<String, String>>> configurations) {
+    public void setConfigurations(Map<String, BlueprintConfigurations> configurations) {
       this.configurations = configurations;
     }
 
@@ -110,6 +111,35 @@ public class RecommendationResponse extends StackAdvisorResponse {
     }
   }
 
+  public static class BlueprintConfigurations {
+    @JsonProperty
+    private Map<String, String> properties;
+
+    @JsonProperty("property_attributes")
+    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+    private Map<String, Map<String, String>> propertyAttributes;
+
+    public BlueprintConfigurations() {
+      System.out.println(this);
+    }
+
+    public Map<String, String> getProperties() {
+      return properties;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+      this.properties = properties;
+    }
+
+    public Map<String, Map<String, String>> getPropertyAttributes() {
+      return propertyAttributes;
+    }
+
+    public void setPropertyAttributes(Map<String, Map<String, String>> propertyAttributes) {
+      this.propertyAttributes = propertyAttributes;
+    }
+  }
+
   public static class HostGroup {
     @JsonProperty
     private String name;

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java
index 6ae557d..620251b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java
@@ -18,8 +18,10 @@
 
 package org.apache.ambari.server.controller.internal;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -38,6 +40,7 @@ import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 import com.google.inject.Inject;
+import org.apache.ambari.server.state.PropertyDependencyInfo;
 
 /**
  * Abstract superclass for recommendations and validations.
@@ -52,6 +55,8 @@ public abstract class StackAdvisorResourceProvider extends ReadOnlyResourceProvi
   private static final String HOST_PROPERTY = "hosts";
   private static final String SERVICES_PROPERTY = "services";
 
+  private static final String CHANGED_CONFIGURATIONS_PROPERTY = "changed_configurations";
+
   private static final String BLUEPRINT_HOST_GROUPS_PROPERTY = "recommendations/blueprint/host_groups";
   private static final String BINDING_HOST_GROUPS_PROPERTY = "recommendations/blueprint_cluster_binding/host_groups";
 
@@ -99,12 +104,17 @@ public abstract class StackAdvisorResourceProvider extends ReadOnlyResourceProvi
           hgHostsMap);
       Map<String, Map<String, Map<String, String>>> configurations = calculateConfigurations(request);
 
-      StackAdvisorRequest saRequest = StackAdvisorRequestBuilder.forStack(stackName, stackVersion)
-          .ofType(requestType).forHosts(hosts).forServices(services)
-          .forHostComponents(hgComponentsMap).forHostsGroupBindings(hgHostsMap)
-          .withComponentHostsMap(componentHostsMap).withConfigurations(configurations).build();
-
-      return saRequest;
+      List<PropertyDependencyInfo> changedConfigurations =
+        requestType == StackAdvisorRequestType.CONFIGURATION_DEPENDENCIES ?
+          calculateChangedConfigurations(request) : Collections.<PropertyDependencyInfo>emptyList();
+
+      return StackAdvisorRequestBuilder.
+        forStack(stackName, stackVersion).ofType(requestType).forHosts(hosts).
+        forServices(services).forHostComponents(hgComponentsMap).
+        forHostsGroupBindings(hgHostsMap).
+        withComponentHostsMap(componentHostsMap).
+        withConfigurations(configurations).
+        withChangedConfigurations(changedConfigurations).build();
     } catch (Exception e) {
       LOG.warn("Error occured during preparation of stack advisor request", e);
       Response response = Response.status(Status.BAD_REQUEST)
@@ -176,6 +186,18 @@ public abstract class StackAdvisorResourceProvider extends ReadOnlyResourceProvi
     return map;
   }
 
+  protected List<PropertyDependencyInfo> calculateChangedConfigurations(Request request) {
+    List<PropertyDependencyInfo> configs =
+      new LinkedList<PropertyDependencyInfo>();
+    HashSet<HashMap<String, String>> changedConfigs =
+      (HashSet<HashMap<String, String>>) getRequestProperty(request, CHANGED_CONFIGURATIONS_PROPERTY);
+    for (HashMap<String, String> props: changedConfigs) {
+      configs.add(new PropertyDependencyInfo(props.get("type"), props.get("name")));
+    }
+
+    return configs;
+  }
+
   protected static final String CONFIGURATIONS_PROPERTY_ID = "recommendations/blueprint/configurations/";
 
   protected Map<String, Map<String, Map<String, String>>> calculateConfigurations(Request request) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index 0b27ae5..4b88aff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -29,6 +29,7 @@ import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.RepositoryInfo;
@@ -597,11 +598,15 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
     for (ServiceModule serviceModule : serviceModules.values()) {
       for (PropertyInfo pi : serviceModule.getModuleInfo().getProperties()) {
         for (PropertyDependencyInfo pdi : pi.getDependsOnProperties()) {
-          PropertyDependencyInfo propertyDependency = new PropertyDependencyInfo(pi.getFilename(), pi.getName());
+          String type = ConfigHelper.fileNameToConfigType(pi.getFilename());
+          String name = pi.getName();
+          PropertyDependencyInfo propertyDependency =
+            new PropertyDependencyInfo(type, name);
           if (dependedByMap.keySet().contains(pdi)) {
             dependedByMap.get(pdi).add(propertyDependency);
           } else {
-            Set<PropertyDependencyInfo> newDependenciesSet = new HashSet<PropertyDependencyInfo>();
+            Set<PropertyDependencyInfo> newDependenciesSet =
+              new HashSet<PropertyDependencyInfo>();
             newDependenciesSet.add(propertyDependency);
             dependedByMap.put(pdi, newDependenciesSet);
           }
@@ -612,7 +617,10 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
     // Go through all service-configs again and set their 'depended-by' if necessary.
     for (ServiceModule serviceModule : serviceModules.values()) {
       for (PropertyInfo pi : serviceModule.getModuleInfo().getProperties()) {
-        Set<PropertyDependencyInfo> set = dependedByMap.remove(new PropertyDependencyInfo(pi.getFilename(), pi.getName()));
+        String type = ConfigHelper.fileNameToConfigType(pi.getFilename());
+        String name = pi.getName();
+        Set<PropertyDependencyInfo> set =
+          dependedByMap.remove(new PropertyDependencyInfo(type, name));
         if (set != null) {
           pi.getDependedByProperties().addAll(set);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
index a99a132..bf20d6e 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
@@ -41,7 +41,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>mapred-site.xml</type>
+        <type>mapred-site</type>
         <name>mapreduce.map.memory.mb</name>
       </property>
     </depends-on>
@@ -186,7 +186,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.scheduler.maximum-allocation-mb</name>
       </property>
     </depends-on>
@@ -206,7 +206,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.scheduler.maximum-allocation-mb</name>
       </property>
     </depends-on>
@@ -281,7 +281,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.scheduler.maximum-allocation-mb</name>
       </property>
     </depends-on>
@@ -306,7 +306,7 @@
     <display-name>MR AppMaster Java Heap Size</display-name>
     <depends-on>
       <property>
-        <type>mapred-site.xml</type>
+        <type>mapred-site</type>
         <name>yarn.app.mapreduce.am.resource.mb</name>
       </property>
     </depends-on>
@@ -328,7 +328,7 @@
     <display-name>MR AppMaster Java Heap Size</display-name>
     <depends-on>
       <property>
-        <type>mapred-site.xml</type>
+        <type>mapred-site</type>
         <name>yarn.app.mapreduce.am.resource.mb</name>
       </property>
     </depends-on>
@@ -383,7 +383,7 @@
     <display-name>MR Map Java Heap Size</display-name>
     <depends-on>
       <property>
-        <type>mapred-site.xml</type>
+        <type>mapred-site</type>
         <name>mapreduce.map.memory.mb</name>
       </property>
     </depends-on>
@@ -399,7 +399,7 @@
     <display-name>MR Reduce Java Heap Size</display-name>
     <depends-on>
       <property>
-        <type>mapred-site.xml</type>
+        <type>mapred-site</type>
         <name>mapreduce.reduce.memory.mb</name>
       </property>
     </depends-on>

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
index e6407ef..e71dfc9 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
@@ -80,7 +80,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.nodemanager.resource.memory-mb</name>
       </property>
     </depends-on>
@@ -104,7 +104,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.nodemanager.resource.memory-mb</name>
       </property>
     </depends-on>

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index b230cb7..94374bc 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -376,6 +376,7 @@
         "recommend",
         "hosts",
         "services",
+        "changed_configurations",
         "recommendations",
         "recommendations/blueprint",
         "recommendations/blueprint/configurations",

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/scripts/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/scripts/stack_advisor.py b/ambari-server/src/main/resources/scripts/stack_advisor.py
index 60f87f9..1d67872 100755
--- a/ambari-server/src/main/resources/scripts/stack_advisor.py
+++ b/ambari-server/src/main/resources/scripts/stack_advisor.py
@@ -26,9 +26,14 @@ import traceback
 RECOMMEND_COMPONENT_LAYOUT_ACTION = 'recommend-component-layout'
 VALIDATE_COMPONENT_LAYOUT_ACTION = 'validate-component-layout'
 RECOMMEND_CONFIGURATIONS = 'recommend-configurations'
+RECOMMEND_CONFIGURATION_DEPENDENCIES = 'recommend-configuration-dependencies'
 VALIDATE_CONFIGURATIONS = 'validate-configurations'
 
-ALL_ACTIONS = [ RECOMMEND_COMPONENT_LAYOUT_ACTION, VALIDATE_COMPONENT_LAYOUT_ACTION, RECOMMEND_CONFIGURATIONS, VALIDATE_CONFIGURATIONS ]
+ALL_ACTIONS = [RECOMMEND_COMPONENT_LAYOUT_ACTION,
+               VALIDATE_COMPONENT_LAYOUT_ACTION,
+               RECOMMEND_CONFIGURATIONS,
+               RECOMMEND_CONFIGURATION_DEPENDENCIES,
+               VALIDATE_CONFIGURATIONS]
 USAGE = "Usage: <action> <hosts_file> <services_file>\nPossible actions are: {0}\n".format( str(ALL_ACTIONS) )
 
 SCRIPT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
@@ -101,6 +106,10 @@ def main(argv=None):
   elif action == RECOMMEND_CONFIGURATIONS:
     result = stackAdvisor.recommendConfigurations(services, hosts)
     result_file = os.path.join(actionDir, "configurations.json")
+  elif action == RECOMMEND_CONFIGURATION_DEPENDENCIES:
+    result = stackAdvisor.recommendConfigurations(services, hosts)
+    result_file = os.path.join(actionDir, "configurations.json")
+    result = filterResult(result, services)
   else: # action == VALIDATE_CONFIGURATIONS
     result = stackAdvisor.validateConfigurations(services, hosts)
     result_file = os.path.join(actionDir, "configurations-validation.json")
@@ -108,6 +117,45 @@ def main(argv=None):
   dumpJson(result, result_file)
   pass
 
+# returns recommendations only for changed and depended properties
+def filterResult(result, services):
+  allRequestedProperties = getAllRequestedProperties(services)
+
+  configs = result['recommendations']['blueprint']['configurations']
+  filteredConfigs = {}
+  for type, names in configs.items():
+    for name in names['properties']:
+      if type in allRequestedProperties.keys() and \
+              name in allRequestedProperties[type]:
+        if type not in filteredConfigs.keys():
+          filteredConfigs[type] = {'properties': {}}
+        filteredConfigs[type]['properties'][name] = \
+          configs[type]['properties'][name]
+    if 'property_attributes' in names.keys():
+      for name in names['property_attributes']:
+        if type in allRequestedProperties.keys() and \
+                name in allRequestedProperties[type]:
+          if type not in filteredConfigs.keys():
+            filteredConfigs[type] = {'property_Attributes': {}}
+          elif 'property_attributes' not in filteredConfigs[type].keys():
+            filteredConfigs[type]['property_attributes'] = {}
+          filteredConfigs[type]['property_attributes'][name] = \
+            configs[type]['property_attributes'][name]
+
+  result['recommendations']['blueprint']['configurations'] = filteredConfigs
+  return result
+
+def getAllRequestedProperties(services):
+  changedConfigs = []
+  changedConfigs.extend(services['changed-configurations'])
+  changedConfigs.extend(services['depended-configurations'])
+  allRequestedProperties = {}
+  for config in changedConfigs:
+    if config['type'] in allRequestedProperties:
+      allRequestedProperties[config['type']].append(config['name'])
+    else:
+      allRequestedProperties[config['type']] = [config['name']]
+  return allRequestedProperties
 
 def instantiateStackAdvisor(stackName, stackVersion, parentVersions):
   """Instantiates StackAdvisor implementation for the specified Stack"""

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/stack_advisor.py
index 853a732..53591cd 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/stack_advisor.py
@@ -105,7 +105,7 @@ class BaseBIGTOP08StackAdvisor(DefaultStackAdvisor):
     putMapredProperty('mapreduce.reduce.java.opts', "-Xmx" + str(int(round(0.8 * clusterData['reduceMemory']))) + "m")
     putMapredProperty('mapreduce.task.io.sort.mb', min(int(round(0.4 * clusterData['mapMemory'])), 1024))
 
-  def getConfigurationClusterSummary(self, servicesList, hosts, components):
+  def getConfigurationClusterSummary(self, servicesList, hosts, components, services):
 
     hBaseInstalled = False
     if 'HBASE' in servicesList:

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
index c9ded5e..2405954 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
@@ -88,23 +88,48 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
       "AMBARI_METRICS": self.recommendAmsConfigurations
     }
 
-  def putProperty(self, config, configType):
-    if configType not in config or "properties" not in config[configType]:
-      config[configType] = {"properties": {}}
+  def putProperty(self, config, configType, services=None):
+    userConfigs = {}
+    changedConfigs = []
+    # if services parameter, prefer values, set by user
+    if services:
+      if 'configurations' in services.keys():
+        userConfigs = services['configurations']
+      if 'changed-configurations' in services.keys():
+        changedConfigs = services["changed-configurations"]
+
+    if configType not in config:
+      config[configType] = {}
+    if"properties" not in config[configType]:
+      config[configType]["properties"] = {}
     def appendProperty(key, value):
-      config[configType]["properties"][key] = str(value)
+      if {'type': configType, 'name': key} in changedConfigs:
+        config[configType]["properties"][key] = userConfigs[configType]['properties'][key]
+      else:
+        config[configType]["properties"][key] = str(value)
     return appendProperty
 
+  def putPropertyAttribute(self, config, configType):
+    if configType not in config:
+      config[configType] = {}
+    def appendPropertyAttribute(key, attribute, attributeValue):
+      if"property_attributes" not in config[configType]:
+        config[configType]["property_attributes"] = {}
+      if key not in config[configType]["property_attributes"]:
+        config[configType]["property_attributes"][key] = {}
+      config[configType]["property_attributes"][key][attribute] = str(attributeValue)
+    return appendPropertyAttribute
+
   def recommendYARNConfigurations(self, configurations, clusterData, services, hosts):
-    putYarnProperty = self.putProperty(configurations, "yarn-site")
-    putYarnEnvProperty = self.putProperty(configurations, "yarn-env")
+    putYarnProperty = self.putProperty(configurations, "yarn-site", services)
+    putYarnEnvProperty = self.putProperty(configurations, "yarn-env", services)
     putYarnProperty('yarn.nodemanager.resource.memory-mb', int(round(clusterData['containers'] * clusterData['ramPerContainer'])))
     putYarnProperty('yarn.scheduler.minimum-allocation-mb', int(clusterData['ramPerContainer']))
     putYarnProperty('yarn.scheduler.maximum-allocation-mb', int(round(clusterData['containers'] * clusterData['ramPerContainer'])))
     putYarnEnvProperty('min_user_id', self.get_system_min_uid())
 
   def recommendMapReduce2Configurations(self, configurations, clusterData, services, hosts):
-    putMapredProperty = self.putProperty(configurations, "mapred-site")
+    putMapredProperty = self.putProperty(configurations, "mapred-site", services)
     putMapredProperty('yarn.app.mapreduce.am.resource.mb', int(clusterData['amMemory']))
     putMapredProperty('yarn.app.mapreduce.am.command-opts', "-Xmx" + str(int(round(0.8 * clusterData['amMemory']))) + "m")
     putMapredProperty('mapreduce.map.memory.mb', clusterData['mapMemory'])
@@ -184,7 +209,18 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
 
 
 
-  def getConfigurationClusterSummary(self, servicesList, hosts, components):
+  def getHostWithComponent(self, serviceName, componentName, services, hosts):
+    if services is not None and hosts is not None:
+      service = [serviceEntry for serviceEntry in services["services"] if serviceEntry["StackServices"]["service_name"] == serviceName][0]
+      components = [componentEntry for componentEntry in service["components"] if componentEntry["StackServiceComponents"]["component_name"] == "NODEMANAGER"]
+      if (len(components) > 0 and len(components[0]["StackServiceComponents"]["hostnames"]) > 0):
+        # NodeManager available - determine hosts and memory
+        componentHostname = components[0]["StackServiceComponents"]["hostnames"][0]
+        componentHosts = [host for host in hosts["items"] if host["Hosts"]["host_name"] == componentHostname]
+        if (componentHosts is not None and len(componentHosts) > 0):
+          return componentHosts[0]
+
+  def getConfigurationClusterSummary(self, servicesList, hosts, components, services):
 
     hBaseInstalled = False
     if 'HBASE' in servicesList:
@@ -199,7 +235,11 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
     }
 
     if len(hosts["items"]) > 0:
-      host = hosts["items"][0]["Hosts"]
+      nodeManagerHost = self.getHostWithComponent("YARN", "NODEMANAGER", services, hosts)
+      if nodeManagerHost is not None:
+        host = nodeManagerHost["Hosts"]
+      else:
+        host = hosts["items"][0]["Hosts"]
       cluster["cpu"] = host["cpu_count"]
       cluster["disk"] = len(host["disk_info"])
       cluster["ram"] = int(host["total_mem"] / (1024 * 1024))

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
index 826f458..9137bdb 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
@@ -349,7 +349,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.nodemanager.resource.cpu-vcores</name>
       </property>
     </depends-on>
@@ -367,7 +367,7 @@
     </value-attributes>
     <depends-on>
       <property>
-        <type>yarn-site.xml</type>
+        <type>yarn-site</type>
         <name>yarn.nodemanager.resource.cpu-vcores</name>
       </property>
     </depends-on>

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
index b8ddc49..87748d2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
@@ -38,8 +38,19 @@ class HDP22StackAdvisor(HDP21StackAdvisor):
 
   def recommendYARNConfigurations(self, configurations, clusterData, services, hosts):
     super(HDP22StackAdvisor, self).recommendYARNConfigurations(configurations, clusterData, services, hosts)
-    putYarnProperty = self.putProperty(configurations, "yarn-site")
+    putYarnProperty = self.putProperty(configurations, "yarn-site", services)
     putYarnProperty('yarn.nodemanager.resource.cpu-vcores', clusterData['cpu'])
+    # Property Attributes
+    putYarnPropertyAttribute = self.putPropertyAttribute(configurations, "yarn-site")
+    nodeManagerHost = self.getHostWithComponent("YARN", "NODEMANAGER", services, hosts)
+    if (nodeManagerHost is not None):
+      putYarnProperty('yarn.nodemanager.resource.cpu-vcores', nodeManagerHost["Hosts"]["cpu_count"] * 2)
+      putYarnPropertyAttribute('yarn.nodemanager.resource.memory-mb', 'max', int(nodeManagerHost["Hosts"]["total_mem"] / 1024)) # total_mem in kb
+      putYarnPropertyAttribute('yarn.nodemanager.resource.cpu-vcores', 'max', nodeManagerHost["Hosts"]["cpu_count"] * 4)
+      putYarnPropertyAttribute('yarn.scheduler.minimum-allocation-vcores', 'max', configurations["yarn-site"]["properties"]["yarn.nodemanager.resource.cpu-vcores"])
+      putYarnPropertyAttribute('yarn.scheduler.maximum-allocation-vcores', 'max', configurations["yarn-site"]["properties"]["yarn.nodemanager.resource.cpu-vcores"])
+      putYarnPropertyAttribute('yarn.scheduler.minimum-allocation-mb', 'max', configurations["yarn-site"]["properties"]["yarn.nodemanager.resource.memory-mb"])
+      putYarnPropertyAttribute('yarn.scheduler.maximum-allocation-mb', 'max', configurations["yarn-site"]["properties"]["yarn.nodemanager.resource.memory-mb"])
 
   def recommendHDFSConfigurations(self, configurations, clusterData, services, hosts):
     putHdfsProperty = self.putProperty(configurations, "hdfs-site")
@@ -156,14 +167,25 @@ class HDP22StackAdvisor(HDP21StackAdvisor):
     return self.toConfigurationValidationProblems(validationItems, "tez-site")
 
   def recommendMapReduce2Configurations(self, configurations, clusterData, services, hosts):
-    putMapredProperty = self.putProperty(configurations, "mapred-site")
+    self.recommendYARNConfigurations(configurations, clusterData, services, hosts)
+    putMapredProperty = self.putProperty(configurations, "mapred-site", services)
     putMapredProperty('yarn.app.mapreduce.am.resource.mb', int(clusterData['amMemory']))
     putMapredProperty('yarn.app.mapreduce.am.command-opts', "-Xmx" + str(int(round(0.8 * clusterData['amMemory']))) + "m" + " -Dhdp.version=${hdp.version}")
-    putMapredProperty('mapreduce.map.memory.mb', clusterData['mapMemory'])
+    putMapredProperty('mapreduce.map.memory.mb', configurations["yarn-site"]["properties"]["yarn.scheduler.minimum-allocation-mb"])
     putMapredProperty('mapreduce.reduce.memory.mb', int(clusterData['reduceMemory']))
     putMapredProperty('mapreduce.map.java.opts', "-Xmx" + str(int(round(0.8 * clusterData['mapMemory']))) + "m")
     putMapredProperty('mapreduce.reduce.java.opts', "-Xmx" + str(int(round(0.8 * clusterData['reduceMemory']))) + "m")
     putMapredProperty('mapreduce.task.io.sort.mb', min(int(round(0.4 * clusterData['mapMemory'])), 1024))
+    # Property Attributes
+    putMapredPropertyAttribute = self.putPropertyAttribute(configurations, "mapred-site")
+    yarnMinAllocationSize = int(clusterData['ramPerContainer'])
+    yarnMaxAllocationSize = max(30 * int(clusterData['ramPerContainer']), configurations["yarn-site"]["properties"]["yarn.scheduler.maximum-allocation-mb"])
+    putMapredPropertyAttribute("mapreduce.map.memory.mb", "max", yarnMaxAllocationSize)
+    putMapredPropertyAttribute("mapreduce.map.memory.mb", "min", yarnMinAllocationSize)
+    putMapredPropertyAttribute("mapreduce.reduce.memory.mb", "max", yarnMaxAllocationSize)
+    putMapredPropertyAttribute("mapreduce.reduce.memory.mb", "min", yarnMinAllocationSize)
+    putMapredPropertyAttribute("yarn.app.mapreduce.am.resource.mb", "max", yarnMaxAllocationSize)
+    putMapredPropertyAttribute("yarn.app.mapreduce.am.resource.mb", "min", yarnMinAllocationSize)
 
   def validateMapReduce2Configurations(self, properties, recommendedDefaults, configurations, services, hosts):
     validationItems = [ {"config-name": 'mapreduce.map.java.opts', "item": self.validateXmxValue(properties, recommendedDefaults, 'mapreduce.map.java.opts')},

http://git-wip-us.apache.org/repos/asf/ambari/blob/d7fcd258/ambari-server/src/main/resources/stacks/HDPWIN/2.1/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDPWIN/2.1/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDPWIN/2.1/services/stack_advisor.py
index cf35e47..3353af1 100644
--- a/ambari-server/src/main/resources/stacks/HDPWIN/2.1/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDPWIN/2.1/services/stack_advisor.py
@@ -133,7 +133,7 @@ class HDPWIN21StackAdvisor(DefaultStackAdvisor):
                    "-server -Xmx" + str(int(0.8 * clusterData["amMemory"]))
                    + "m -Djava.net.preferIPv4Stack=true -XX:+UseNUMA -XX:+UseParallelGC")
 
-  def getConfigurationClusterSummary(self, servicesList, hosts, components):
+  def getConfigurationClusterSummary(self, servicesList, hosts, components, services):
 
     hBaseInstalled = False
     if 'HBASE' in servicesList: