You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ja...@apache.org on 2016/03/22 18:49:45 UTC

[2/2] ambari git commit: AMBARI-15503. Hive interactive component should be created/deleted when interactive query is enabled/disabled. (jaimin)

AMBARI-15503. Hive interactive component should be created/deleted when interactive query is enabled/disabled. (jaimin)


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

Branch: refs/heads/trunk
Commit: da7f00c4432d3299be8895243a867af7a5fcb57f
Parents: 6b933cc
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Tue Mar 22 10:49:20 2016 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Tue Mar 22 10:49:20 2016 -0700

----------------------------------------------------------------------
 .../stacks/HDP/2.6/role_command_order.json      |  10 +
 .../HIVE/configuration/hive-interactive-env.xml | 131 ++++
 .../configuration/hive-interactive-site.xml     | 301 +++++++--
 .../services/HIVE/configuration/llap-env.xml    |  72 --
 .../stacks/HDP/2.6/services/HIVE/metainfo.xml   |   2 +-
 .../HDP/2.6/services/HIVE/themes/theme.json     |  76 ---
 .../services/HIVE/themes/theme_version_2.json   | 666 +++++++++++++++++++
 .../controllers/main/service/info/configs.js    |  20 +-
 .../wizard/step7/assign_master_controller.js    | 222 +++++--
 .../app/controllers/wizard/step7_controller.js  |  52 +-
 ambari-web/app/mappers/configs/themes_mapper.js |   6 +
 ambari-web/app/messages.js                      |   6 +-
 ambari-web/app/mixins.js                        |   1 +
 .../app/mixins/common/configs/configs_saver.js  |  30 +-
 .../configs/component_actions_by_configs.js     | 277 ++++++++
 .../mixins/wizard/assign_master_components.js   |  46 +-
 .../app/models/configs/theme/config_action.js   |  35 +-
 .../common/assign_master_components.hbs         |   2 +-
 .../configs/widgets/label_config_widget.hbs     |  24 +
 ambari-web/app/utils/ajax/ajax.js               |  22 +
 ambari-web/app/utils/configs/theme/theme.js     |   2 +-
 ambari-web/app/views.js                         |   1 +
 .../common/assign_master_components_view.js     |   2 +
 .../configs/service_config_layout_tab_view.js   |   8 +
 .../configs/widgets/config_widget_view.js       |  65 +-
 .../configs/widgets/label_config_widget_view.js |  38 ++
 .../widgets/time_interval_spinner_view.js       |   2 +-
 .../views/wizard/step7/assign_master_view.js    |  18 +
 .../test/controllers/wizard/step5_test.js       |  71 +-
 .../wizard/assign_master_components_test.js     |   6 +-
 30 files changed, 1864 insertions(+), 350 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json b/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json
new file mode 100644
index 0000000..613a076
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json
@@ -0,0 +1,10 @@
+{
+  "_comment" : "Record format:",
+  "_comment" : "blockedRole-blockedCommand: [blockerRole1-blockerCommand1, blockerRole2-blockerCommand2, ...]",
+  "general_deps" : {
+  "_comment" : "dependencies for all cases",
+    "HIVE_SERVER_INTERACTIVE-START": ["NODEMANAGER-START", "MYSQL_SERVER-START"],
+    "HIVE_SERVER_INTERACTIVE-RESTART": ["NODEMANAGER-RESTART", "MYSQL_SERVER-RESTART"],
+    "HIVE_SERVICE_CHECK-SERVICE_CHECK": ["HIVE_SERVER-START", "HIVE_METASTORE-START", "WEBHCAT_SERVER-START", "HIVE_SERVER_INTERACTIVE-START"]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml
new file mode 100644
index 0000000..d518c8b
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<configuration supports_adding_forbidden="true">
+  <property>
+    <name>enable_hive_interactive</name>
+    <value>false</value>
+    <description>Enable or disable interactive query in this cluster.</description>
+    <display-name>Enable Interactive Query</display-name>
+    <value-attributes>
+      <type>value-list</type>
+      <overridable>false</overridable>
+      <entries>
+        <entry>
+          <value>true</value>
+          <label>Yes</label>
+        </entry>
+        <entry>
+          <value>false</value>
+          <label>No</label>
+        </entry>
+      </entries>
+      <selection-cardinality>1</selection-cardinality>
+    </value-attributes>
+  </property>
+  <property>
+    <name>hive_server_interactive_host</name>
+    <value>localhost</value>
+    <description>HiveServer2 Interactive Host</description>
+    <display-name>HiveServer2 Interactive Host</display-name>
+    <value-attributes>
+      <overridable>false</overridable>
+    </value-attributes>
+  </property>
+  <property>
+    <name>llap_queue_capacity</name>
+    <value>0</value>
+    <description>Percentage of the cluster dedicated to interactive query.</description>
+    <display-name>% of Cluster Capacity</display-name>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+      <maximum>100</maximum>
+      <increment-step>1</increment-step>
+    </value-attributes>
+  </property>
+  <property>
+    <name>num_llap_nodes</name>
+    <value>1</value>
+    <description>The number of Hive LLAP daemons to run.</description>
+    <display-name>Number of Daemon Instances</display-name>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+      <maximum>8</maximum>
+      <increment-step>1</increment-step>
+    </value-attributes>
+  </property>
+
+  <!-- hive-env.sh -->
+  <property>
+    <name>content</name>
+    <description>This is the jinja template for hive-env.sh file</description>
+    <value>
+      if [ "$SERVICE" = "cli" ]; then
+      if [ -z "$DEBUG" ]; then
+      export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:+UseParNewGC -XX:-UseGCOverheadLimit"
+      else
+      export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:-UseGCOverheadLimit"
+      fi
+      fi
+
+      # The heap size of the jvm stared by hive shell script can be controlled via:
+
+      if [ "$SERVICE" = "metastore" ]; then
+      export HADOOP_HEAPSIZE={{hive_metastore_heapsize}} # Setting for HiveMetastore
+      else
+      export HADOOP_HEAPSIZE={{hive_heapsize}} # Setting for HiveServer2 and Client
+      fi
+
+      export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS  -Xmx${HADOOP_HEAPSIZE}m"
+
+      # Larger heap size may be required when running queries over large number of files or partitions.
+      # By default hive shell scripts use a heap size of 256 (MB).  Larger heap size would also be
+      # appropriate for hive server (hwi etc).
+
+
+      # Set HADOOP_HOME to point to a specific hadoop install directory
+      HADOOP_HOME=${HADOOP_HOME:-{{hadoop_home}}}
+
+      # Hive Configuration Directory can be controlled by:
+      export HIVE_CONF_DIR={{hive_server_interactive_conf_dir}}
+
+      # Folder containing extra ibraries required for hive compilation/execution can be controlled by:
+      # if [ "${HIVE_AUX_JARS_PATH}" != "" ]; then
+      # export HIVE_AUX_JARS_PATH=${HIVE_AUX_JARS_PATH}
+      # elif [ -d "/usr/lib/hive-hcatalog/" ]; then
+      # export HIVE_AUX_JARS_PATH=/usr/lib/hive-hcatalog/share/hcatalog/hive-hcatalog-core-*.jar
+      # else
+      # export HIVE_AUX_JARS_PATH=/usr/lib/hcatalog/share/hcatalog/hcatalog-core.jar
+      # fi
+      export METASTORE_PORT={{hive_metastore_port}}
+
+      export HADOOP_CLASSPATH={{atlas_conf_dir}}:{{atlas_home_dir}}/hook/hive:${HADOOP_CLASSPATH}
+
+    </value>
+    <value-attributes>
+      <type>content</type>
+    </value-attributes>
+  </property>
+
+</configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
index fb55d2d..face571 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
@@ -74,7 +74,7 @@ limitations under the License.
     </description>
   </property>
 
- <property>
+  <property>
     <name>hive.heapsize</name>
     <value>1024</value>
     <display-name>HiveServer2 heap size</display-name>
@@ -201,8 +201,11 @@ limitations under the License.
 
   <property>
     <name>hive.metastore.uris</name>
-    <value>thrift://localhost:9083</value>
+    <value></value>
     <description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description>
+    <value-attributes>
+      <empty-value-valid>true</empty-value-valid>
+    </value-attributes>
   </property>
 
   <property>
@@ -363,7 +366,7 @@ limitations under the License.
 
   <property>
     <name>hive.server2.enable.doAs</name>
-    <value>true</value>
+    <value>false</value>
     <description>
       Setting this property to true will have HiveServer2 execute
       Hive operations as the user making the calls to it.
@@ -441,13 +444,6 @@ limitations under the License.
   </property>
 
   <property>
-    <name>hive.server2.enable.impersonation</name>
-    <value>true</value>
-    <deleted>true</deleted>
-    <description>Enable user impersonation for HiveServer2</description>
-  </property>
-
-  <property>
     <name>fs.hdfs.impl.disable.cache</name>
     <value>true</value>
     <description>Disable HDFS filesystem cache.</description>
@@ -523,39 +519,6 @@ limitations under the License.
   </property>
 
   <property>
-    <name>hive.enforce.bucketing</name>
-    <value>true</value>
-    <description>Whether bucketing is enforced. If true, while inserting into the table, bucketing is enforced.</description>
-    <display-name>Enforce bucketing</display-name>
-    <value-attributes>
-      <type>value-list</type>
-      <entries>
-        <entry>
-          <value>true</value>
-          <label>True</label>
-        </entry>
-        <entry>
-          <value>false</value>
-          <label>False</label>
-        </entry>
-      </entries>
-      <selection-cardinality>1</selection-cardinality>
-    </value-attributes>
-    <depends-on>
-      <property>
-        <type>hive-env</type>
-        <name>hive_txn_acid</name>
-      </property>
-    </depends-on>
-  </property>
-
-  <property>
-    <name>hive.enforce.sorting</name>
-    <value>true</value>
-    <description>Whether sorting is enforced. If true, while inserting into the table, sorting is enforced.</description>
-  </property>
-
-  <property>
     <name>hive.enforce.sortmergebucketmapjoin</name>
     <value>true</value>
     <description>If the user asked for sort-merge bucketed map-side join, and it cannot be performed, should the query fail or not ?</description>
@@ -1143,6 +1106,7 @@ limitations under the License.
   </property>
 
   <property>
+    <!-- This is different for Hive batch and interactive -->
     <name>hive.prewarm.enabled</name>
     <value>false</value>
     <description>Enables container prewarm for Tez (Hadoop 2 only)</description>
@@ -1261,7 +1225,7 @@ limitations under the License.
       <selection-cardinality>1</selection-cardinality>
     </value-attributes>
     <depends-on>
-       <property>
+      <property>
         <type>hive-site</type>
         <name>hive.cbo.enable</name>
       </property>
@@ -1270,12 +1234,12 @@ limitations under the License.
 
   <property>
     <name>hive.tez.container.size</name>
-    <value>682</value>
+    <value>341</value>
     <description>By default, Tez uses the java options from map tasks. Use this property to override that value.</description>
     <display-name>Tez Container Size</display-name>
     <value-attributes>
       <type>int</type>
-      <minimum>682</minimum>
+      <minimum>341</minimum>
       <maximum>6820</maximum>
       <unit>MB</unit>
       <increment-step>682</increment-step>
@@ -1300,8 +1264,11 @@ limitations under the License.
 
   <property>
     <name>hive.tez.java.opts</name>
-    <value>-server -Xmx545m -Djava.net.preferIPv4Stack=true -XX:NewRatio=8 -XX:+UseNUMA -XX:+UseParallelGC -XX:+PrintGCDetails -verbose:gc -XX:+PrintGCTimeStamps</value>
+    <value></value>
     <description>Java command line options for Tez. The -Xmx parameter value is generally 80% of hive.tez.container.size.</description>
+    <value-attributes>
+      <empty-value-valid>true</empty-value-valid>
+    </value-attributes>
   </property>
 
   <property>
@@ -1462,7 +1429,7 @@ limitations under the License.
 
   <property>
     <name>hive.vectorized.execution.reduce.enabled</name>
-    <value>false</value>
+    <value>true</value>
     <description>
       This flag should be set to true to enable vectorized mode of the reduce-side of
       query execution.
@@ -1573,11 +1540,9 @@ limitations under the License.
     <name>hive.server2.tez.sessions.per.default.queue</name>
     <value>1</value>
     <description>
-      A positive integer that determines the number of Tez sessions that should be
-      launched on each of the queues specified by "hive.server2.tez.default.queues".
-      Determines the parallelism on each queue.
+      The maximum number of queries this Hive LLAP cluster will be able to handle concurrently.
     </description>
-    <display-name>Session per queue</display-name>
+    <display-name>Maximum Concurrent Queries</display-name>
     <value-attributes>
       <type>int</type>
       <minimum>1</minimum>
@@ -1588,7 +1553,7 @@ limitations under the License.
 
   <property>
     <name>hive.server2.tez.initialize.default.sessions</name>
-    <value>false</value>
+    <value>true</value>
     <description>
       This flag is used in HiveServer2 to enable a user to use HiveServer2 without
       turning on Tez for HiveServer2. The user could potentially want to run queries
@@ -1612,6 +1577,29 @@ limitations under the License.
   </property>
 
   <property>
+    <name>hive.driver.parallel.compilation</name>
+    <value>true</value>
+    <description>
+      This flag allows HiveServer2 to compile queries in parallel.
+    </description>
+    <display-name>Compile queries in parallel</display-name>
+    <value-attributes>
+      <type>value-list</type>
+      <entries>
+        <entry>
+          <value>true</value>
+          <label>True</label>
+        </entry>
+        <entry>
+          <value>false</value>
+          <label>False</label>
+        </entry>
+      </entries>
+      <selection-cardinality>1</selection-cardinality>
+    </value-attributes>
+  </property>
+
+  <property>
     <name>hive.txn.manager</name>
     <value>org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager</value>
     <description/>
@@ -1830,6 +1818,12 @@ limitations under the License.
   </property>
 
   <property>
+    <name>hive.server2.webui.port </name>
+    <value>10502</value>
+    <description>Web UI port address</description>
+  </property>
+
+  <property>
     <name>hive.server2.allow.user.substitution</name>
     <value>true</value>
     <description>Allow alternate user to be specified as part of HiveServer2 open connection request.</description>
@@ -1932,7 +1926,7 @@ limitations under the License.
 
   <property>
     <name>hive.server2.zookeeper.namespace</name>
-    <value>hiveserver2</value>
+    <value>hiveserver2-hive2</value>
     <description>The parent node in ZooKeeper used by HiveServer2 when supporting dynamic service discovery.</description>
   </property>
 
@@ -2038,4 +2032,203 @@ limitations under the License.
     </description>
   </property>
 
+  <property>
+    <name>hive.llap.daemon.queue.name</name>
+    <value>default</value>
+    <description>Choose the YARN queue in this cluster that is dedicated to interactive query.</description>
+    <display-name>Interactive Query Queue</display-name>
+    <value-attributes>
+      <type>combo</type>
+      <entries>
+        <entry>
+          <value>default</value>
+          <label>Default</label>
+        </entry>
+      </entries>
+      <selection-cardinality>1</selection-cardinality>
+    </value-attributes>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.yarn.shuffle.port</name>
+    <value>15551</value>
+  </property>
+
+  <property>
+    <name>hive.execution.mode</name>
+    <value>llap</value>
+  </property>
+
+  <property>
+    <name>hive.llap.execution.mode</name>
+    <value>all</value>
+  </property>
+
+  <property>
+    <name>hive.llap.io.enabled</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.llap.io.use.lrfu</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.llap.auto.allow.uber</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.llap.object.cache.enabled</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.tez.input.generate.consistent.splits</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.llap.client.consistent.splits</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.llap.task.scheduler.locality.delay</name>
+    <value>-1</value>
+  </property>
+
+  <property>
+    <name>hive.exec.orc.split.strategy</name>
+    <value>HYBRID</value>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.service.hosts</name>
+    <value>@llap0</value>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.allow.permanent.fns</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.llap.io.memory.size</name>
+    <display-name>Cache Size</display-name>
+    <description>The amount of data reserved for Hive's optimized in-memory cache.</description>
+    <value>20000000</value>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+      <maximum>268435456</maximum>
+      <unit>MB</unit>
+      <increment-step>256</increment-step>
+      <overridable>false</overridable>
+    </value-attributes>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.num.executors</name>
+    <display-name>Number of Executors</display-name>
+    <description>Number of execution threads per Hive LLAP daemon. Generally this should be set to number of CPU cores.</description>
+    <value>1</value>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+      <maximum>8</maximum>
+      <increment-step>1</increment-step>
+    </value-attributes>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.memory.per.instance.mb</name>
+    <value>250</value>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.vcpus.per.instance</name>
+    <value>${hive.llap.daemon.num.executors}</value>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.yarn.container.mb</name>
+    <display-name>Total Daemon Size</display-name>
+    <description>The memory per node to be used by Hive LLAP.</description>
+    <value>341</value>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+      <maximum>268435456</maximum>
+      <unit>MB</unit>
+      <increment-step>256</increment-step>
+      <overridable>false</overridable>
+    </value-attributes>
+  </property>
+
+  <property>
+    <name>llap.shuffle.connection-keep-alive.enable</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>llap.shuffle.connection-keep-alive.timeout</name>
+    <value>60</value>
+  </property>
+
+  <property>
+    <name>hive.llap.io.threadpool.size</name>
+    <value>4</value>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.rpc.port</name>
+    <value>15001</value>
+  </property>
+  <property>
+    <name>hive.llap.management.rpc.port</name>
+    <value>15004</value>
+  </property>
+
+  <property>
+    <name>hive.llap.daemon.task.scheduler.enable.preemption</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.tez.exec.print.summary</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.vectorized.execution.mapjoin.native.enabled</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.vectorized.execution.mapjoin.minmax.enabled</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.vectorized.execution.mapjoin.native.fast.hashtable.enabled</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.mapjoin.hybridgrace.hashtable</name>
+    <value>false</value>
+  </property>
+
+  <property>
+    <name>hive.tez.bucket.pruning</name>
+    <value>true</value>
+  </property>
+
+  <property>
+    <name>hive.optimize.dynamic.partition.hashjoin</name>
+    <value>true</value>
+  </property>
+
 </configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml
deleted file mode 100644
index 24a95cf..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
-<!--
-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.
--->
-<configuration supports_final="false" supports_adding_forbidden="true">
-  <property>
-    <name>enable_hive_interactive</name>
-    <value>false</value>
-    <description>Enable or disable interactive query in this cluster.</description>
-    <display-name>Enable Interactive Query</display-name>
-    <value-attributes>
-      <type>value-list</type>
-      <entries>
-        <entry>
-          <value>true</value>
-          <label>Yes</label>
-        </entry>
-        <entry>
-          <value>false</value>
-          <label>No</label>
-        </entry>
-      </entries>
-      <selection-cardinality>1</selection-cardinality>
-    </value-attributes>
-  </property>
-  <property>
-    <name>llap_queue_name</name>
-    <value>default</value>
-    <description>LLAP Queue Name.</description>
-    <display-name>LLAP Queue Name</display-name>
-    <value-attributes>
-      <type>combo</type>
-      <entries>
-        <entry>
-          <value>default</value>
-          <label>Default</label>
-        </entry>
-      </entries>
-      <selection-cardinality>1</selection-cardinality>
-    </value-attributes>
-  </property>
-  <property>
-    <name>llap_am_queue_name</name>
-    <value>default</value>
-    <description>LLAP AM Queue Name.</description>
-    <display-name>LLAP AM Queue Name</display-name>
-    <value-attributes>
-      <type>combo</type>
-      <entries>
-        <entry>
-          <value>default</value>
-          <label>Default</label>
-        </entry>
-      </entries>
-      <selection-cardinality>1</selection-cardinality>
-    </value-attributes>
-  </property>
-</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
index ff0f318..f0918c5 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
@@ -99,7 +99,7 @@
       </components>
       <themes>
         <theme>
-          <fileName>theme.json</fileName>
+          <fileName>theme_version_2.json</fileName>
           <default>true</default>
         </theme>
       </themes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json
deleted file mode 100644
index 26b9532..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json
+++ /dev/null
@@ -1,76 +0,0 @@
-{
-  "configuration" : {
-    "placement" : {
-      "configs" : [
-        {
-          "config": "llap-env/enable_hive_interactive",
-          "subsection-name": "interactive-query-row1-col1"
-        },
-        {
-          "config": "llap-env/llap_queue_name",
-          "subsection-name": "interactive-query-row1-col1",
-          "depends-on": [
-            {
-              "configs":[
-                "llap-env/enable_hive_interactive"
-              ],
-              "if": "${llap-env/enable_hive_interactive}",
-              "then": {
-                "property_value_attributes": {
-                  "visible": true
-                }
-              },
-              "else": {
-                "property_value_attributes": {
-                  "visible": false
-                }
-              }
-            }
-          ]
-        },
-        {
-          "config": "llap-env/llap_am_queue_name",
-          "subsection-name": "interactive-query-row1-col1",
-          "depends-on": [
-            {
-              "configs":[
-                "llap-env/enable_hive_interactive"
-              ],
-              "if": "${llap-env/enable_hive_interactive}",
-              "then": {
-                "property_value_attributes": {
-                  "visible": true
-                }
-              },
-              "else": {
-                "property_value_attributes": {
-                  "visible": false
-                }
-              }
-            }
-          ]
-        }
-      ]
-    },
-    "widgets" : [
-      {
-        "config": "llap-env/enable_hive_interactive",
-        "widget": {
-          "type": "toggle"
-        }
-      },
-      {
-        "config": "llap-env/llap_queue_name",
-        "widget": {
-          "type": "list"
-        }
-      },
-      {
-        "config": "llap-env/llap_am_queue_name",
-        "widget": {
-          "type": "list"
-        }
-      }
-    ]
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json
new file mode 100644
index 0000000..64450a8
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json
@@ -0,0 +1,666 @@
+{
+  "name": "default",
+  "description": "Default theme for HIVE service",
+  "configuration": {
+    "layouts": [
+      {
+        "name": "default",
+        "tabs": [
+          {
+            "name": "settings",
+            "display-name": "Settings",
+            "layout": {
+              "tab-rows": 6,
+              "tab-columns": 3,
+              "sections": [
+                {
+                  "name": "acid-transactions",
+                  "display-name": "ACID Transactions",
+                  "row-index": "0",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "acid-transactions-row1-col1-1",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                },
+                {
+                  "name": "interactive-query",
+                  "display-name": "Interactive Query",
+                  "row-index": "0",
+                  "column-index": "1",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "interactive-query-row1-col1",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                },
+                {
+                  "name": "security",
+                  "display-name": "Security",
+                  "row-index": "0",
+                  "column-index": "2",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "security-row1-col1",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                },
+                {
+                  "name": "optimization",
+                  "display-name": "Optimization",
+                  "row-index": "1",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "3",
+                  "section-columns": "3",
+                  "section-rows": "2",
+                  "subsections": [
+                    {
+                      "name": "optimization-row1-col1",
+                      "display-name": "Tez",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "optimization-row1-col2",
+                      "display-name": "",
+                      "row-index": "0",
+                      "column-index": "1",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "optimization-row1-col3",
+                      "display-name": "CBO",
+                      "row-index": "0",
+                      "column-index": "2",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "optimization-row2-col1",
+                      "display-name": "Storage",
+                      "row-index": "1",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "optimization-row2-col2",
+                      "display-name": "",
+                      "row-index": "1",
+                      "column-index": "1",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "optimization-row2-col3",
+                      "display-name": "Memory",
+                      "row-index": "1",
+                      "column-index": "2",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+        ]
+      }
+    ],
+    "placement": {
+      "configuration-layout": "default",
+      "configs": [
+        {
+          "config": "hive-site/hive.exec.orc.default.stripe.size",
+          "subsection-name": "optimization-row2-col1"
+        },
+        {
+          "config": "hive-site/hive.exec.orc.default.compress",
+          "subsection-name": "optimization-row2-col1"
+        },
+        {
+          "config": "hive-env/hive_exec_orc_storage_strategy",
+          "subsection-name": "optimization-row2-col1"
+        },
+        {
+          "config": "hive-env/hive.heapsize",
+          "subsection-name": "optimization-row2-col2"
+        },
+        {
+          "config": "hive-env/hive.metastore.heapsize",
+          "subsection-name": "optimization-row2-col2"
+        },
+        {
+          "config": "hive-env/hive.client.heapsize",
+          "subsection-name": "optimization-row2-col2"
+        },
+        {
+          "config": "hive-site/hive.auto.convert.join.noconditionaltask.size",
+          "subsection-name": "optimization-row2-col3"
+        },
+        {
+          "config": "hive-site/hive.exec.reducers.bytes.per.reducer",
+          "subsection-name": "optimization-row2-col3"
+        },
+        {
+          "config": "hive-env/hive_txn_acid",
+          "subsection-name": "acid-transactions-row1-col1-1"
+        },
+        {
+          "config": "hive-site/hive.compactor.initiator.on",
+          "subsection-name": "acid-transactions-row1-col1-1"
+        },
+        {
+          "config": "hive-site/hive.compactor.worker.threads",
+          "subsection-name": "acid-transactions-row1-col1-1"
+        },
+        {
+          "config": "hive-interactive-env/enable_hive_interactive",
+          "subsection-name": "interactive-query-row1-col1"
+        },
+        {
+          "config": "hive-interactive-env/hive_server_interactive_host",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-site/hive.llap.daemon.queue.name",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-env/llap_queue_capacity",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-env/num_llap_nodes",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-site/hive.llap.daemon.yarn.container.mb",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-site/hive.llap.io.memory.size",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-site/hive.llap.daemon.num.executors",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-interactive-site/hive.server2.tez.sessions.per.default.queue",
+          "subsection-name": "interactive-query-row1-col1",
+          "depends-on": [
+            {
+              "configs":[
+                "hive-interactive-env/enable_hive_interactive"
+              ],
+              "if": "${hive-interactive-env/enable_hive_interactive}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "hive-site/hive.execution.engine",
+          "subsection-name": "optimization-row1-col1"
+        },
+        {
+          "config": "hive-site/hive.tez.container.size",
+          "subsection-name": "optimization-row1-col1"
+        },
+        {
+          "config": "hive-site/hive.prewarm.enabled",
+          "subsection-name": "optimization-row1-col2"
+        },
+        {
+          "config": "hive-site/hive.prewarm.numcontainers",
+          "subsection-name": "optimization-row1-col2"
+        },
+        {
+          "config": "hive-site/hive.cbo.enable",
+          "subsection-name": "optimization-row1-col3"
+        },
+        {
+          "config": "hive-site/hive.stats.fetch.column.stats",
+          "subsection-name": "optimization-row1-col3"
+        },
+        {
+          "config": "hive-env/hive_security_authorization",
+          "subsection-name": "security-row1-col1"
+        },
+        {
+          "config": "hive-site/hive.server2.enable.doAs",
+          "subsection-name": "security-row1-col1"
+        },
+        {
+          "config": "hive-site/hive.server2.authentication",
+          "subsection-name": "security-row1-col1"
+        },
+        {
+          "config": "hive-site/hive.server2.use.SSL",
+          "subsection-name": "security-row1-col1"
+        }
+      ]
+    },
+    "widgets": [
+      {
+        "config": "hive-site/hive.exec.orc.default.stripe.size",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-site/hive.exec.orc.default.compress",
+        "widget": {
+          "type": "combo"
+        }
+      },
+      {
+        "config": "hive-env/hive_exec_orc_storage_strategy",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-env/hive.heapsize",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-env/hive.metastore.heapsize",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-env/hive.client.heapsize",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-site/hive.auto.convert.join.noconditionaltask.size",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-site/hive.exec.reducers.bytes.per.reducer",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-env/hive_txn_acid",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-site/hive.compactor.initiator.on",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-site/hive.compactor.worker.threads",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "int"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-interactive-env/enable_hive_interactive",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-interactive-env/hive_server_interactive_host",
+        "widget": {
+          "type": "label"
+        }
+      },
+      {
+        "config": "hive-interactive-site/hive.llap.daemon.queue.name",
+        "widget": {
+          "type": "list"
+        }
+      },
+      {
+        "config": "hive-interactive-env/num_llap_nodes",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "int"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-interactive-env/llap_queue_capacity",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "percent"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-interactive-site/hive.llap.daemon.yarn.container.mb",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "GB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-interactive-site/hive.llap.io.memory.size",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "GB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-interactive-site/hive.llap.daemon.num.executors",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "int"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-interactive-site/hive.server2.tez.sessions.per.default.queue",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "int"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-site/hive.execution.engine",
+        "widget": {
+          "type": "combo"
+        }
+      },
+      {
+        "config": "hive-site/hive.tez.container.size",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "MB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-site/hive.prewarm.enabled",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-site/hive.prewarm.numcontainers",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "int"
+            }
+          ]
+        }
+      },
+      {
+        "config": "hive-site/hive.cbo.enable",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-site/hive.stats.fetch.column.stats",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-site/hive.server2.enable.doAs",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "hive-env/hive_security_authorization",
+        "widget": {
+          "type": "combo"
+        }
+      },
+      {
+        "config": "hive-site/hive.server2.authentication",
+        "widget": {
+          "type": "combo"
+        }
+      },
+      {
+        "config": "hive-site/hive.server2.use.SSL",
+        "widget": {
+          "type": "toggle"
+        }
+      }
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index 93775fb..8c855fc 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -20,7 +20,7 @@ var App = require('app');
 var batchUtils = require('utils/batch_scheduled_requests');
 var databaseUtils = require('utils/configs/database');
 
-App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.VersionsMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, {
+App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.VersionsMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, App.ComponentActionsByConfigs, {
 
   name: 'mainServiceInfoConfigsController',
 
@@ -301,8 +301,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
         // This requires calling  `loadCurrentVersions` after theme has loaded
         self.loadCurrentVersions();
       });
-    }
-    else {
+    } else {
       this.loadCurrentVersions();
     }
     this.loadServiceConfigVersions();
@@ -558,6 +557,21 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
         serviceConfig.get('configs').push(App.ServiceConfigProperty.create(hProperty));
       }
     }, this);
+
+    App.ConfigAction.find().forEach(function(item){
+      var hostComponentConfig = item.get('hostComponentConfig');
+      var config =  serviceConfig.get('configs').filterProperty('filename', hostComponentConfig.fileName).findProperty('name', hostComponentConfig.configName);
+      if (config){
+        var componentHostName = App.HostComponent.find().findProperty('componentName', item.get('componentName')) ;
+        if (componentHostName) {
+          var setConfigValue =  !config.get('value');
+          if (setConfigValue) {
+            config.set('value', componentHostName.get('hostName'));
+            config.set('recommendedValue', componentHostName.get('hostName'));
+          }
+        }
+      }
+    }, this);
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7/assign_master_controller.js b/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
index 496968b..57230c4 100644
--- a/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
+++ b/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+var stringUtils = require('utils/string_utils');
+
 App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App.AssignMasterComponents, {
 
   name:"assignMasterOnStep7Controller",
@@ -24,7 +26,13 @@ App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App
 
   showInstalledMastersFirst: false,
 
-  deferred: null,
+  configWidgetContext: {},
+
+  configActionComponent: {},
+
+  content: function() {
+    return (this.get('configWidgetContext.controller.content') || {});
+  }.property('configWidgetContext.controller.content'),
 
   popup: null,
 
@@ -32,35 +40,46 @@ App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App
 
   markSavedComponentsAsInstalled: true,
 
-  execute: function(context) {
-    var dfd = $.Deferred();
-    this.set('content', context.get('content'));
-    var allConfigs = context.get('stepConfigs').mapProperty('configs').filter(function(item) {
-      return item.length;
-    }).reduce(function(p, c) {
-      if (p) {
-        return p.concat(c);
-      }
-    });
-    var storedConfigs = this.get('content.serviceConfigProperties');
-    var configThemeActions =  App.configTheme.getConfigThemeActions(allConfigs, storedConfigs || []);
-
-    if (configThemeActions['add'].length) {
-      this.showAssignComponentPopup(dfd, configThemeActions['add']);
-    } else {
-      if (configThemeActions['delete'].length) {
-        this.removeMasterComponent(configThemeActions['delete']);
-      }
-      dfd.resolve();
+  /**
+   * Marks component add/delete action to be performed ahead.
+   * @param context {Object} Context of the calling function
+   * @param action {String} ADD|DELETE
+   * @param hostComponent {Object}
+   * @public
+   * @method {execute}
+   */
+  execute: function(context, action, hostComponent) {
+    this.set('configWidgetContext', context);
+    this.set('content', context.get('controller.content'));
+    this.set('configActionComponent',hostComponent);
+    this.set('mastersToCreate', [hostComponent.componentName]);
+    var missingDependentServices = this.getAllMissingDependentServices();
+    var isNonWizardPage = !this.get('content.controllerName');
+    switch(action) {
+      case 'ADD':
+        if (missingDependentServices.length && isNonWizardPage) {
+          this.showInstallServicesPopup(missingDependentServices);
+        } else {
+          this.showAssignComponentPopup();
+        }
+        break;
+      case 'DELETE':
+        this.removeMasterComponent();
+        break;
     }
-    return dfd.promise();
   },
 
-  showAssignComponentPopup: function(dfd, componentsToAdd) {
+  /**
+   * Assign Master page will be displayed in the popup
+   * @private
+   * @method
+   */
+  showAssignComponentPopup: function() {
     var self = this;
-    this.set('deferred', dfd);
-    this.set('mastersToCreate', componentsToAdd);
-
+    // Master component hosts should be loaded only when content.controller name is not defined i.e non-wizard pages
+    if (!this.get('content.controllerName')) {
+      this.loadMasterComponentHosts();
+    }
     var popup = App.ModalPopup.show({
       classNames: ['full-width-modal', 'add-service-wizard-modal'],
       header: Em.I18n.t('admin.highAvailability.wizard.step2.header'),
@@ -70,38 +89,159 @@ App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App
       primary: Em.I18n.t('form.cancel'),
       showFooter: false,
       secondary: null,
-      onClose: function () {
-        this.hide();
-      },
+      showCloseButton: false,
       didInsertElement: function () {
         this._super();
         this.fitHeight();
+        self.set('configWidgetContext.controller.saveInProgress', false);
       }
     });
     this.set('popup', popup);
   },
 
-  removeMasterComponent: function(componentsToDelete) {
-    var parentController = App.router.get(this.get('content.controllerName'));
-    var masterComponentHosts =   this.get('content.masterComponentHosts');
-    componentsToDelete.forEach(function(_componentName) {
-      masterComponentHosts = masterComponentHosts.rejectProperty('component',_componentName);
-    }, this);
-    this.get('content').set('masterComponentHosts', masterComponentHosts);
-    parentController.setDBProperty('masterComponentHosts',  masterComponentHosts);
+  /**
+   * Displays the popup to install required service dependencies for being added component with this config change
+   * @param missingDependentServices {String[]}   Array of service display names
+   */
+  showInstallServicesPopup: function(missingDependentServices) {
+    var self = this;
+    var displayServices =  stringUtils.getFormattedStringFromArray(missingDependentServices);
+    var configWidgetContext = this.get('configWidgetContext');
+    var config =  self.get('configWidgetContext.config');
+    var configDisplayName =  config.get('displayName').toLowerCase();
+    App.ModalPopup.show({
+      header: Em.I18n.t('installer.step7.missing.service.header'),
+      body: Em.I18n.t('installer.step7.missing.service.body').format(displayServices, configDisplayName),
+      primaryClass: 'btn-danger',
+      onPrimary: function () {
+        var value = config.get('initialValue');
+        config.set('value', value);
+        configWidgetContext.setValue(value);
+        this._super();
+      },
+      secondary: null,
+      showCloseButton: false,
+      didInsertElement: function () {
+        this._super();
+        configWidgetContext.set('controller.saveInProgress', false);
+      }
+    });
+  },
+
+  /**
+   * This method is used while installing or adding a service
+   * Removes the masterComponent that was previously being tracked to be added to the cluster
+   * @private
+   * @method {removeMasterComponent}
+   */
+  removeMasterComponent: function() {
+    var componentsToDelete = this.get('mastersToCreate');
+    if (this.get('content.controllerName')) {
+      var parentController = App.router.get(this.get('content.controllerName'));
+      var masterComponentHosts = this.get('content.masterComponentHosts');
+      componentsToDelete.forEach(function (_componentName) {
+        masterComponentHosts = masterComponentHosts.rejectProperty('component', _componentName);
+      }, this);
+      this.get('content').set('masterComponentHosts', masterComponentHosts);
+      parentController.setDBProperty('masterComponentHosts', masterComponentHosts);
+    }
+    var configActionComponent = this.get('configActionComponent');
+    this.get('configWidgetContext.config').set('configActionComponent', configActionComponent);
+  },
+
+  /**
+   * Load active host list to <code>hosts</code> variable
+   * @override
+   * @method renderHostInfo
+   */
+  renderHostInfo: function () {
+    var numberUtils = require('utils/number_utils');
+    var parentController = this.get('content.controllerName');
+    if (parentController) {
+      this._super();
+    } else {
+      var hosts = App.Host.find().toArray();
+      var result = [];
+      for (var p = 0; p < hosts.length; p++) {
+        result.push(Em.Object.create({
+          host_name: hosts[p].get('hostName'),
+          cpu: hosts[p].get('cpu'),
+          memory: hosts[p].get('memory'),
+          disk_info: hosts[p].get('diskInfo'),
+          host_info: Em.I18n.t('installer.step5.hostInfo').fmt(hosts[p].get('hostName'), numberUtils.bytesToSize(hosts[p].get('memory'), 1, 'parseFloat', 1024), hosts[p].get('cpu'))
+        }));
+      }
+
+      this.set("hosts", result);
+      this.sortHosts(this.get('hosts'));
+      this.set('isLoaded', true);
+    }
   },
 
   /**
+   *  This method is called on Service->config page and is responsible to load the "Assign Master popup"
+   *  with the installed master component hosts.
+   * @private
+   * @method {loadMasterComponentHosts}
+   */
+  loadMasterComponentHosts: function () {
+    var stackMasterComponents = App.get('components.masters').uniq();
+    var masterComponentHosts = [];
+    App.HostComponent.find().filter(function(component) {
+      return stackMasterComponents.contains(component.get('componentName'));
+    }).forEach(function (item) {
+      masterComponentHosts.push({
+        component: item.get('componentName'),
+        hostName: item.get('hostName'),
+        isInstalled: true,
+        serviceId: item.get('service.id'),
+        display_name: item.get('displayName')
+      })
+    });
+    this.set("masterComponentHosts", masterComponentHosts);
+  },
+
+  /**
+   * Returns array of dependent services that are yet not installed in the cluster
+   * @private
+   * @method getAllMissingDependentServices
+   * @return  missingDependentServices {Array}
+   */
+  getAllMissingDependentServices: function() {
+    var context = this.get('configWidgetContext');
+    var configActionComponentName = this.get('configActionComponent').componentName;
+    var componentStackService = App.StackServiceComponent.find(configActionComponentName).get('stackService');
+    var dependentServices = componentStackService.get('requiredServices');
+    var missingDependentServices =  dependentServices.filter(function(item) {
+      return !App.Service.find().findProperty('serviceName', item);
+    }).map(function(item){
+       return  App.StackService.find(item).get('displayName');
+    });
+    return missingDependentServices;
+  },
+
+
+  /**
    * Submit button click handler
    * @method submit
    */
   submit: function () {
-    if (this.get('deferred')) {
-      this.get('popup').hide();
+    this.get('popup').hide();
+    if (this.get('content.controllerName')) {
       var controller = App.router.get(this.get('content.controllerName'));
       controller.saveMasterComponentHosts(this);
-      this.get('deferred').resolve();
-      this.set('deferred', null);
     }
+    var selectedServicesMasters = this.get('selectedServicesMasters');
+    var context = this.get('configWidgetContext');
+    var configActionComponent = this.get('configActionComponent');
+    var componentHostName = selectedServicesMasters.findProperty('component_name',configActionComponent.componentName).selectedHost;
+
+    var hostComponentConfig = context.get('config.configAction.hostComponentConfig');
+    var serviceConfigs = context.get('controller.stepConfigs').findProperty('serviceName', context.get('config.serviceName')).get('configs');
+    var config =  serviceConfigs.filterProperty('filename', hostComponentConfig.fileName).findProperty('name', hostComponentConfig.configName);
+    config.set('value', componentHostName);
+    config.set('recommendedValue', componentHostName);
+    configActionComponent.hostName =  componentHostName;
+    this.get('configWidgetContext.config').set('configActionComponent', configActionComponent);
   }
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/controllers/wizard/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index 06488b1..9113ea2 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -526,11 +526,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
           var service = App.config.get('serviceByConfigTypeMap')[App.config.getConfigTagFromFileName(serviceConfigProperty.get('filename'))];
           serviceConfigProperty.set('isEditable', service && !this.get('installedServiceNames').contains(service.get('serviceName')));
         } else {
-          serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
+          serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isEditable') && serviceConfigProperty.get('isReconfigurable'));
         }
-      } else if (Em.get(serviceConfigProperty, 'group') && Em.get(serviceConfigProperty, 'group.name') == this.get('selectedConfigGroup.name')) {
-        serviceConfigProperty.set('isEditable', true);
-      } else {
+      } else if (!(Em.get(serviceConfigProperty, 'group') && Em.get(serviceConfigProperty, 'group.name') == this.get('selectedConfigGroup.name'))) {
         serviceConfigProperty.set('isEditable', false);
       }
     }
@@ -690,8 +688,11 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     var stepConfigs = this.createStepConfigs();
     var serviceConfigs = this.renderConfigs(stepConfigs, configs);
     // if HA is enabled -> Make some reconfigurations
-    if (this.get('wizardController.name') === 'addServiceController' && App.get('isHaEnabled')) {
-      serviceConfigs = this._reconfigureServicesOnNnHa(serviceConfigs);
+    if (this.get('wizardController.name') === 'addServiceController') {
+      this.updateComponentActionConfigs(configs, serviceConfigs);
+      if (App.get('isHaEnabled')) {
+        serviceConfigs = this._reconfigureServicesOnNnHa(serviceConfigs);
+      }
     }
     this.set('stepConfigs', serviceConfigs);
     this.checkHostOverrideInstaller();
@@ -704,6 +705,31 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     this.loadConfigRecommendations(null, this.completeConfigLoading.bind(this));
   },
 
+  /**
+   *
+   * Makes installed service's configs resulting into component actions (add/delete) non editable on Add Service Wizard
+   * @param configs Object[]
+   * @param  stepConfigs Object[]
+   * @private
+   * @method updateComponentActionConfigs
+   */
+  updateComponentActionConfigs: function(configs, stepConfigs) {
+    App.ConfigAction.find().forEach(function(item){
+      var configName = item.get('configName');
+      var fileName = item.get('fileName');
+      var config =  configs.filterProperty('filename', fileName).findProperty('name', configName);
+      if (config) {
+        var isServiceInstalled = App.Service.find().findProperty('serviceName', config.serviceName);
+        if (isServiceInstalled) {
+          var serviceConfigs = stepConfigs.findProperty('serviceName', config.serviceName).get('configs');
+          var serviceConfig =  serviceConfigs.filterProperty('filename', fileName).findProperty('name', configName);
+          serviceConfig.set('isEditable', false);
+          config.isEditable = false;
+        }
+      }
+    }, this);
+  },
+
   completeConfigLoading: function() {
     this.clearRecommendationsByServiceName(App.StackService.find().filterProperty('isSelected').mapProperty('serviceName'));
     console.timeEnd('wizard loadStep: ');
@@ -1270,7 +1296,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     var isEditable = config.get('isEditable'),
       isServiceInstalled = this.get('installedServiceNames').contains(this.get('selectedService.serviceName'));
     if (isServiceInstalled) {
-      isEditable = (!isEditable && !config.get('isReconfigurable')) ? false : selectedGroup.get('isDefault');
+      isEditable = (!isEditable || !config.get('isReconfigurable')) ? false : selectedGroup.get('isDefault');
     }
     else {
       isEditable = selectedGroup.get('isDefault');
@@ -1620,24 +1646,18 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
    * @method submit
    */
   submit: function () {
-    var self = this;
     if (this.get('isSubmitDisabled') || App.router.nextBtnClickInProgress) {
       return false;
     }
 
-    var assignMasterOnStep7Controller =  App.router.get('assignMasterOnStep7Controller');
-    var dfdPromise = assignMasterOnStep7Controller.execute(self);
-
     if (this.get('supportsPreInstallChecks')) {
       var preInstallChecksController = App.router.get('preInstallChecksController');
       if (preInstallChecksController.get('preInstallChecksWhereRun')) {
-        return dfdPromise.done(self.postSubmit.bind(self));
+        return this.postSubmit();
       }
-      return dfdPromise.done(function() {
-        preInstallChecksController.notRunChecksWarnPopup(self.postSubmit.bind(self));
-      });
+      return preInstallChecksController.notRunChecksWarnPopup(this.postSubmit.bind(this));
     }
-    return dfdPromise.done(self.postSubmit.bind(self));
+    return this.postSubmit();
   },
 
   postSubmit: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mappers/configs/themes_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/themes_mapper.js b/ambari-web/app/mappers/configs/themes_mapper.js
index 3e68e67..6cba017 100644
--- a/ambari-web/app/mappers/configs/themes_mapper.js
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -130,7 +130,9 @@ App.themesMapper = App.QuickDataMapper.create({
                       var type = 'subsectionTab';
                       this.mapThemeConditions(subSectionTabConditions, type);
                     }
+                    App.store.commit();
                     App.store.loadMany(this.get("subSectionTabModel"), subSectionTabs);
+                    App.store.commit();
                     parsedSubSection.sub_section_tabs = subSectionTabs.mapProperty("id");
                   }
                   if (parsedSubSection['depends_on']) {
@@ -142,14 +144,18 @@ App.themesMapper = App.QuickDataMapper.create({
                   var type = 'subsection';
                   this.mapThemeConditions(subSectionConditions, type);
                 }
+                App.store.commit();
                 App.store.loadMany(this.get("subSectionModel"), subSections);
+                App.store.commit();
                 parsedSection.sub_sections = subSections.mapProperty("id");
               }
 
               sections.push(parsedSection);
             }, this);
 
+            App.store.commit();
             App.store.loadMany(this.get("sectionModel"), sections);
+            App.store.commit();
             parsedTab.sections = sections.mapProperty("id");
           }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 421143a..52e3b8e 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -321,6 +321,7 @@ Em.I18n.translations = {
   'common.levels': 'Levels',
   'common.extension': 'Extension',
   'common.logs': 'Logs',
+  'common.warn.message': '<div class="alert alert-warn">{0}</div>',
 
   'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on {1}",
   'models.alert_definition.triggered.verbose': "Occurred on {0}",
@@ -853,7 +854,10 @@ Em.I18n.translations = {
   'installer.step7.preInstallChecks.checksPopup.header':'Pre Install Checks',
 
 
-  'installer.step7.assign.master.body':'Assign {0} to {1} you want to run {2} on.',
+  'installer.step7.assign.master.body':'Assign <strong>{0}</strong> to {1} you want to run {2} on.',
+  'installer.step7.assign.master.dependent.component.body':'If not present {0} will also be installed on the selected host. ',
+  'installer.step7.missing.service.header':'Missing Service',
+  'installer.step7.missing.service.body': '{0} service should be added to the cluster to {1}.',
 
 
   'installer.step8.header': 'Review',

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mixins.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js
index 0a686b3..23d447b 100644
--- a/ambari-web/app/mixins.js
+++ b/ambari-web/app/mixins.js
@@ -39,6 +39,7 @@ require('mixins/main/service/themes_mapping');
 require('mixins/main/service/versions_mapping');
 require('mixins/main/service/configs/config_overridable');
 require('mixins/main/service/configs/widget_popover_support');
+require('mixins/main/service/configs/component_actions_by_configs');
 require('mixins/routers/redirections');
 require('mixins/wizard/wizardProgressPageController');
 require('mixins/wizard/wizardDeployProgressController');

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js b/ambari-web/app/mixins/common/configs/configs_saver.js
index 82741fa..ece8a2d 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -608,7 +608,8 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * @method doPUTClusterConfigurationSiteSuccessCallback
    */
   doPUTClusterConfigurationSiteSuccessCallback: function () {
-    this.onDoPUTClusterConfigurations();
+    var doConfigActions = true;
+    this.onDoPUTClusterConfigurations(doConfigActions);
   },
 
   /**
@@ -617,16 +618,17 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    */
   doPUTClusterConfigurationSiteErrorCallback: function () {
     this.set('saveConfigsFlag', false);
-    this.doPUTClusterConfigurationSiteSuccessCallback();
+    this.onDoPUTClusterConfigurations();
   },
 
   /**
    * On save configs handler. Open save configs popup with appropriate message
    * and clear config dependencies list.
+   * @param  {Boolean} doConfigActions
    * @private
    * @method onDoPUTClusterConfigurations
    */
-  onDoPUTClusterConfigurations: function () {
+  onDoPUTClusterConfigurations: function (doConfigActions) {
     var header, message, messageClass, value, status = 'unknown', urlParams = '',
       result = {
         flag: this.get('saveConfigsFlag'),
@@ -667,7 +669,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
     //  update configs for service actions
     App.router.get('mainServiceItemController').loadConfigs();
 
-    this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams);
+    this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams, doConfigActions);
     this.clearAllRecommendations();
   },
 
@@ -677,11 +679,8 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * @private
    * @method showSaveConfigsPopup
    */
-  showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams) {
+  showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams, doConfigActions) {
     var self = this;
-    if (flag) {
-      self.loadStep();
-    }
     return App.ModalPopup.show({
       header: header,
       primary: Em.I18n.t('ok'),
@@ -767,12 +766,12 @@ App.ConfigsSaverMixin = Em.Mixin.create({
           switch (status) {
             case 'unknown':
               response.items.filter(function (item) {
-                return (item.ServiceComponentInfo.total_count > item.ServiceComponentInfo.started_count + item.ServiceComponentInfo.installed_count);
+                return (item.ServiceComponentInfo.total_count > (item.ServiceComponentInfo.started_count + item.ServiceComponentInfo.installed_count));
               }).forEach(function (item) {
                 var total = item.ServiceComponentInfo.total_count,
                   started = item.ServiceComponentInfo.started_count,
                   installed = item.ServiceComponentInfo.installed_count,
-                  unknown = total - started + installed;
+                  unknown = total - (started + installed);
                 components = setComponents(item, components);
                 count += unknown;
               });
@@ -796,7 +795,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
           this.set('isLoaded', true);
         },
         didInsertElement: function () {
-          return App.ajax.send({
+          var dfd = App.ajax.send({
             name: 'components.filter_by_status',
             sender: this,
             data: {
@@ -806,6 +805,15 @@ App.ConfigsSaverMixin = Em.Mixin.create({
             success: 'componentsFilterSuccessCallback',
             error: 'componentsFilterErrorCallback'
           });
+
+          dfd.done(function() {
+            if (doConfigActions && self.doConfigActions) {
+              self.doConfigActions.bind(self)();
+              if (flag) {
+                self.loadStep();
+              }
+            }
+          });
         },
         getDisplayMessage: function () {
           var displayMsg = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js b/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js
new file mode 100644
index 0000000..7857411
--- /dev/null
+++ b/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js
@@ -0,0 +1,277 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var stringUtils = require('utils/string_utils');
+
+/**
+ * Mixin with methods for component actions that needs to be done when a config with specific value is saved
+ * Used in the service config controller
+ * @type {Em.Mixin}
+ */
+App.ComponentActionsByConfigs = Em.Mixin.create({
+
+  /**
+   * Do component add/delete actions as inferred from value of service configs
+   * @public
+   * @method doConfigActions
+   */
+  doConfigActions: function() {
+    var serviceConfigs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
+    var configActionComponents = serviceConfigs.filterProperty('configActionComponent');
+
+    this.doComponentDeleteActions(configActionComponents);
+    this.doComponentAddActions(configActionComponents);
+  },
+
+  /**
+   * Do component Delete actions as inferred from value of service config
+   * @param configActionComponents Object[]
+   * @private
+   * @method {configActionComponents}
+   */
+  doComponentDeleteActions: function(configActionComponents) {
+    var self = this;
+    var componentsToDelete = configActionComponents.filterProperty('configActionComponent.action', 'delete').map(function(item){
+      return item.configActionComponent;
+    }).filter(function(_componentToDelete){
+      return  App.HostComponent.find().filterProperty('componentName',_componentToDelete.componentName).someProperty('hostName', _componentToDelete.hostName);
+    }, this);
+
+    if (componentsToDelete.length) {
+      componentsToDelete.forEach(function(_componentToDelete){
+        var displayName = App.StackServiceComponent.find().findProperty('componentName',  _componentToDelete.componentName).get('displayName');
+        var context = Em.I18n.t('requestInfo.stop').format(displayName);
+        this.installHostComponents( _componentToDelete.hostName, _componentToDelete.componentName, context).done(function(data){
+          self.isRequestCompleted(data).done(function() {
+            self.deleteHostComponent(_componentToDelete.hostName, _componentToDelete.componentName);
+          });
+        });
+      }, this);
+    }
+  },
+
+  /**
+   * Do component Add actions as inferred from value of service config
+   * @param configActionComponents Object[]
+   * @private
+   * @method {doComponentAddActions}
+   */
+  doComponentAddActions: function(configActionComponents) {
+    var self = this;
+    var componentsToAdd = configActionComponents.filterProperty('configActionComponent.action', 'add').map(function(item){
+      return item.configActionComponent;
+    }).filter(function(_componentToAdd){
+      return  !App.HostComponent.find().filterProperty('componentName',_componentToAdd.componentName).someProperty('hostName', _componentToAdd.hostName);
+    }, this);
+
+    var dependentComponents = [];
+    if (componentsToAdd.length) {
+      componentsToAdd.forEach(function(_component) {
+        var dependencies = App.StackServiceComponent.find(_component.componentName).get('dependencies').filterProperty('scope', 'host').map(function(_dependency){
+          return {
+            componentName: _dependency.componentName,
+            hostName:  _component.hostName,
+            isClient: App.StackServiceComponent.find(_dependency.componentName).get('isClient')
+          }
+        }, this);
+        var dependenciesToInstall =  dependencies.filter(function (_dependencyToAdd) {
+          var isInstalled = App.HostComponent.find().filterProperty('componentName', _dependencyToAdd.componentName).someProperty('hostName', _dependencyToAdd.hostName);
+          var isAddedToInstall =  dependentComponents.filterProperty('componentName',_dependencyToAdd.componentName).someProperty('hostName', _dependencyToAdd.hostName);
+          return !(isInstalled || isAddedToInstall);
+        }, this);
+        dependentComponents = dependentComponents.concat(dependenciesToInstall);
+      }, this);
+      var allComponentsToAdd = componentsToAdd.concat(dependentComponents);
+      var allComponentsToAddHosts = allComponentsToAdd.mapProperty('hostName').uniq();
+      allComponentsToAddHosts.forEach(function(_hostName, index){
+        var hostComponents = allComponentsToAdd.filterProperty('hostName', _hostName).mapProperty('componentName').uniq();
+        var masterHostComponents =  allComponentsToAdd.filterProperty('hostName', _hostName).filterProperty('isClient', false).mapProperty('componentName').uniq();
+        this.createHostComponents(_hostName, hostComponents).done(function(data){
+          self.installHostComponents(_hostName, hostComponents).done(function(data){
+            self.isRequestCompleted(data).done(function() {
+              var displayNames = masterHostComponents.map(function(item) {
+                return App.StackServiceComponent.find().findProperty('componentName', item).get('displayName');
+              });
+              var displayStr =  stringUtils.getFormattedStringFromArray(displayNames);
+              var context = Em.I18n.t('requestInfo.start').format(displayStr);
+              self.startHostComponents(_hostName, masterHostComponents, context);
+            });
+          });
+        });
+      }, this);
+    }
+  },
+
+  /**
+   * Calls the API to create multiple components on a host
+   * @param hostName {String}
+   * @param components {String[]}|{String}
+   * @return {Object} Deferred promise
+   */
+  createHostComponents: function(hostName, components) {
+    var query =  "Hosts/host_name.in(" + hostName + ")";
+    components = (Array.isArray(components)) ? components : [components];
+    var hostComponent = components.map(function(_componentName){
+      return {
+        "HostRoles":{
+          "component_name":_componentName
+        }
+      }
+    }, this);
+    return App.ajax.send({
+      name: 'common.host.host_components.create',
+      sender: this,
+      data: {
+        query: query,
+        host_components: hostComponent,
+        type: ''
+      }
+    });
+  },
+
+  /**
+   * Calls the API to install multiple components on a host
+   * @param hostName {String}
+   * @param components {String[]}
+   * @param context {String} Optional
+   * @return {Object} Deferred promise
+   */
+  installHostComponents: function(hostName, components, context) {
+    context = context || Em.I18n.t('requestInfo.installComponents');
+    return this.updateHostComponents(hostName, components, App.HostComponentStatus.stopped, context);
+  },
+
+  /**
+   * Calls the API to start multiple components on a host
+   * @param hostName {String}
+   * @param components {String[]}
+   * @param context {String} Optional
+   * @return {Object} Deferred promise
+   */
+  startHostComponents: function(hostName, components, context) {
+    context = context || Em.I18n.t('requestInfo.startHostComponents');
+    return this.updateHostComponents(hostName, components, App.HostComponentStatus.started, context);
+  },
+
+  /**
+   * Calls the API to start/stop multiple components on a host
+   * @param hostName {String}
+   * @param components
+   * @param desiredState
+   * @param context {String}
+   * @private
+   * @method {updateHostComponents}
+   * @return {Object} Deferred promise
+   */
+  updateHostComponents: function(hostName, components, desiredState, context) {
+    var data = {
+      hostName: hostName,
+      context: context,
+      HostRoles: {
+        state: desiredState
+      }
+    };
+    components = (Array.isArray(components)) ? components : [components];
+    data.query = "HostRoles/component_name.in(" + components.join(',') + ")";
+
+    return App.ajax.send({
+      name: 'common.host.host_components.update',
+      sender: this,
+      data: data
+    });
+  },
+
+  /**
+   * Calls the API to delete component on a host
+   * @param hostName {String}
+   * @param component {String}
+   * @return {Object} Deferred
+   */
+  deleteHostComponent: function(hostName, component) {
+    return App.ajax.send({
+      name: 'common.delete.host_component',
+      sender: this,
+      data: {
+        hostName: hostName,
+        componentName: component
+      }
+    });
+  },
+
+  /**
+   * Fetched the Request Id to poll and starts the polling to check
+   * if the request is ongoing or completed until deferred is resolved
+   * @param data {Object} Json
+   * @private
+   * @method {isRequestCompleted}
+   * @return {Object} Deferred promise
+   */
+  isRequestCompleted: function(data) {
+    var dfd = $.Deferred();
+    if (!data) {
+      dfd.resolve();
+    } else {
+      var requestId = data.Requests.id;
+      this.getRequestStatus(requestId, dfd);
+    }
+    return dfd.promise();
+  },
+
+  /**
+   * keeps checking on requestId if the request is ongoing or completed until deferred is resolved
+   * @param requestId {Integer}
+   * @param requestCompletedDfd {Object} Deferred Object to resolve when the requestId shows that the request is completed
+   * @private
+   * @method {isRequestCompleted}
+   */
+  getRequestStatus: function(requestId, requestCompletedDfd) {
+    var self = this;
+    var POLL_INTERVAL = 5000;
+    var TIMEOUT = 3000;
+
+    var dfdPromise =  App.ajax.send({
+      name: 'common.get.request.status',
+      sender: this,
+      data: {
+        requestId: requestId,
+        timeout: TIMEOUT
+      }
+    });
+
+    var successCallback = function(data) {
+      if (['PENDING','IN_PROGRESS'].contains(data.Requests.request_status)) {
+        window.setTimeout(function () {
+          self.getRequestStatus(requestId, requestCompletedDfd);
+        }, POLL_INTERVAL);
+      } else if (data.Requests.request_status === 'COMPLETED') {
+        requestCompletedDfd.resolve();
+      } else {
+        requestCompletedDfd.fail();
+      }
+    };
+
+    var errorCallback = function()  {
+      window.setTimeout(function () {
+        self.getRequestStatus(requestId, requestCompletedDfd);
+      }, POLL_INTERVAL);
+    };
+
+    dfdPromise.then(successCallback, errorCallback);
+  }
+});
\ No newline at end of file