You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2014/07/09 06:29:44 UTC

[1/6] AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Repository: ambari
Updated Branches:
  refs/heads/trunk ed65cfdd0 -> 00f8d5c5c


http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/service_components.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/service_components.js b/ambari-web/test/service_components.js
index a0e9a93..e4e475e 100644
--- a/ambari-web/test/service_components.js
+++ b/ambari-web/test/service_components.js
@@ -36,7 +36,8 @@ module.exports = {
             "service_name" : "MAPREDUCE",
             "stack_name" : "HDP",
             "stack_version" : "1.3.2"
-          }
+          },
+          "dependencies": []
         },
         {
           "StackServiceComponents" : {
@@ -47,7 +48,8 @@ module.exports = {
             "service_name" : "MAPREDUCE",
             "stack_name" : "HDP",
             "stack_version" : "1.3.2"
-          }
+          },
+          "dependencies": []
         },
         {
           "StackServiceComponents" : {
@@ -58,7 +60,8 @@ module.exports = {
             "service_name" : "MAPREDUCE",
             "stack_name" : "HDP",
             "stack_version" : "1.3.2"
-          }
+          },
+          "dependencies": []
         },
         {
           "StackServiceComponents" : {
@@ -69,21 +72,32 @@ module.exports = {
             "service_name" : "MAPREDUCE",
             "stack_name" : "HDP",
             "stack_version" : "1.3.2"
-          }
+          },
+          "dependencies": []
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/FALCON",
       "StackServices" : {
         "comments" : "Data management and processing platform",
+        "config_types" : [
+          "oozie-site",
+          "global",
+          "falcon-startup.properties",
+          "falcon-runtime.properties"
+        ],
         "service_name" : "FALCON",
-        "service_version" : "0.4.0.2.1.1",
+        "service_version" : "0.5.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/FALCON/serviceComponents/FALCON_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "CLIENT",
             "component_name" : "FALCON_CLIENT",
             "is_client" : true,
@@ -91,10 +105,13 @@ module.exports = {
             "service_name" : "FALCON",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/FALCON/serviceComponents/FALCON_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "FALCON_SERVER",
             "is_client" : false,
@@ -102,21 +119,61 @@ module.exports = {
             "service_name" : "FALCON",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/FLUME",
       "StackServices" : {
-        "comments" : "Ganglia Metrics Collection system",
+        "comments" : "Data management and processing platform",
+        "config_types" : [
+          "flume-conf",
+          "flume-log4j",
+          "global"
+        ],
+        "service_name" : "FLUME",
+        "service_version" : "1.4.0.2.1.1.0",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1",
+        "user_name" : null
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/FLUME/serviceComponents/FLUME_HANDLER",
+          "StackServiceComponents" : {
+            "cardinality" : null,
+            "component_category" : "SLAVE",
+            "component_name" : "FLUME_HANDLER",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "FLUME",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          },
+          "dependencies" : [ ]
+        }
+      ]
+    },
+    {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/GANGLIA",
+      "StackServices" : {
+        "comments" : "Ganglia Metrics Collection system (<a href=\"http://oss.oetiker.ch/rrdtool/\" target=\"_blank\">RRDTool</a> will be installed too)",
+        "config_types" : [
+          "global"
+        ],
         "service_name" : "GANGLIA",
         "service_version" : "3.5.0",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/GANGLIA/serviceComponents/GANGLIA_MONITOR",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "SLAVE",
             "component_name" : "GANGLIA_MONITOR",
             "is_client" : false,
@@ -124,10 +181,13 @@ module.exports = {
             "service_name" : "GANGLIA",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/GANGLIA/serviceComponents/GANGLIA_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "GANGLIA_SERVER",
             "is_client" : false,
@@ -135,21 +195,32 @@ module.exports = {
             "service_name" : "GANGLIA",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HBASE",
       "StackServices" : {
         "comments" : "Non-relational distributed database and centralized service for configuration management &\n        synchronization\n      ",
+        "config_types" : [
+          "global",
+          "hbase-policy",
+          "hbase-site",
+          "hbase-log4j"
+        ],
         "service_name" : "HBASE",
-        "service_version" : "0.96.0.2.1",
+        "service_version" : "0.98.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "CLIENT",
             "component_name" : "HBASE_CLIENT",
             "is_client" : true,
@@ -157,10 +228,13 @@ module.exports = {
             "service_name" : "HBASE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_MASTER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "HBASE_MASTER",
             "is_client" : false,
@@ -168,10 +242,34 @@ module.exports = {
             "service_name" : "HBASE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_MASTER/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "HBASE_MASTER",
+                "dependent_service_name" : "HBASE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_MASTER/dependencies/ZOOKEEPER_SERVER",
+              "Dependencies" : {
+                "component_name" : "ZOOKEEPER_SERVER",
+                "dependent_component_name" : "HBASE_MASTER",
+                "dependent_service_name" : "HBASE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_REGIONSERVER",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "SLAVE",
             "component_name" : "HBASE_REGIONSERVER",
             "is_client" : false,
@@ -179,21 +277,29 @@ module.exports = {
             "service_name" : "HBASE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HCATALOG",
       "StackServices" : {
         "comments" : "This is comment for HCATALOG service",
+        "config_types" : [
+          "global"
+        ],
         "service_name" : "HCATALOG",
         "service_version" : "0.12.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HCATALOG/serviceComponents/HCAT",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "CLIENT",
             "component_name" : "HCAT",
             "is_client" : true,
@@ -201,21 +307,33 @@ module.exports = {
             "service_name" : "HCATALOG",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS",
       "StackServices" : {
         "comments" : "Apache Hadoop Distributed File System",
+        "config_types" : [
+          "core-site",
+          "global",
+          "hdfs-site",
+          "hadoop-policy",
+          "hdfs-log4j"
+        ],
         "service_name" : "HDFS",
-        "service_version" : "2.1.0.2.1",
+        "service_version" : "2.4.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS/serviceComponents/DATANODE",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "SLAVE",
             "component_name" : "DATANODE",
             "is_client" : false,
@@ -223,10 +341,13 @@ module.exports = {
             "service_name" : "HDFS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS/serviceComponents/HDFS_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "CLIENT",
             "component_name" : "HDFS_CLIENT",
             "is_client" : true,
@@ -234,10 +355,13 @@ module.exports = {
             "service_name" : "HDFS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS/serviceComponents/JOURNALNODE",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "JOURNALNODE",
             "is_client" : false,
@@ -245,10 +369,13 @@ module.exports = {
             "service_name" : "HDFS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS/serviceComponents/NAMENODE",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "NAMENODE",
             "is_client" : false,
@@ -256,10 +383,13 @@ module.exports = {
             "service_name" : "HDFS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS/serviceComponents/SECONDARY_NAMENODE",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "SECONDARY_NAMENODE",
             "is_client" : false,
@@ -267,10 +397,13 @@ module.exports = {
             "service_name" : "HDFS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HDFS/serviceComponents/ZKFC",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "SLAVE",
             "component_name" : "ZKFC",
             "is_client" : false,
@@ -278,21 +411,33 @@ module.exports = {
             "service_name" : "HDFS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE",
       "StackServices" : {
         "comments" : "Data warehouse system for ad-hoc queries & analysis of large datasets and table & storage management service",
+        "config_types" : [
+          "hive-site",
+          "hive-log4j",
+          "hive-exec-log4j",
+          "global",
+          "mapred-site"
+        ],
         "service_name" : "HIVE",
-        "service_version" : "0.12.0.2.1",
+        "service_version" : "0.13.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "CLIENT",
             "component_name" : "HIVE_CLIENT",
             "is_client" : true,
@@ -300,10 +445,13 @@ module.exports = {
             "service_name" : "HIVE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_METASTORE",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "HIVE_METASTORE",
             "is_client" : false,
@@ -311,10 +459,17 @@ module.exports = {
             "service_name" : "HIVE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "auto_deploy" : {
+            "enabled" : true,
+            "location" : "HIVE/HIVE_SERVER"
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "HIVE_SERVER",
             "is_client" : false,
@@ -322,10 +477,54 @@ module.exports = {
             "service_name" : "HIVE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_SERVER/dependencies/MAPREDUCE2_CLIENT",
+              "Dependencies" : {
+                "component_name" : "MAPREDUCE2_CLIENT",
+                "dependent_component_name" : "HIVE_SERVER",
+                "dependent_service_name" : "HIVE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_SERVER/dependencies/TEZ_CLIENT",
+              "Dependencies" : {
+                "component_name" : "TEZ_CLIENT",
+                "dependent_component_name" : "HIVE_SERVER",
+                "dependent_service_name" : "HIVE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_SERVER/dependencies/YARN_CLIENT",
+              "Dependencies" : {
+                "component_name" : "YARN_CLIENT",
+                "dependent_component_name" : "HIVE_SERVER",
+                "dependent_service_name" : "HIVE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_SERVER/dependencies/ZOOKEEPER_SERVER",
+              "Dependencies" : {
+                "component_name" : "ZOOKEEPER_SERVER",
+                "dependent_component_name" : "HIVE_SERVER",
+                "dependent_service_name" : "HIVE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/HIVE/serviceComponents/MYSQL_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "MYSQL_SERVER",
             "is_client" : false,
@@ -333,21 +532,36 @@ module.exports = {
             "service_name" : "HIVE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "auto_deploy" : {
+            "enabled" : true,
+            "location" : "HIVE/HIVE_SERVER"
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/MAPREDUCE2",
       "StackServices" : {
         "comments" : "Apache Hadoop NextGen MapReduce (YARN)",
+        "config_types" : [
+          "core-site",
+          "global",
+          "mapred-site",
+          "mapred-queue-acls"
+        ],
         "service_name" : "MAPREDUCE2",
         "service_version" : "2.1.0.2.0.6.0",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/MAPREDUCE2/serviceComponents/HISTORYSERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "HISTORYSERVER",
             "is_client" : false,
@@ -355,10 +569,28 @@ module.exports = {
             "service_name" : "MAPREDUCE2",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "auto_deploy" : {
+            "enabled" : true,
+            "location" : "YARN/RESOURCEMANAGER"
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/MAPREDUCE2/serviceComponents/HISTORYSERVER/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "HISTORYSERVER",
+                "dependent_service_name" : "MAPREDUCE2",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/MAPREDUCE2/serviceComponents/MAPREDUCE2_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : "0+",
             "component_category" : "CLIENT",
             "component_name" : "MAPREDUCE2_CLIENT",
             "is_client" : true,
@@ -366,21 +598,29 @@ module.exports = {
             "service_name" : "MAPREDUCE2",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS",
       "StackServices" : {
         "comments" : "Nagios Monitoring and Alerting system",
+        "config_types" : [
+          "global"
+        ],
         "service_name" : "NAGIOS",
         "service_version" : "3.5.0",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "NAGIOS_SERVER",
             "is_client" : false,
@@ -388,21 +628,92 @@ module.exports = {
             "service_name" : "NAGIOS",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER/dependencies/HCAT",
+              "Dependencies" : {
+                "component_name" : "HCAT",
+                "dependent_component_name" : "NAGIOS_SERVER",
+                "dependent_service_name" : "NAGIOS",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "NAGIOS_SERVER",
+                "dependent_service_name" : "NAGIOS",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER/dependencies/MAPREDUCE2_CLIENT",
+              "Dependencies" : {
+                "component_name" : "MAPREDUCE2_CLIENT",
+                "dependent_component_name" : "NAGIOS_SERVER",
+                "dependent_service_name" : "NAGIOS",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER/dependencies/OOZIE_CLIENT",
+              "Dependencies" : {
+                "component_name" : "OOZIE_CLIENT",
+                "dependent_component_name" : "NAGIOS_SERVER",
+                "dependent_service_name" : "NAGIOS",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER/dependencies/TEZ_CLIENT",
+              "Dependencies" : {
+                "component_name" : "TEZ_CLIENT",
+                "dependent_component_name" : "NAGIOS_SERVER",
+                "dependent_service_name" : "NAGIOS",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER/dependencies/YARN_CLIENT",
+              "Dependencies" : {
+                "component_name" : "YARN_CLIENT",
+                "dependent_component_name" : "NAGIOS_SERVER",
+                "dependent_service_name" : "NAGIOS",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE",
       "StackServices" : {
         "comments" : "System for workflow coordination and execution of Apache Hadoop jobs.  This also includes the installation of the optional Oozie Web Console which relies on and will install the <a target=\"_blank\" href=\"http://www.sencha.com/products/extjs/license/\">ExtJS</a> Library.\n      ",
+        "config_types" : [
+          "global",
+          "oozie-site",
+          "oozie-log4j"
+        ],
         "service_name" : "OOZIE",
         "service_version" : "4.0.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : "0+",
             "component_category" : "CLIENT",
             "component_name" : "OOZIE_CLIENT",
             "is_client" : true,
@@ -410,10 +721,34 @@ module.exports = {
             "service_name" : "OOZIE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_CLIENT/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "OOZIE_CLIENT",
+                "dependent_service_name" : "OOZIE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_CLIENT/dependencies/MAPREDUCE2_CLIENT",
+              "Dependencies" : {
+                "component_name" : "MAPREDUCE2_CLIENT",
+                "dependent_component_name" : "OOZIE_CLIENT",
+                "dependent_service_name" : "OOZIE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "OOZIE_SERVER",
             "is_client" : false,
@@ -421,21 +756,61 @@ module.exports = {
             "service_name" : "OOZIE",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_SERVER/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "OOZIE_SERVER",
+                "dependent_service_name" : "OOZIE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_SERVER/dependencies/MAPREDUCE2_CLIENT",
+              "Dependencies" : {
+                "component_name" : "MAPREDUCE2_CLIENT",
+                "dependent_component_name" : "OOZIE_SERVER",
+                "dependent_service_name" : "OOZIE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_SERVER/dependencies/YARN_CLIENT",
+              "Dependencies" : {
+                "component_name" : "YARN_CLIENT",
+                "dependent_component_name" : "OOZIE_SERVER",
+                "dependent_service_name" : "OOZIE",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/PIG",
       "StackServices" : {
         "comments" : "Scripting platform for analyzing large datasets",
+        "config_types" : [
+          "global",
+          "pig-log4j"
+        ],
         "service_name" : "PIG",
-        "service_version" : "0.12.0.2.1",
+        "service_version" : "0.12.1.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/PIG/serviceComponents/PIG",
           "StackServiceComponents" : {
+            "cardinality" : "0+",
             "component_category" : "CLIENT",
             "component_name" : "PIG",
             "is_client" : true,
@@ -443,21 +818,27 @@ module.exports = {
             "service_name" : "PIG",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/SQOOP",
       "StackServices" : {
         "comments" : "Tool for transferring bulk data between Apache Hadoop and\n        structured data stores such as relational databases\n      ",
+        "config_types" : [ ],
         "service_name" : "SQOOP",
         "service_version" : "1.4.4.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/SQOOP/serviceComponents/SQOOP",
           "StackServiceComponents" : {
+            "cardinality" : "0+",
             "component_category" : "CLIENT",
             "component_name" : "SQOOP",
             "is_client" : true,
@@ -465,21 +846,51 @@ module.exports = {
             "service_name" : "SQOOP",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/SQOOP/serviceComponents/SQOOP/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "SQOOP",
+                "dependent_service_name" : "SQOOP",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/SQOOP/serviceComponents/SQOOP/dependencies/MAPREDUCE2_CLIENT",
+              "Dependencies" : {
+                "component_name" : "MAPREDUCE2_CLIENT",
+                "dependent_component_name" : "SQOOP",
+                "dependent_service_name" : "SQOOP",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/STORM",
       "StackServices" : {
         "comments" : "Apache Hadoop Stream processing framework",
+        "config_types" : [
+          "storm-site",
+          "global"
+        ],
         "service_name" : "STORM",
-        "service_version" : "0.9.0.1",
+        "service_version" : "0.9.1.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/STORM/serviceComponents/DRPC_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "DRPC_SERVER",
             "is_client" : false,
@@ -487,21 +898,13 @@ module.exports = {
             "service_name" : "STORM",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
-        },
-        {
-          "StackServiceComponents" : {
-            "component_category" : "MASTER",
-            "component_name" : "LOGVIEWER_SERVER",
-            "is_client" : false,
-            "is_master" : true,
-            "service_name" : "STORM",
-            "stack_name" : "HDP",
-            "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/STORM/serviceComponents/NIMBUS",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "NIMBUS",
             "is_client" : false,
@@ -509,10 +912,13 @@ module.exports = {
             "service_name" : "STORM",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/STORM/serviceComponents/STORM_REST_API",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "STORM_REST_API",
             "is_client" : false,
@@ -520,10 +926,13 @@ module.exports = {
             "service_name" : "STORM",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/STORM/serviceComponents/STORM_UI_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "MASTER",
             "component_name" : "STORM_UI_SERVER",
             "is_client" : false,
@@ -531,10 +940,13 @@ module.exports = {
             "service_name" : "STORM",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/STORM/serviceComponents/SUPERVISOR",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "SLAVE",
             "component_name" : "SUPERVISOR",
             "is_client" : false,
@@ -542,21 +954,30 @@ module.exports = {
             "service_name" : "STORM",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/TEZ",
       "StackServices" : {
         "comments" : "Tez is the next generation Hadoop Query Processing framework written on top of YARN.",
+        "config_types" : [
+          "global",
+          "tez-site"
+        ],
         "service_name" : "TEZ",
         "service_version" : "0.4.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/TEZ/serviceComponents/TEZ_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : null,
             "component_category" : "CLIENT",
             "component_name" : "TEZ_CLIENT",
             "is_client" : true,
@@ -564,21 +985,29 @@ module.exports = {
             "service_name" : "TEZ",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT",
       "StackServices" : {
         "comments" : "This is comment for WEBHCAT service",
+        "config_types" : [
+          "webhcat-site"
+        ],
         "service_name" : "WEBHCAT",
-        "service_version" : "0.12.0.2.1",
+        "service_version" : "0.13.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "WEBHCAT_SERVER",
             "is_client" : false,
@@ -586,32 +1015,100 @@ module.exports = {
             "service_name" : "WEBHCAT",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER/dependencies/HDFS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "HDFS_CLIENT",
+                "dependent_component_name" : "WEBHCAT_SERVER",
+                "dependent_service_name" : "WEBHCAT",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER/dependencies/MAPREDUCE2_CLIENT",
+              "Dependencies" : {
+                "component_name" : "MAPREDUCE2_CLIENT",
+                "dependent_component_name" : "WEBHCAT_SERVER",
+                "dependent_service_name" : "WEBHCAT",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER/dependencies/YARN_CLIENT",
+              "Dependencies" : {
+                "component_name" : "YARN_CLIENT",
+                "dependent_component_name" : "WEBHCAT_SERVER",
+                "dependent_service_name" : "WEBHCAT",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER/dependencies/ZOOKEEPER_CLIENT",
+              "Dependencies" : {
+                "component_name" : "ZOOKEEPER_CLIENT",
+                "dependent_component_name" : "WEBHCAT_SERVER",
+                "dependent_service_name" : "WEBHCAT",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            },
+            {
+              "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER/dependencies/ZOOKEEPER_SERVER",
+              "Dependencies" : {
+                "component_name" : "ZOOKEEPER_SERVER",
+                "dependent_component_name" : "WEBHCAT_SERVER",
+                "dependent_service_name" : "WEBHCAT",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/YARN",
       "StackServices" : {
         "comments" : "Apache Hadoop NextGen MapReduce (YARN)",
+        "config_types" : [
+          "yarn-site",
+          "capacity-scheduler",
+          "core-site",
+          "global",
+          "yarn-log4j",
+          "mapred-site",
+          "mapred-queue-acls"
+        ],
         "service_name" : "YARN",
-        "service_version" : "2.1.0.2.1",
+        "service_version" : "2.4.0.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/YARN/serviceComponents/APP_TIMELINE_SERVER",
           "StackServiceComponents" : {
-            "component_category" : "MASTER",
+            "cardinality" : null,
+            "component_category" : "SLAVE",
             "component_name" : "APP_TIMELINE_SERVER",
             "is_client" : false,
-            "is_master" : true,
+            "is_master" : false,
             "service_name" : "YARN",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/YARN/serviceComponents/NODEMANAGER",
           "StackServiceComponents" : {
+            "cardinality" : "1+",
             "component_category" : "SLAVE",
             "component_name" : "NODEMANAGER",
             "is_client" : false,
@@ -619,10 +1116,13 @@ module.exports = {
             "service_name" : "YARN",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/YARN/serviceComponents/RESOURCEMANAGER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "RESOURCEMANAGER",
             "is_client" : false,
@@ -630,10 +1130,13 @@ module.exports = {
             "service_name" : "YARN",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/YARN/serviceComponents/YARN_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : "0+",
             "component_category" : "CLIENT",
             "component_name" : "YARN_CLIENT",
             "is_client" : true,
@@ -641,21 +1144,31 @@ module.exports = {
             "service_name" : "YARN",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     },
     {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/ZOOKEEPER",
       "StackServices" : {
         "comments" : "Centralized service which provides highly reliable distributed\n        coordination.",
+        "config_types" : [
+          "global",
+          "zookeeper-log4j",
+          "zoo.cfg"
+        ],
         "service_name" : "ZOOKEEPER",
         "service_version" : "3.4.5.2.1",
         "stack_name" : "HDP",
-        "stack_version" : "2.1"
+        "stack_version" : "2.1",
+        "user_name" : null
       },
       "serviceComponents" : [
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/ZOOKEEPER/serviceComponents/ZOOKEEPER_CLIENT",
           "StackServiceComponents" : {
+            "cardinality" : "0+",
             "component_category" : "CLIENT",
             "component_name" : "ZOOKEEPER_CLIENT",
             "is_client" : true,
@@ -663,10 +1176,13 @@ module.exports = {
             "service_name" : "ZOOKEEPER",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         },
         {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks2/HDP/versions/2.1/stackServices/ZOOKEEPER/serviceComponents/ZOOKEEPER_SERVER",
           "StackServiceComponents" : {
+            "cardinality" : "1",
             "component_category" : "MASTER",
             "component_name" : "ZOOKEEPER_SERVER",
             "is_client" : false,
@@ -674,9 +1190,10 @@ module.exports = {
             "service_name" : "ZOOKEEPER",
             "stack_name" : "HDP",
             "stack_version" : "2.1"
-          }
+          },
+          "dependencies" : [ ]
         }
       ]
     }
   ]
-};
\ No newline at end of file
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/utils/component_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/component_test.js b/ambari-web/test/utils/component_test.js
index f98f9e2..a304d17 100644
--- a/ambari-web/test/utils/component_test.js
+++ b/ambari-web/test/utils/component_test.js
@@ -22,75 +22,4 @@ require('models/host_component');
 require('models/stack_service_component');
 
 describe('utils/component', function(){
-  describe('#loadStackServiceComponentModel()', function(){
-    var data = {
-      "items": [
-        {
-          "serviceComponents": [
-            {
-              "StackServiceComponents": {
-                "component_category": "CLIENT",
-                "component_name": "FALCON_CLIENT",
-                "is_client": true,
-                "is_master": false,
-                "service_name": "FALCON",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            },
-            {
-              "StackServiceComponents": {
-                "component_category": "MASTER",
-                "component_name": "FALCON_SERVER",
-                "is_client": false,
-                "is_master": true,
-                "service_name": "FALCON",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            }
-          ]
-        },
-        {
-          "serviceComponents": [
-            {
-              "StackServiceComponents": {
-                "component_category": "SLAVE",
-                "component_name": "GANGLIA_MONITOR",
-                "is_client": false,
-                "is_master": false,
-                "service_name": "GANGLIA",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            },
-            {
-              "StackServiceComponents": {
-                "component_category": "MASTER",
-                "component_name": "GANGLIA_SERVER",
-                "is_client": false,
-                "is_master": true,
-                "service_name": "GANGLIA",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            }
-          ]
-        }
-      ]
-    };
-
-    afterEach(function(){
-      App.StackServiceComponent.find().set('content', []);
-    });
-
-    it('should return 4 components', function(){
-      expect(component.loadStackServiceComponentModel(data).items.length).to.eql(4);
-    });
-
-    it('should load data to StackServiceComponent model', function(){
-      component.loadStackServiceComponentModel(data);
-      expect(App.StackServiceComponent.find().get('content')).have.length(4);
-    });
-  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/utils/helper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/helper_test.js b/ambari-web/test/utils/helper_test.js
index 8918b39..27b1c2f 100644
--- a/ambari-web/test/utils/helper_test.js
+++ b/ambari-web/test/utils/helper_test.js
@@ -204,6 +204,92 @@ describe('utils/helper', function() {
           });
         });
       });
+      describe('#normalizeName()', function() {
+        var testMessage = '`{0}` should be converted to `{1}`';
+        var tests = {
+          'APP_TIMELINE_SERVER': 'App Timeline Server',
+          'DATANODE': 'DataNode',
+          'DECOMMISSION_DATANODE': 'Update Exclude File',
+          'DRPC_SERVER': 'DRPC Server',
+          'FALCON': 'Falcon',
+          'FALCON_CLIENT': 'Falcon Client',
+          'FALCON_SERVER': 'Falcon Server',
+          'FALCON_SERVICE_CHECK': 'Falcon Service Check',
+          'FLUME_HANDLER': 'Flume Agent',
+          'FLUME_SERVICE_CHECK': 'Flume Service Check',
+          'GANGLIA_MONITOR': 'Ganglia Monitor',
+          'GANGLIA_SERVER': 'Ganglia Server',
+          'GLUSTERFS_CLIENT': 'GLUSTERFS Client',
+          'GLUSTERFS_SERVICE_CHECK': 'GLUSTERFS Service Check',
+          'GMETAD_SERVICE_CHECK': 'Gmetad Service Check',
+          'GMOND_SERVICE_CHECK': 'Gmond Service Check',
+          'HADOOP_CLIENT': 'Hadoop Client',
+          'HBASE_CLIENT': 'HBase Client',
+          'HBASE_MASTER': 'HBase Master',
+          'HBASE_REGIONSERVER': 'RegionServer',
+          'HBASE_SERVICE_CHECK': 'HBase Service Check',
+          'HCAT': 'HCat',
+          'HCAT_SERVICE_CHECK': 'HCat Service Check',
+          'HDFS': 'HDFS',
+          'HDFS_CLIENT': 'HDFS Client',
+          'HDFS_SERVICE_CHECK': 'HDFS Service Check',
+          'HISTORYSERVER': 'History Server',
+          'HIVE_CLIENT': 'Hive Client',
+          'HIVE_METASTORE': 'Hive Metastore',
+          'HIVE_SERVER': 'HiveServer2',
+          'HIVE_SERVICE_CHECK': 'Hive Service Check',
+          'HUE_SERVER': 'Hue Server',
+          'JAVA_JCE': 'Java JCE',
+          'JOBTRACKER': 'JobTracker',
+          'JOBTRACKER_SERVICE_CHECK': 'JobTracker Service Check',
+          'JOURNALNODE': 'JournalNode',
+          'KERBEROS_ADMIN_CLIENT': 'Kerberos Admin Client',
+          'KERBEROS_CLIENT': 'Kerberos Client',
+          'KERBEROS_SERVER': 'Kerberos Server',
+          'MAPREDUCE2_CLIENT': 'MapReduce2 Client',
+          'MAPREDUCE2_SERVICE_CHECK': 'MapReduce2 Service Check',
+          'MAPREDUCE_CLIENT': 'MapReduce Client',
+          'MAPREDUCE_SERVICE_CHECK': 'MapReduce Service Check',
+          'MYSQL_SERVER': 'MySQL Server',
+          'NAGIOS_SERVER': 'Nagios Server',
+          'NAMENODE': 'NameNode',
+          'NAMENODE_SERVICE_CHECK': 'NameNode Service Check',
+          'NIMBUS': 'Nimbus',
+          'NODEMANAGER': 'NodeManager',
+          'OOZIE_CLIENT': 'Oozie Client',
+          'OOZIE_SERVER': 'Oozie Server',
+          'OOZIE_SERVICE_CHECK': 'Oozie Service Check',
+          'PIG': 'Pig',
+          'PIG_SERVICE_CHECK': 'Pig Service Check',
+          'RESOURCEMANAGER': 'ResourceManager',
+          'SECONDARY_NAMENODE': 'SNameNode',
+          'SQOOP': 'Sqoop',
+          'SQOOP_SERVICE_CHECK': 'Sqoop Service Check',
+          'STORM_REST_API': 'Storm REST API Server',
+          'STORM_SERVICE_CHECK': 'Storm Service Check',
+          'STORM_UI_SERVER': 'Storm UI Server',
+          'SUPERVISOR': 'Supervisor',
+          'TASKTRACKER': 'TaskTracker',
+          'TEZ_CLIENT': 'Tez Client',
+          'WEBHCAT_SERVER': 'WebHCat Server',
+          'WEBHCAT_SERVICE_CHECK': 'WebHCat Service Check',
+          'YARN_CLIENT': 'YARN Client',
+          'YARN_SERVICE_CHECK': 'YARN Service Check',
+          'ZKFC': 'ZKFailoverController',
+          'ZOOKEEPER_CLIENT': 'ZooKeeper Client',
+          'ZOOKEEPER_QUORUM_SERVICE_CHECK': 'ZK Quorum Service Check',
+          'ZOOKEEPER_SERVER': 'ZooKeeper Server',
+          'ZOOKEEPER_SERVICE_CHECK': 'ZooKeeper Service Check',
+          'CLIENT': 'Client'
+        };
+        for (var inputName in tests) {
+          (function(name) {
+            it(testMessage.format(name, tests[name]), function() {
+              expect(App.format.normalizeName(name)).to.eql(tests[name]);
+            });
+          })(inputName)
+        }
+      });
     });
   });
   describe('#App.permit()', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/views/wizard/step5_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/wizard/step5_view_test.js b/ambari-web/test/views/wizard/step5_view_test.js
index 7107461..9cf6bdf 100644
--- a/ambari-web/test/views/wizard/step5_view_test.js
+++ b/ambari-web/test/views/wizard/step5_view_test.js
@@ -52,6 +52,7 @@ describe('App.WizardStep5View', function() {
 });
 
 describe('App.SelectHostView', function() {
+  var models = require('test/init_model_test');
 
   beforeEach(function() {
     view = App.SelectHostView.create({
@@ -65,17 +66,18 @@ describe('App.SelectHostView', function() {
 
     beforeEach(function() {
       sinon.stub(view, 'initContent', Em.K);
+      models.setupStackServiceComponent();
     });
 
     afterEach(function() {
       view.initContent.restore();
+      models.cleanStackServiceComponent();
     });
 
     it('should call initContent', function() {
       view.click();
       expect(view.initContent.calledOnce).to.be.true;
     });
-
   });
 
   describe('#didInsertElement', function() {


[2/6] AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Posted by yu...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/item.js b/ambari-web/app/views/main/service/item.js
index 4ee6a64..15d9835 100644
--- a/ambari-web/app/views/main/service/item.js
+++ b/ambari-web/app/views/main/service/item.js
@@ -30,7 +30,7 @@ App.MainServiceItemView = Em.View.extend({
     var serviceName = service.get('serviceName');
     var disableRefreshConfgis = !service.get('isRestartRequired');
 
-    if (service.get('isClientsOnly')) {
+    if (this.get('controller.isClientsOnlyService')) {
       if (serviceName != 'TEZ') {
         options.push({action: 'runSmokeTest', cssClass: 'icon-thumbs-up-alt', 'label': Em.I18n.t('services.service.actions.run.smoke')});
       }
@@ -84,13 +84,13 @@ App.MainServiceItemView = Em.View.extend({
       options.push({action:'turnOnOffPassive', cssClass: 'icon-medkit', context:requestLabel, 'label':passiveLabel , disabled: false});
     }
     return options;
-  }.property('controller.content', 'controller.isStopDisabled'),
+  }.property('controller.content', 'controller.isStopDisabled','controller.isClientsOnlyService'),
   isMaintenanceActive: function() {
     return this.get('maintenance').length !== 0;
   }.property('maintenance'),
-  hasConfigTab: function(){
-    return this.get("controller.content.isConfigurable");
-  }.property('controller.content.isConfigurable'),
+  hasConfigTab: function() {
+    return !App.get('services.noConfigTypes').concat('HCATALOG').contains('controller.content.serviceName');
+  }.property('controller.content.serviceName','App.services.noConfigTypes'),
 
   didInsertElement: function () {
     this.get('controller').setStartStopState();

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/service/menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/menu.js b/ambari-web/app/views/main/service/menu.js
index de81134..562ddf0 100644
--- a/ambari-web/app/views/main/service/menu.js
+++ b/ambari-web/app/views/main/service/menu.js
@@ -26,7 +26,8 @@ App.MainServiceMenuView = Em.CollectionView.extend({
     var items = App.router.get('mainServiceController.content').filter(function(item){
       return !this.get('disabledServices').contains(item.get('id'));
     }, this);
-    return misc.sortByOrder(App.Service.servicesSortOrder, items);
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    return misc.sortByOrder(stackServices, items);
   }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
 
   didInsertElement:function () {
@@ -73,12 +74,16 @@ App.MainServiceMenuView = Em.CollectionView.extend({
       return this.get('content.criticalAlertsCount');
     }.property('content.criticalAlertsCount'),
 
+    isConfigurable: function () {
+      return !App.get('services.noConfigTypes').concat('HCATALOG').contains('content.serviceName');
+    }.property('App.services.noConfigTypes','content.serviceName'),
+
     link: function() {
       var stateName = (['summary','configs'].contains(App.router.get('currentState.name')))
-        ? this.get('content.isConfigurable') ?  App.router.get('currentState.name') : 'summary'
+        ? this.get('isConfigurable') ?  App.router.get('currentState.name') : 'summary'
         : 'summary';
       return "#/main/services/" + this.get('content.id') + "/" + stateName;
-    }.property('App.router.currentState.name', 'parentView.activeServiceId'),
+    }.property('App.router.currentState.name', 'parentView.activeServiceId', 'isConfigurable'),
 
     refreshRestartRequiredMessage: function() {
       var restarted, componentsCount, hostsCount, message, tHosts, tComponents;
@@ -115,7 +120,8 @@ App.TopNavServiceMenuView = Em.CollectionView.extend({
     var items = App.router.get('mainServiceController.content').filter(function(item){
       return !this.get('disabledServices').contains(item.get('id'));
     }, this);
-    return misc.sortByOrder(App.Service.servicesSortOrder, items);
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    return misc.sortByOrder(stackServices, items);
   }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
 
   didInsertElement:function () {
@@ -160,12 +166,16 @@ App.TopNavServiceMenuView = Em.CollectionView.extend({
       return this.get('content.criticalAlertsCount');
     }.property('content.criticalAlertsCount'),
 
+    isConfigurable: function () {
+      return !App.get('services.noConfigTypes').concat('HCATALOG').contains('content.serviceName');
+    }.property('App.services.noConfigTypes','content.serviceName'),
+
     link: function() {
       var stateName = (['summary','configs'].contains(App.router.get('currentState.name')))
-        ? this.get('content.isConfigurable') ?  App.router.get('currentState.name') : 'summary'
+        ? this.get('isConfigurable') ?  App.router.get('currentState.name') : 'summary'
         : 'summary';
       return "#/main/services/" + this.get('content.id') + "/" + stateName;
-    }.property('App.router.currentState.name', 'parentView.activeServiceId'),
+    }.property('App.router.currentState.name', 'parentView.activeServiceId','isConfigurable'),
 
     refreshRestartRequiredMessage: function() {
       var restarted, componentsCount, hostsCount, message, tHosts, tComponents;

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/service/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/service.js b/ambari-web/app/views/main/service/service.js
index b8b6c42..7f48ac9 100644
--- a/ambari-web/app/views/main/service/service.js
+++ b/ambari-web/app/views/main/service/service.js
@@ -52,7 +52,8 @@ App.MainDashboardServiceHealthView = Em.View.extend({
   },
 
   healthStatus: function () {
-    if (this.get('service.isClientsOnly')) {
+    var isClientOnlyService = App.get('services.clientOnly').contains(this.get('service.serviceName'));
+    if (isClientOnlyService) {
       return 'icon-laptop';
     }
     if (this.get('service.passiveState') != 'OFF') {
@@ -82,7 +83,7 @@ App.MainDashboardServiceHealthView = Em.View.extend({
     }
 
     return 'health-status-' + status;
-  }.property('service.healthStatus','service.passiveState','service.isClientsOnly'),
+  }.property('service.healthStatus','service.passiveState','service.serviceName'),
 
   healthStatusClass: function () {
     switch (this.get('healthStatus')) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/wizard/step5_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step5_view.js b/ambari-web/app/views/wizard/step5_view.js
index 2a5fb34..c78cb4c 100644
--- a/ambari-web/app/views/wizard/step5_view.js
+++ b/ambari-web/app/views/wizard/step5_view.js
@@ -17,6 +17,7 @@
  */
 
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 App.WizardStep5View = Em.View.extend({
 
@@ -33,14 +34,30 @@ App.WizardStep5View = Em.View.extend({
 
   didInsertElement: function () {
     this.get('controller').loadStep();
-  }
+    this.setCoHostedComponentText();
+  },
+
+  coHostedComponentText: '',
+
+  setCoHostedComponentText: function () {
+    var coHostedComponents = App.StackServiceComponent.find().filterProperty('isOtherComponentCoHosted').filterProperty('stackService.isSelected');
+    var coHostedComponentsText = '';
+    coHostedComponents.forEach(function (serviceComponent, index) {
+      var coHostedComponentsDisplayNames = serviceComponent.get('coHostedComponents').map(function (item) {
+        return App.StackServiceComponent.find().findProperty('componentName', item).get('displayName');
+      });
+      var componentTextArr = [serviceComponent.get('displayName')].concat(coHostedComponentsDisplayNames);
+      coHostedComponents[index] = stringUtils.getFormattedStringFromArray(componentTextArr);
+      coHostedComponentsText += '<br/>' + Em.I18n.t('installer.step5.body.coHostedComponents').format(coHostedComponents[index]);
+    }, this);
 
+    this.set('coHostedComponentText', coHostedComponentsText);
+  }
 });
 
 App.InputHostView = Em.TextField.extend(App.SelectHost, {
 
   attributeBindings: ['disabled'],
-
   /**
    * Saved typeahead component
    * @type {$}
@@ -162,7 +179,7 @@ App.RemoveControlView = Em.View.extend({
    * Index for multiple component
    * @type {number}
    */
-  zId: null,
+  serviceComponentId: null,
 
   /**
    * Current component name
@@ -182,6 +199,6 @@ App.RemoveControlView = Em.View.extend({
    * @method click
    */
   click: function () {
-    this.get('controller').removeComponent(this.get('componentName'), this.get("zId"));
+    this.get('controller').removeComponent(this.get('componentName'), this.get("serviceComponentId"));
   }
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/wizard/step6_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step6_view.js b/ambari-web/app/views/wizard/step6_view.js
index 39c37aa..c700565 100644
--- a/ambari-web/app/views/wizard/step6_view.js
+++ b/ambari-web/app/views/wizard/step6_view.js
@@ -53,14 +53,9 @@ App.WizardStep6View = App.TableView.extend({
    */
   didInsertElement: function () {
     var controller = this.get('controller');
-    if (controller.get('isMasters')) {
-      this.set('label', Em.I18n.t('installer.step6.addHostWizard.body'));
-      this.set('title', Em.I18n.t('installer.step5.header'));
-    }
-    else {
-      this.set('title', Em.I18n.t('installer.step6.header'));
-      this.setLabel();
-    }
+    this.set('title', Em.I18n.t('installer.step6.header'));
+    this.setLabel();
+
     App.tooltip($('body'), {selector: '[rel=tooltip]'});
     controller.loadStep();
   },
@@ -113,8 +108,6 @@ App.WizardStep6HostView = Em.View.extend({
    * @method didInsertElement
    */
   didInsertElement: function () {
-    if(this.get('controller.isMasters')) return;
-
     var components = this.get('controller').getMasterComponentsForHost(this.get('host.hostName'));
     if (components && components.length > 0) {
       components = components.map(function (_component) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/app_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/app_test.js b/ambari-web/test/app_test.js
index 3b0565b..a5b4d76 100644
--- a/ambari-web/test/app_test.js
+++ b/ambari-web/test/app_test.js
@@ -92,14 +92,15 @@ describe('#App', function() {
 
     var globalProperties = require('data/HDP2/global_properties');
     var siteProperties = require('data/HDP2/site_properties');
+
     var reviewConfigs = require('data/review_configs');
     var disableResult = App.disableComponent(testableComponent);
 
+
     describe('#disableComponent()', function() {
       // copy
       var _globalProperties = $.extend({}, globalProperties);
       var _siteProperties = $.extend({}, siteProperties);
-      var _reviewConfigs = JSON.parse(JSON.stringify(reviewConfigs));
 
       describe('result validation', function() {
 
@@ -139,12 +140,6 @@ describe('#App', function() {
           expect(_siteProperties.configProperties.mapProperty('name')).to.not.include.members(expectedInfo.properties.site_properties);
         });
 
-        it('should remove review config for component', function() {
-          var reviewConfig = _reviewConfigs.findProperty('config_name', 'services')
-            .config_value.findProperty('service_name', testableComponent.get('serviceName'))
-            .service_components.mapProperty('component_name');
-          expect(reviewConfig).to.not.include(expectedInfo.reviewConfigs.component_name);
-        });
       });
     });
 
@@ -158,13 +153,6 @@ describe('#App', function() {
       it('should add site properties of component', function() {
         expect(siteProperties.configProperties.mapProperty('name')).to.include.members(expectedInfo.properties.site_properties);
       });
-
-      it('should add review config for component', function() {
-        var reviewConfig = reviewConfigs.findProperty('config_name', 'services')
-          .config_value.findProperty('service_name', testableComponent.get('serviceName'))
-          .get('service_components').mapProperty('component_name');
-        expect(reviewConfig).to.include(expectedInfo.reviewConfigs.component_name);
-      });
     });
 
     modelSetup.restoreStackVersion(this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/main/host/add_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/add_controller_test.js b/ambari-web/test/controllers/main/host/add_controller_test.js
index 6ca3f0d..4bdeae3 100644
--- a/ambari-web/test/controllers/main/host/add_controller_test.js
+++ b/ambari-web/test/controllers/main/host/add_controller_test.js
@@ -119,30 +119,30 @@ describe('App.AddHostController', function () {
       {
         title: 'Service is not in stack',
         services: [
-          {
+          Em.Object.create({
             serviceName: 'TEST',
             isSelected: true
-          }
+          })
         ],
         result: []
       },
       {
         title: 'Service does not have any clients',
         services: [
-          {
+          Em.Object.create({
             serviceName: 'GANGLIA',
             isSelected: true
-          }
+          })
         ],
         result: []
       },
       {
         title: 'StackServiceComponent is empty',
         services: [
-          {
+          Em.Object.create({
             serviceName: 'HDFS',
             isSelected: true
-          }
+          })
         ],
         result: []
       }
@@ -160,10 +160,10 @@ describe('App.AddHostController', function () {
     it('HDFS has uninstalled client', function () {
       modelSetup.setupStackServiceComponent();
       var services = [
-        {
+        Em.Object.create({
           serviceName: 'HDFS',
           isSelected: true
-        }
+        })
       ];
       controller.set('content.services', services);
       controller.saveClients();
@@ -186,10 +186,10 @@ describe('App.AddHostController', function () {
     it('HDFS has installed client', function () {
       modelSetup.setupStackServiceComponent();
       var services = [
-        {
+        Em.Object.create({
           serviceName: 'HDFS',
           isSelected: true
-        }
+        })
       ];
       App.store.load(App.HostComponent, {
         id: 'HDFS_CLIENT_host1',

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/main/host/details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js
index 624af19..058ac57 100644
--- a/ambari-web/test/controllers/main/host/details_test.js
+++ b/ambari-web/test/controllers/main/host/details_test.js
@@ -913,6 +913,7 @@ describe('App.MainHostDetailsController', function () {
       controller.doDecommissionRegionServer.restore();
       controller.doDecommission.restore();
       controller.showBackgroundOperationsPopup.restore();
+      controller.doDecommissionRegionServer.restore();
     });
 
     it('HDFS service', function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/wizard/step4_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step4_test.js b/ambari-web/test/controllers/wizard/step4_test.js
index a1d9ed5..71c417b 100644
--- a/ambari-web/test/controllers/wizard/step4_test.js
+++ b/ambari-web/test/controllers/wizard/step4_test.js
@@ -30,7 +30,7 @@ describe('App.WizardStep4Controller', function () {
   var controller = App.WizardStep4Controller.create();
   services.forEach(function(serviceName, index){
     controller.pushObject(Ember.Object.create({
-      'serviceName':serviceName, 'isSelected': true, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': 'HDFS' === serviceName
+      'serviceName':serviceName, 'isSelected': true, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': 'HDFS' === serviceName, isDFS: 'HDFS' === serviceName
     }));
   });
 
@@ -78,145 +78,14 @@ describe('App.WizardStep4Controller', function () {
   });
 
   describe('#selectMinimum()', function () {
-    it('should set isSelected false for all not disabled services', function () {
+    it('should set isSelected false for all services', function () {
       controller.setEach('isSelected', true);
       controller.selectMinimum();
-      expect(controller.findProperty('serviceName', 'HDFS').get('isSelected')).to.equal(true);
+      expect(controller.findProperty('serviceName', 'HDFS').get('isSelected')).to.equal(false);
       expect(controller.filterProperty('isDisabled', false).everyProperty('isSelected', false)).to.equal(true);
     });
   });
 
-  describe('#needToAddMapReduce()', function () {
-    it('should return true if Pig is selected and MapReduce is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'PIG').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(true);
-    });
-
-    it('should return true if Oozie is selected and MapReduce is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'OOZIE').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(true);
-    });
-
-    it('should return true if Hive is selected and MapReduce is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'HIVE').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(true);
-    });
-
-    it('should return false if MapReduce is selected or Pig, Oozie and Hive are not selected', function () {
-      controller.findProperty('serviceName', 'MAPREDUCE').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(false);
-      controller.setEach('isSelected', false);
-      expect(controller.needToAddMapReduce()).to.equal(false);
-    });
-  });
-
-  describe('#needToAddYarnMapReduce2()', function () {
-    it('should return true if Pig is selected and YARN+MapReduce2 is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'PIG').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(true);
-    });
-
-    it('should return true if Oozie is selected and YARN+MapReduce2 is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'OOZIE').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(true);
-    });
-
-    it('should return true if Hive is selected and YARN+MapReduce2 is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'HIVE').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(true);
-    });
-
-    it('should return false if YARN+MapReduce2 is selected or Pig, Oozie and Hive are not selected', function () {
-      controller.findProperty('serviceName', 'YARN').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(false);
-      controller.setEach('isSelected', false);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(false);
-    });
-  });
-
-  describe('#needToAddZooKeeper()', function () {
-    beforeEach(function() {
-      ajax_send = App.ajax.send;
-      App.ajax.send = function() {};
-    });
-
-    afterEach(function() {
-      App.ajax.send = ajax_send;
-    });
-    var originalStackVersion = App.get('currentStackVersion');
-
-    it('should return false if ZOOKEEPER is selected and Hadoop version above 2', function () {
-      App.set('currentStackVersion', 'HDP-2.1.1');
-      controller.findProperty('serviceName', 'ZOOKEEPER').set('isSelected', true);
-      expect(controller.needToAddZooKeeper()).to.equal(false);
-    });
-    it('should return true if ZOOKEEPER is not selected and Hadoop version above 2', function () {
-      controller.findProperty('serviceName', 'ZOOKEEPER').set('isSelected', false);
-      expect(controller.needToAddZooKeeper()).to.equal(true);
-    });
-    it('should return false if none of the HBASE, HIVE, WEBHCAT, STORM is selected and Hadoop version below 2', function () {
-      App.set('currentStackVersion', 'HDP-1.3.0');
-      expect(controller.needToAddZooKeeper()).to.equal(false);
-    });
-    it('should return true if HBASE is not selected and Hadoop version below 2', function () {
-      controller.findProperty('serviceName', 'HBASE').set('isSelected', true);
-      expect(controller.needToAddZooKeeper()).to.equal(true);
-    });
-    it('should return true if HBASE, HIVE, WEBHCAT, STORM are selected and Hadoop version below 2', function () {
-      controller.findProperty('serviceName', 'HIVE').set('isSelected', true);
-      controller.findProperty('serviceName', 'WEBHCAT').set('isSelected', true);
-      controller.findProperty('serviceName', 'STORM').set('isSelected', true);
-      expect(controller.needToAddZooKeeper()).to.equal(true);
-      App.set('currentStackVersion', originalStackVersion);
-    });
-  });
-
-  describe('#gangliaOrNagiosNotSelected()', function () {
-    it('should return true if Nagios or Ganglia is not selected', function () {
-      controller.setEach('isSelected', true);
-      controller.findProperty('serviceName', 'NAGIOS').set('isSelected', false);
-      expect(controller.gangliaOrNagiosNotSelected()).to.equal(true);
-      controller.setEach('isSelected', true);
-      controller.findProperty('serviceName', 'GANGLIA').set('isSelected', false);
-      expect(controller.gangliaOrNagiosNotSelected()).to.equal(true);
-    });
-
-    it('should return false if Nagios and Ganglia is selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'GANGLIA').set('isSelected', true);
-      controller.findProperty('serviceName', 'NAGIOS').set('isSelected', true);
-      expect(controller.gangliaOrNagiosNotSelected()).to.equal(false);
-    });
-  });
-
-  describe('#needToAddTez()', function () {
-    it('should return false if YARN is present, but not selected', function () {
-      controller.findProperty('serviceName', 'YARN').set('isSelected', false);
-      expect(controller.needToAddTez()).to.equal(false);
-    });
-    it('should return true if YARN is selected', function () {
-      controller.findProperty('serviceName', 'YARN').set('isSelected', true);
-      expect(controller.needToAddTez()).to.equal(true);
-    });
-  });
-
-  describe('#needToAddOozie()', function () {
-    it('should return false if FALCON is present, but not selected', function () {
-      controller.findProperty('serviceName', 'FALCON').set('isSelected', false);
-      expect(controller.needToAddOozie()).to.equal(false);
-    });
-    it('should return true if FALCON is selected', function () {
-      controller.findProperty('serviceName', 'FALCON').set('isSelected', true);
-      expect(controller.needToAddOozie()).to.equal(true);
-    });
-  });
-
   describe('#noDFSs()', function () {
     it('should return true if HDFS is not selected and GLUSTERFS is absent', function () {
       controller.findProperty('serviceName', 'HDFS').set('isSelected', false);
@@ -228,7 +97,7 @@ describe('App.WizardStep4Controller', function () {
     });
     it('should return true if HDFS is not selected and GLUSTERFS is not selected, but present', function () {
       controller.pushObject(Ember.Object.create({
-        'serviceName':'GLUSTERFS', 'isSelected': false, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': false
+        'serviceName':'GLUSTERFS', 'isSelected': false, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': false, 'isDFS': true
       }));
       controller.findProperty('serviceName', 'HDFS').set('isSelected', false);
       expect(controller.noDFSs()).to.equal(true);
@@ -256,7 +125,7 @@ describe('App.WizardStep4Controller', function () {
     });
   });
 
-  describe('#checkDependencies()', function () {
+  describe('#setGroupedServices()', function () {
     var testCases = [
       {
         title: 'should set HCATALOG and WEBHCAT isSelected to true when HIVE is selected',
@@ -327,10 +196,13 @@ describe('App.WizardStep4Controller', function () {
         controller.clear();
         for(var id in testCase.condition) {
           controller.pushObject(Ember.Object.create({
-            'serviceName':id, 'isSelected': testCase.condition[id], 'canBeSelected': true, 'isInstalled': false
+            'serviceName':id, 'isSelected': testCase.condition[id], 'canBeSelected': true, 'isInstalled': false,
+            coSelectedServices: function() {
+              return App.StackService.coSelected[this.get('serviceName')] || [];
+            }.property('serviceName')
           }));
         }
-        controller.checkDependencies();
+        controller.setGroupedServices();
         for(var service in testCase.result) {
           expect(controller.findProperty('serviceName', service).get('isSelected')).to.equal(testCase.result[service]);
         }
@@ -381,6 +253,14 @@ describe('App.WizardStep4Controller', function () {
   });
 
   describe('#validateMonitoring', function() {
+    beforeEach(function() {
+      sinon.stub(controller, 'monitoringCheckPopup', Em.K);
+      sinon.stub(App.router, 'send', Em.K);
+    });
+    afterEach(function() {
+      controller.monitoringCheckPopup.restore();
+      App.router.send.restore();
+    });
     Em.A([
         {
           gangliaOrNagiosNotSelected: true,
@@ -398,12 +278,11 @@ describe('App.WizardStep4Controller', function () {
         }
       ]).forEach(function (test) {
         it(test.m, function () {
-          sinon.stub(controller, 'monitoringCheckPopup', Em.K);
-          sinon.stub(App.router, 'send', Em.K);
           sinon.stub(controller, 'gangliaOrNagiosNotSelected', function() {
             return test.gangliaOrNagiosNotSelected;
           });
           controller.validateMonitoring();
+          controller.gangliaOrNagiosNotSelected.restore();
           if (test.e.monitoringCheckPopup) {
            expect(controller.monitoringCheckPopup.calledOnce).to.equal(true);
           }
@@ -416,9 +295,6 @@ describe('App.WizardStep4Controller', function () {
           else {
             expect(App.router.send.called).to.equal(false);
           }
-          controller.gangliaOrNagiosNotSelected.restore();
-          controller.monitoringCheckPopup.restore();
-          App.router.send.restore();
         });
       });
   });
@@ -426,9 +302,11 @@ describe('App.WizardStep4Controller', function () {
   describe('#submit', function() {
     beforeEach(function() {
       sinon.stub(controller, 'validateMonitoring', Em.K);
+      sinon.stub(controller, 'setGroupedServices', Em.K);
     });
     afterEach(function() {
       controller.validateMonitoring.restore();
+      controller.setGroupedServices.restore();
     });
     it('if not isSubmitDisabled shound\'t do nothing', function() {
       controller.reopen({isSubmitDisabled: true});
@@ -436,19 +314,20 @@ describe('App.WizardStep4Controller', function () {
       expect(controller.validateMonitoring.called).to.equal(false);
     });
     it('if isSubmitDisabled and not submitChecks should call validateMonitoring', function() {
+      sinon.stub(controller, 'isSubmitChecksFailed', function() { return false; });
       controller.reopen({
         isSubmitDisabled: false,
         submitChecks: []
       });
       controller.submit();
       expect(controller.validateMonitoring.calledOnce).to.equal(true);
+      controller.isSubmitChecksFailed.restore();
     });
     it('if isSubmitDisabled and some submitChecks true shouldn\'t call validateMonitoring', function() {
       controller.reopen({
         isSubmitDisabled: false,
         submitChecks: [
           {
-            checkCallback: 'needToAddMapReduce',
             popupParams: [
               {serviceName: 'MAPREDUCE', selected: true},
               'mapreduceCheck'
@@ -456,10 +335,10 @@ describe('App.WizardStep4Controller', function () {
           }
         ]
       });
-      sinon.stub(controller, 'needToAddMapReduce', function() {return true;});
+      sinon.stub(controller, 'isSubmitChecksFailed', function() { return true; });
       controller.submit();
+      controller.isSubmitChecksFailed.restore();
       expect(controller.validateMonitoring.called).to.equal(false);
-      controller.needToAddMapReduce.restore();
     });
     it('if isSubmitDisabled and some submitChecks false should call validateMonitoring', function() {
       controller.reopen({
@@ -474,10 +353,10 @@ describe('App.WizardStep4Controller', function () {
           }
         ]
       });
-      sinon.stub(controller, 'needToAddMapReduce', function() {return false;});
+      sinon.stub(controller, 'isSubmitChecksFailed', function() { return false; });
       controller.submit();
+      controller.isSubmitChecksFailed.restore();
       expect(controller.validateMonitoring.calledOnce).to.equal(true);
-      controller.needToAddMapReduce.restore();
     });
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/wizard/step5_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step5_test.js b/ambari-web/test/controllers/wizard/step5_test.js
index d3f5a91..3eb18cb 100644
--- a/ambari-web/test/controllers/wizard/step5_test.js
+++ b/ambari-web/test/controllers/wizard/step5_test.js
@@ -19,212 +19,85 @@
 var Ember = require('ember');
 var App = require('app');
 require('controllers/wizard/step5_controller');
+var modelSetup = require('test/init_model_test');
+require('utils/ajax/ajax');
 var c;
 describe('App.WizardStep5Controller', function () {
-  beforeEach(function() {
+  beforeEach(function () {
     c = App.WizardStep5Controller.create();
   });
   var controller = App.WizardStep5Controller.create();
   controller.set('content', {});
   var cpu = 2, memory = 4;
 
-  var schemes = Em.A([
-    {'description': 'empty condition'},
-    {
-      'description': 'second host if amount more than 1',
-      "else": 1
-    },
-    {
-      'description': 'first host if amount less than 3, third host if amount less than 6, fourth host if amount more than 5',
-      "3": 0,
-      "6": 2,
-      "else": 3
-    },
-    {
-      'description': 'second host if amount less than 3, second host if amount less than 6, third host if amount less than 31, sixth host if amount more than 30',
-      "3": 1,
-      "6": 1,
-      "31": 2,
-      "else": 5
-    }
-  ]);
-
-  var test_config = [
-    {
-      title: '1 host',
-      hosts: ['host0'],
-      equals: [0, 0, 0, 0]
-    },
-    {
-      title: '2 hosts',
-      hosts: ['host0', 'host1'],
-      equals: [0, 1, 0, 1]
-    },
-    {
-      title: '3 hosts',
-      hosts: ['host0', 'host1', 'host2'],
-      equals: [0, 1, 2, 1]
-    },
-    {
-      title: '5 hosts',
-      hosts: ['host0', 'host1', 'host2', 'host3', 'host4'],
-      equals: [0, 1, 2, 1]
-    },
-    {
-      title: '6 hosts',
-      hosts: ['host0', 'host1', 'host2', 'host3', 'host4', 'host6'],
-      equals: [0, 1, 3, 2]
-    },
-    {
-      title: '10 hosts',
-      hosts: ['host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9'],
-      equals: [0, 1, 3, 2]
-    },
-    {
-      title: '31 hosts',
-      hosts: ['host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9', 'host10', 'host11', 'host12', 'host13', 'host14', 'host15', 'host16', 'host17', 'host18', 'host19', 'host20', 'host21', 'host22', 'host23', 'host24', 'host25', 'host26', 'host27', 'host28', 'host29', 'host30'],
-      equals: [0, 1, 3, 5]
-    }
-  ];
-
-  schemes.forEach(function(scheme, index) {
-    describe('#getHostForComponent() condition: ' + scheme.description, function() {
-
-      delete scheme['description'];
+  describe('#getHostForComponent()', function () {
+    before(function () {
+      modelSetup.setupStackServiceComponent();
+    });
 
-      test_config.forEach(function(test) {
-        it(test.title, function () {
-          controller.get('hosts').clear();
-          test.hosts.forEach(function(_host) {
-            controller.get('hosts').pushObject(Em.Object.create({
-              host_name: _host,
-              cpu: cpu,
-              memory: memory
-            }));
-          });
-          expect(controller.getHostForComponent(test.hosts.length, scheme).host_name).to.equal(test.hosts[test.equals[index]]);
+    var componentHostsGenerator = function (componentName, hosts) {
+        it('test hosts input valid', function () {
+          expect(hosts.length).to.eql(5);
         });
+        return {
+          componentName: componentName,
+          expectedLocation: hosts
+        };
+      },
+      hostsCount = [1, 3, 6, 10, 31],
+      tests = [
+        componentHostsGenerator('NAMENODE', ['host0', 'host0', 'host0', 'host0', 'host0']),
+        componentHostsGenerator('SECONDARY_NAMENODE', ['host0', 'host1', 'host1', 'host1', 'host1']),
+        componentHostsGenerator('HBASE_MASTER', ['host0', 'host0', 'host2', 'host2', 'host3']),
+        componentHostsGenerator('JOBTRACKER', ['host0', 'host1', 'host1', 'host1', 'host2']),
+        componentHostsGenerator('OOZIE_SERVER', ['host0', 'host1', 'host2', 'host2', 'host3']),
+        componentHostsGenerator('HIVE_SERVER', ['host0', 'host1', 'host2', 'host2', 'host4']),
+        componentHostsGenerator('STORM_UI_SERVER', ['host0', 'host0', 'host0', 'host0', 'host0'])
+      ],
+      testMessage = 'should locate `{0}` to `{1}` with {2} node cluster';
+
+    tests.forEach(function (test) {
+      var componentName = test.componentName;
+      hostsCount.forEach(function (count, index) {
+        it(testMessage.format(componentName, test.expectedLocation[index], count), function () {
+          var hosts = Array.apply(null, Array(count)).map(function (_, i) {
+            return 'host' + i;
+          });
+          expect(controller.getHostForComponent(test.componentName, hosts)).to.eql(test.expectedLocation[index]);
+        })
       });
     });
-  });
-
-  describe('#getZooKeeperServer', function() {
-    it('should be array with three host names if hosts number more than three', function() {
-      var hosts = [
-        {host_name: 'host1'},
-        {host_name: 'host2'},
-        {host_name: 'host3'}
-      ];
-
-      controller.set('hosts', hosts);
-      expect(controller.getZooKeeperServer(hosts.length)).to.eql(['host1', 'host2', 'host3']);
-    });
-
-    it('should be array with one host names if hosts number less than three', function() {
-      var hosts = [
-        {host_name: 'host1'},
-        {host_name: 'host2'}
-      ];
 
-      controller.set('hosts', hosts);
-      expect(controller.getZooKeeperServer(hosts.length)).to.eql(['host1']);
+    after(function () {
+      modelSetup.cleanStackServiceComponent();
     });
   });
 
-  describe('#getServerHost', function() {
-    it('should be host name if one host ', function() {
-      var hosts = [
-        {host_name: 'host1'}
-      ];
-
-      controller.set('hosts', hosts);
-      expect(controller.getServerHost(hosts.length)).to.eql('host1');
-    });
-
-    it('should be host name if hosts number more than one', function() {
-      var hosts = [
-        {host_name: 'host1'},
-        {host_name: 'host2'}
-      ];
-
-      controller.set('hosts', hosts);
-      expect(controller.getServerHost(hosts.length)).to.eql('host1');
-    });
-
-    it('should be host name different from localhost if hosts number more than one', function() {
-      var hosts = [
-        {host_name: location.hostname},
-        {host_name: 'host2'}
-      ];
-      //first host_name is empty string, because of location.hostname = "" in console,
-      //to implement current test case
-
-      controller.set('hosts', hosts);
-      expect(controller.getServerHost(hosts.length)).to.eql('host2');
-    });
-  });
-
-
   controller.set('content', {});
 
-  describe('#isReassignWizard', function() {
-    it('true if content.controllerName is reassignMasterController', function() {
+  describe('#isReassignWizard', function () {
+    it('true if content.controllerName is reassignMasterController', function () {
       controller.set('content.controllerName', 'reassignMasterController');
       expect(controller.get('isReassignWizard')).to.equal(true);
     });
-    it('false if content.controllerName is not reassignMasterController', function() {
+    it('false if content.controllerName is not reassignMasterController', function () {
       controller.set('content.controllerName', 'mainController');
       expect(controller.get('isReassignWizard')).to.equal(false);
     });
   });
 
-  describe('#isAddServiceWizard', function() {
-    it('true if content.controllerName is addServiceController', function() {
+  describe('#isAddServiceWizard', function () {
+    it('true if content.controllerName is addServiceController', function () {
       controller.set('content.controllerName', 'addServiceController');
       expect(controller.get('isAddServiceWizard')).to.equal(true);
     });
-    it('false if content.controllerName is not addServiceController', function() {
+    it('false if content.controllerName is not addServiceController', function () {
       controller.set('content.controllerName', 'mainController');
       expect(controller.get('isAddServiceWizard')).to.equal(false);
     });
   });
 
-  describe('#isReassignHive', function() {
-
-    var tests = Em.A([
-      {
-        servicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
-        controllerName: 'reassignMasterController',
-        e: true
-      },
-      {
-        servicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
-        controllerName: 'addServiceController',
-        e: false
-      },
-      {
-        servicesMasters: Em.A([{component_name: 'ZOOKEEPER_SERVER'}]),
-        controllerName: 'reassignMasterController',
-        e: false
-      },
-      {
-        servicesMasters: Em.A([{component_name: 'ZOOKEEPER_SERVER'}]),
-        controllerName: 'addServiceController',
-        e: false
-      }
-    ]);
-
-    tests.forEach(function(test) {
-      it(test.controllerName + ' ' + test.servicesMasters.mapProperty('component_name').join(','), function() {
-        controller.set('content.controllerName', test.controllerName);
-        controller.set('servicesMasters', test.servicesMasters);
-        expect(controller.get('isReassignHive')).to.equal(test.e);
-      });
-    });
-
-  });
-
-  describe('#sortHosts', function() {
+  describe('#sortHosts', function () {
 
     var tests = Em.A([
       {
@@ -235,7 +108,7 @@ describe('App.WizardStep5Controller', function () {
           Em.Object.create({memory: 1, cpu: 1, host_name: 'host4', id: 4})
         ],
         m: 'memory',
-        e: [1,2,3,4]
+        e: [1, 2, 3, 4]
       },
       {
         hosts: [
@@ -245,7 +118,7 @@ describe('App.WizardStep5Controller', function () {
           Em.Object.create({memory: 1, cpu: 1, host_name: 'host4', id: 4})
         ],
         m: 'cpu',
-        e: [1,2,3,4]
+        e: [1, 2, 3, 4]
       },
       {
         hosts: [
@@ -255,7 +128,7 @@ describe('App.WizardStep5Controller', function () {
           Em.Object.create({memory: 1, cpu: 1, host_name: 'host1', id: 4})
         ],
         m: 'host_name',
-        e: [4,2,3,1]
+        e: [4, 2, 3, 1]
       },
       {
         hosts: [
@@ -265,12 +138,12 @@ describe('App.WizardStep5Controller', function () {
           Em.Object.create({memory: 1, cpu: 1, host_name: 'host2', id: 4})
         ],
         m: 'mix',
-        e: [1,2,4,3]
+        e: [1, 2, 4, 3]
       }
     ]);
 
-    tests.forEach(function(test) {
-      it(test.m, function() {
+    tests.forEach(function (test) {
+      it(test.m, function () {
         var hosts = Em.copy(test.hosts);
         controller.sortHosts(hosts);
         expect(Em.A(hosts).mapProperty('id')).to.eql(test.e);
@@ -279,7 +152,7 @@ describe('App.WizardStep5Controller', function () {
 
   });
 
-  describe('#renderHostInfo', function() {
+  describe('#renderHostInfo', function () {
 
     var tests = Em.A([
       {
@@ -334,8 +207,8 @@ describe('App.WizardStep5Controller', function () {
       }
     ]);
 
-    tests.forEach(function(test) {
-      it(test.m, function() {
+    tests.forEach(function (test) {
+      it(test.m, function () {
         controller.set('content', {hosts: test.hosts});
         controller.renderHostInfo();
         var r = controller.get('hosts');
@@ -345,49 +218,16 @@ describe('App.WizardStep5Controller', function () {
 
   });
 
-  describe('#hasHiveServer', function() {
-
-    var tests = Em.A([
-      {
-        selectedServicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
-        controllerName: 'reassignMasterController',
-        e: false
-      },
-      {
-        selectedServicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
-        controllerName: 'addServiceController',
-        e: true
-      },
-      {
-        selectedServicesMasters: Em.A([{component_name: 'ANOTHER'}]),
-        controllerName: 'addServiceController',
-        e: false
-      },
-      {
-        selectedServicesMasters: Em.A([{component_name: 'ANOTHER'}]),
-        controllerName: 'reassignMasterController',
-        e: false
-      }
-    ]);
-
-    tests.forEach(function(test) {
-      it(test.controllerName + ' ' + test.selectedServicesMasters.mapProperty('component_name').join(','), function() {
-        controller.set('content.controllerName', test.controllerName);
-        controller.set('selectedServicesMasters', test.selectedServicesMasters);
-        expect(controller.get('hasHiveServer')).to.equal(test.e);
+  describe('#selectHost', function () {
+    before(function () {
+      modelSetup.setupStackServiceComponent();
+      App.store.load(App.StackServiceComponent, {
+        id: 'KERBEROS_SERVER',
+        component_name: 'KERBEROS_SERVER'
       });
     });
 
-  });
-
-  describe('#selectHost', function() {
-
     var tests = Em.A([
-      {componentName: 'KERBEROS_SERVER', hostsCount: 1, e: 'host1'},
-      {componentName: 'KERBEROS_SERVER', hostsCount: 3, e: 'host2'},
-      {componentName: 'KERBEROS_SERVER', hostsCount: 6, e: 'host4'},
-      {componentName: 'KERBEROS_SERVER', hostsCount: 31, e: 'host6'},
-      {componentName: 'KERBEROS_SERVER', hostsCount: 32, e: 'host6'},
       {componentName: 'NAMENODE', hostsCount: 1, e: 'host1'},
       {componentName: 'NAMENODE', hostsCount: 2, e: 'host1'},
       {componentName: 'SECONDARY_NAMENODE', hostsCount: 1, e: 'host1'},
@@ -444,27 +284,22 @@ describe('App.WizardStep5Controller', function () {
       {componentName: 'FALCON_SERVER', hostsCount: 32, e: 'host4'}
     ]);
 
-    tests.forEach(function(test) {
-      it(test.componentName + ' ' + test.hostsCount, function() {
-        controller.set('hosts', d3.range(1, test.hostsCount + 1).map(function(i) { return {host_name: 'host' + i.toString()};}));
+    tests.forEach(function (test) {
+      it(test.componentName + ' ' + test.hostsCount, function () {
+        controller.set('hosts', d3.range(1, test.hostsCount + 1).map(function (i) {
+          return {host_name: 'host' + i.toString()};
+        }));
         expect(controller.selectHost(test.componentName)).to.eql(test.e);
       });
     });
 
-    describe('getServerHost should be called for', function() {
-      Em.A(['STORM_UI_SERVER','DRPC_SERVER','STORM_REST_API','NIMBUS','GANGLIA_SERVER','NAGIOS_SERVER','HUE_SERVER']).forEach(function(componentName) {
-        it(componentName, function() {
-          sinon.spy(controller, 'getServerHost');
-          controller.selectHost(componentName);
-          expect(controller.getServerHost.calledOnce).to.equal(true);
-          controller.getServerHost.restore();
-        });
-      });
+    after(function () {
+      modelSetup.cleanStackServiceComponent();
     });
 
   });
 
-  describe('#last', function() {
+  describe('#last', function () {
 
     var tests = Em.A([
       {
@@ -489,8 +324,8 @@ describe('App.WizardStep5Controller', function () {
       }
     ]);
 
-    tests.forEach(function(test) {
-      it(test.m, function() {
+    tests.forEach(function (test) {
+      it(test.m, function () {
         controller.set('selectedServicesMasters', test.selectedServicesMasters);
         if (!Em.isNone(test.e)) {
           expect(controller.last(test.c).indx).to.equal(test.e);
@@ -503,37 +338,43 @@ describe('App.WizardStep5Controller', function () {
 
   });
 
-  describe('#isSubmitDisabled', function() {
-    it('should be false if it\'s not a isReassignWizard', function() {
+  describe('#isSubmitDisabled', function () {
+    it('should be false if it\'s not a isReassignWizard', function () {
       c.set('controllerName', 'addServiceController');
       expect(c.get('isSubmitDisabled')).to.equal(false);
     });
   });
 
-  describe('#remainingHosts', function() {
-    it('should show count of hosts without masters', function() {
-      c.reopen({masterHostMapping: [{}]});
-      c.set('hosts', [{},{},{}]);
+  describe('#remainingHosts', function () {
+    it('should show count of hosts without masters', function () {
+      c.reopen({masterHostMapping: [
+        {}
+      ]});
+      c.set('hosts', [
+        {},
+        {},
+        {}
+      ]);
       expect(c.get('remainingHosts')).to.equal(2);
     });
   });
 
-  describe('#clearStep', function() {
+  describe('#clearStep', function () {
     var tests = Em.A([
       {p: 'hosts'},
       {p: 'selectedServicesMasters'},
       {p: 'servicesMasters'}
     ]);
-    tests.forEach(function(test) {
-      it('should cleanup ' + test.p, function() {
-        c.set(test.p, [Em.Object.create({}),Em.Object.create({})]);
+    tests.forEach(function (test) {
+      it('should cleanup ' + test.p, function () {
+        c.set(test.p, [Em.Object.create({}), Em.Object.create({})]);
         c.clearStep();
         expect(c.get(test.p).length).to.equal(0);
       });
     });
   });
 
-  describe('#updateComponent', function() {
+  describe('#updateComponent', function () {
     var tests = Em.A([
       {
         componentName: 'HBASE_SERVER',
@@ -612,30 +453,37 @@ describe('App.WizardStep5Controller', function () {
       }
     ]);
 
-    tests.forEach(function(test) {
-      it(test.m, function() {
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        sinon.stub(App.StackService, 'find', function () {
+          return test.services;
+        });
         c.reopen({
           content: Em.Object.create({
-            services: test.services,
             controllerName: test.controllerName
           }),
-          selectedServicesMasters: test.selectedServicesMasters
+          selectedServicesMasters: test.selectedServicesMasters,
+          hosts: test.hosts
         });
         c.updateComponent(test.componentName);
-        Em.keys(test.e).forEach(function(k) {
+        App.StackService.find.restore();
+        Em.keys(test.e).forEach(function (k) {
           expect(c.last(test.componentName).get(k)).to.equal(test.e[k]);
         });
+
       });
     });
   });
 
-  describe('#renderComponents', function() {
+  describe('#renderComponents', function () {
     var tests = Em.A([
       {
         masterComponents: Em.A([
           {component_name: 'ZOOKEEPER_SERVER'}
         ]),
-        services: Em.A([]),
+        services: Em.A([
+          Em.Object.create({serviceName: 'ZOOKEEPER', isInstalled: false, isSelected: true})
+        ]),
         controllerName: 'reassignMasterController',
         m: 'One component',
         isHaEnabled: false,
@@ -645,24 +493,24 @@ describe('App.WizardStep5Controller', function () {
           servicesMasters: ['ZOOKEEPER_SERVER'],
           showRemoveControl: [false],
           isInstalled: [false],
-          zId: [1]
+          serviceComponentId: [1]
         }
       },
       {
         masterComponents: Em.A([
-          {component_name: 'ZOOKEEPER_SERVER'},
-          {component_name: 'SECONDARY_NAMENODE'}
+          {component_name: 'ZOOKEEPER_SERVER'}
+        ]),
+        services: Em.A([
+          Em.Object.create({serviceName: 'ZOOKEEPER', isInstalled: false, isSelected: true})
         ]),
-        services: Em.A([]),
         controllerName: 'addServiceController',
-        m: 'One component',
-        isHaEnabled: true,
+        m: 'One component, service is not installed',
         component_name: 'ZOOKEEPER_SERVER',
         e: {
           selectedServicesMasters: ['ZOOKEEPER_SERVER'],
           servicesMasters: ['ZOOKEEPER_SERVER'],
           showRemoveControl: [false],
-          zId: [1]
+          serviceComponentId: [1]
         }
       },
       {
@@ -671,17 +519,16 @@ describe('App.WizardStep5Controller', function () {
           {component_name: 'ZOOKEEPER_SERVER'}
         ]),
         services: Em.A([
-          Em.Object.create({serviceName:'ZOOKEEPER', isInstalled: true})
+          Em.Object.create({serviceName: 'ZOOKEEPER', isInstalled: true})
         ]),
         controllerName: 'addServiceController',
         m: 'Two components, but service is installed',
-        isHaEnabled: false,
         component_name: 'ZOOKEEPER_SERVER',
         e: {
           selectedServicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER'],
           servicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER'],
           showRemoveControl: [false, false],
-          zId: [1, 2]
+          serviceComponentId: [1, 2]
         }
       },
       {
@@ -691,24 +538,28 @@ describe('App.WizardStep5Controller', function () {
           {component_name: 'NAMENODE'}
         ]),
         services: Em.A([
+          Em.Object.create({serviceName: 'ZOOKEEPER', isInstalled: false, isSelected: true})
         ]),
         controllerName: 'addServiceController',
-        m: 'Two components, but service is installed',
-        isHaEnabled: false,
+        m: 'Two components, but service is not installed',
         component_name: 'ZOOKEEPER_SERVER',
         e: {
           selectedServicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER', 'NAMENODE'],
           servicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER', 'NAMENODE'],
           showRemoveControl: [true, true, undefined],
-          zId: [1, 2, 1]
+          serviceComponentId: [1, 2, undefined]
         }
       }
     ]);
-    tests.forEach(function(test) {
-      beforeEach(function() {
+    tests.forEach(function (test) {
+      beforeEach(function () {
         App.reopen({isHaEnabled: test.isHaEnabled});
       });
-      it(test.m, function() {
+      it(test.m, function () {
+        modelSetup.setupStackServiceComponent();
+        sinon.stub(App.StackService, 'find', function () {
+          return test.services;
+        });
         App.set('isHaEnabled', test.isHaEnabled);
         c.reopen({
           content: Em.Object.create({
@@ -718,10 +569,12 @@ describe('App.WizardStep5Controller', function () {
           })
         });
         c.renderComponents(test.masterComponents);
+        App.StackService.find.restore();
+        modelSetup.cleanStackServiceComponent();
         expect(c.get('selectedServicesMasters').mapProperty('component_name')).to.eql(test.e.selectedServicesMasters);
         expect(c.get('servicesMasters').mapProperty('component_name')).to.eql(test.e.servicesMasters);
         expect(c.get('selectedServicesMasters').mapProperty('showRemoveControl')).to.eql(test.e.showRemoveControl);
-        expect(c.get('selectedServicesMasters').mapProperty('zId')).to.eql(test.e.zId);
+        expect(c.get('selectedServicesMasters').mapProperty('serviceComponentId')).to.eql(test.e.serviceComponentId);
         if (c.get('isReasignController')) {
           expect(c.get('servicesMasters').mapProperty('isInstalled')).to.eql(test.e.isInstalled);
         }
@@ -729,133 +582,82 @@ describe('App.WizardStep5Controller', function () {
     });
   });
 
-  describe('#updateHiveCoHosts', function() {
-    var tests = Em.A([
-      {
-        selectedServicesMasters: Em.A([
-          Em.Object.create({component_name: 'HIVE_SERVER', selectedHost: 'h1'}),
-          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h2'}),
-          Em.Object.create({component_name: 'WEBHCAT_SERVER', selectedHost: 'h3'})
-        ]),
-        servicesMasters: Em.A([
-          Em.Object.create({component_name: 'HIVE_SERVER', selectedHost: 'h1'})
-        ]),
-        isReassignHive: false,
-        m: 'should set new host for both',
-        e: ['h1','h1','h1']
-      },
-      {
-        selectedServicesMasters: Em.A([
-          Em.Object.create({component_name: 'HIVE_SERVER', selectedHost: 'h1'}),
-          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h2'}),
-          Em.Object.create({component_name: 'WEBHCAT_SERVER', selectedHost: 'h3'})
-        ]),
-        servicesMasters: Em.A([
-          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h1'})
-        ]),
-        isReassignHive: false,
-        m: 'should set new host for WEBHCAT_SERVER',
-        e: ['h1','h2','h1']
-      },
-      {
-        selectedServicesMasters: Em.A([
-          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h2'}),
-          Em.Object.create({component_name: 'WEBHCAT_SERVER', selectedHost: 'h3'})
-        ]),
-        servicesMasters: Em.A([
-          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h1'})
-        ]),
-        isReassignHive: false,
-        m: 'missing HIVE_SERVER',
-        e: ['h2','h3']
-      }
-    ]);
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        c.set('selectedServicesMasters', test.selectedServicesMasters);
-        c.set('servicesMasters', test.servicesMasters);
-        c.reopen({isReassignHive: test.isReassignHive});
-        c.updateHiveCoHosts();
-        expect(c.get('selectedServicesMasters').mapProperty('selectedHost')).to.eql(test.e);
-      });
-    });
-
-  });
-
-  describe('#assignHostToMaster', function() {
+  describe('#assignHostToMaster', function () {
     var tests = Em.A([
-      {
-        componentName: 'c1',
-        selectedHost: 'h2',
-        zId: '1',
-        e: {
-          indx: 0
-        }
-      },
-      {
-        componentName: 'c2',
-        selectedHost: 'h3',
-        zId: '2',
-        e: {
-          indx: 3
-        }
-      },
-      {
-        componentName: 'c3',
-        selectedHost: 'h1',
-        e: {
-          indx: 2
-        }
-      },
-      {
-        componentName: 'c2',
-        selectedHost: 'h4',
-        e: {
-          indx: 1
+        {
+          componentName: 'c1',
+          selectedHost: 'h2',
+          serviceComponentId: '1',
+          e: {
+            indx: 0
+          }
+        },
+        {
+          componentName: 'c2',
+          selectedHost: 'h3',
+          serviceComponentId: '2',
+          e: {
+            indx: 3
+          }
+        },
+        {
+          componentName: 'c3',
+          selectedHost: 'h1',
+          e: {
+            indx: 2
+          }
+        },
+        {
+          componentName: 'c2',
+          selectedHost: 'h4',
+          e: {
+            indx: 1
+          }
         }
-      }
-    ]),
-    selectedServicesMasters = Em.A([
-      Em.Object.create({component_name: 'c1', zId: '1', selectedHost: 'h1'}),
-      Em.Object.create({component_name: 'c2', zId: '1', selectedHost: 'h1'}),
-      Em.Object.create({component_name: 'c3', zId: '1', selectedHost: 'h3'}),
-      Em.Object.create({component_name: 'c2', zId: '2', selectedHost: 'h2'})
-    ]);
+      ]),
+      selectedServicesMasters = Em.A([
+        Em.Object.create({component_name: 'c1', serviceComponentId: '1', selectedHost: 'h1'}),
+        Em.Object.create({component_name: 'c2', serviceComponentId: '1', selectedHost: 'h1'}),
+        Em.Object.create({component_name: 'c3', serviceComponentId: '1', selectedHost: 'h3'}),
+        Em.Object.create({component_name: 'c2', serviceComponentId: '2', selectedHost: 'h2'})
+      ]);
 
-    tests.forEach(function(test) {
-      it(test.componentName + ' ' + test.selectedHost + ' ' + test.zId, function() {
+    tests.forEach(function (test) {
+      it(test.componentName + ' ' + test.selectedHost + ' ' + test.serviceComponentId, function () {
         c.set('selectedServicesMasters', selectedServicesMasters);
-        c.assignHostToMaster(test.componentName, test.selectedHost, test.zId);
+        c.assignHostToMaster(test.componentName, test.selectedHost, test.serviceComponentId);
         expect(c.get('selectedServicesMasters').objectAt(test.e.indx).get('selectedHost')).to.equal(test.selectedHost);
       })
     });
   });
 
-  describe('#submit', function() {
-    beforeEach(function() {
+  describe('#submit', function () {
+    beforeEach(function () {
+      if (!App.router) {
+        App.router = Em.Object.create({send: Em.K});
+      }
       sinon.spy(App.router, 'send');
     });
-    afterEach(function() {
+    afterEach(function () {
       App.router.send.restore();
     });
-    it('should go next if not isSubmitDisabled', function() {
+    it('should go next if not isSubmitDisabled', function () {
       c.reopen({isSubmitDisabled: false});
       c.submit();
       expect(App.router.send.calledWith('next')).to.equal(true);
     });
-    it('shouldn\'t go next if isSubmitDisabled', function() {
+    it('shouldn\'t go next if isSubmitDisabled', function () {
       c.reopen({isSubmitDisabled: true});
       c.submit();
       expect(App.router.send.called).to.equal(false);
     });
   });
 
-  describe('#removeComponent', function() {
+  describe('#removeComponent', function () {
     var tests = Em.A([
       {
         componentName: 'c1',
-        zId: 1,
+        serviceComponentId: 1,
         selectedServicesMasters: Em.A([]),
         hosts: [],
         m: 'empty selectedServicesMasters',
@@ -863,9 +665,9 @@ describe('App.WizardStep5Controller', function () {
       },
       {
         componentName: 'ZOOKEPEER_SERVER',
-        zId: 1,
+        serviceComponentId: 1,
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'HBASE_SERVER'})
+          Em.Object.create({serviceComponentId: 1, component_name: 'HBASE_SERVER'})
         ]),
         hosts: [],
         m: 'no such components',
@@ -873,9 +675,9 @@ describe('App.WizardStep5Controller', function () {
       },
       {
         componentName: 'ZOOKEPEER_SERVER',
-        zId: 1,
+        serviceComponentId: 1,
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER'})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER'})
         ]),
         hosts: [],
         m: 'component is only 1',
@@ -883,12 +685,15 @@ describe('App.WizardStep5Controller', function () {
       },
       {
         componentName: 'ZOOKEPEER_SERVER',
-        zId: 2,
+        serviceComponentId: 2,
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
         ]),
-        hosts: [{},{}],
+        hosts: [
+          {},
+          {}
+        ],
         m: 'two components, add allowed, remove not allowed',
         e: true,
         showAddControl: true,
@@ -896,12 +701,14 @@ describe('App.WizardStep5Controller', function () {
       },
       {
         componentName: 'ZOOKEPEER_SERVER',
-        zId: 2,
+        serviceComponentId: 2,
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
         ]),
-        hosts: [{}],
+        hosts: [
+          {}
+        ],
         m: 'two components, add not allowed, remove not allowed',
         e: true,
         showAddControl: false,
@@ -909,13 +716,16 @@ describe('App.WizardStep5Controller', function () {
       },
       {
         componentName: 'ZOOKEPEER_SERVER',
-        zId: 2,
+        serviceComponentId: 2,
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 3, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: true})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 3, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: true})
         ]),
-        hosts: [{},{}],
+        hosts: [
+          {},
+          {}
+        ],
         m: 'three components, add not allowed, remove allowed',
         e: true,
         showAddControl: false,
@@ -923,25 +733,29 @@ describe('App.WizardStep5Controller', function () {
       },
       {
         componentName: 'ZOOKEPEER_SERVER',
-        zId: 2,
+        serviceComponentId: 2,
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 3, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: true})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 3, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: true})
         ]),
-        hosts: [{},{}, {}],
+        hosts: [
+          {},
+          {},
+          {}
+        ],
         m: 'three components, add allowed, remove allowed',
         e: true,
         showAddControl: true,
         showRemoveControl: true
       }
     ]);
-    tests.forEach(function(test) {
-      it(test.m, function() {
+    tests.forEach(function (test) {
+      it(test.m, function () {
         c.set('selectedServicesMasters', test.selectedServicesMasters);
         c.set('hosts', test.hosts);
-        expect(c.removeComponent(test.componentName, test.zId)).to.equal(test.e);
-        if(test.e) {
+        expect(c.removeComponent(test.componentName, test.serviceComponentId)).to.equal(test.e);
+        if (test.e) {
           expect(c.get('selectedServicesMasters.lastObject.showRemoveControl')).to.equal(test.showRemoveControl);
           expect(c.get('selectedServicesMasters.lastObject.showAddControl')).to.equal(test.showAddControl);
         }
@@ -949,7 +763,7 @@ describe('App.WizardStep5Controller', function () {
     });
   });
 
-  describe('#addComponent', function() {
+  describe('#addComponent', function () {
     var tests = Em.A([
       {
         componentName: 'c1',
@@ -961,7 +775,7 @@ describe('App.WizardStep5Controller', function () {
       {
         componentName: 'ZOOKEPEER_SERVER',
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'HBASE_SERVER'})
+          Em.Object.create({serviceComponentId: 1, component_name: 'HBASE_SERVER'})
         ]),
         hosts: [],
         m: 'no such components',
@@ -970,7 +784,7 @@ describe('App.WizardStep5Controller', function () {
       {
         componentName: 'ZOOKEPEER_SERVER',
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER'})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER'})
         ]),
         hosts: [],
         m: 'one component, 0 hosts',
@@ -979,8 +793,8 @@ describe('App.WizardStep5Controller', function () {
       {
         componentName: 'ZOOKEPEER_SERVER',
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
         ]),
         hosts: [Em.Object.create({}), Em.Object.create({})],
         m: 'two components, two hosts',
@@ -989,16 +803,16 @@ describe('App.WizardStep5Controller', function () {
       {
         componentName: 'ZOOKEPEER_SERVER',
         selectedServicesMasters: Em.A([
-          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
-          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+          Em.Object.create({serviceComponentId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({serviceComponentId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
         ]),
         hosts: [Em.Object.create({}), Em.Object.create({}), Em.Object.create({})],
         m: 'two components, 3 hosts',
         e: true
       }
     ]);
-    tests.forEach(function(test) {
-      it(test.m, function() {
+    tests.forEach(function (test) {
+      it(test.m, function () {
         c.set('selectedServicesMasters', test.selectedServicesMasters);
         c.set('hosts', test.hosts);
         expect(c.addComponent(test.componentName)).to.equal(test.e);
@@ -1006,28 +820,28 @@ describe('App.WizardStep5Controller', function () {
     });
   });
 
-  describe('#loadStep', function() {
+  describe('#loadStep', function () {
     var methods = Em.A(['clearStep', 'renderHostInfo', 'renderComponents', 'loadComponents']);
-    describe('should call several methods', function() {
-      beforeEach(function() {
-        methods.forEach(function(m) {
+    describe('should call several methods', function () {
+      beforeEach(function () {
+        methods.forEach(function (m) {
           sinon.spy(c, m);
         });
         c.reopen({content: {services: Em.A([])}});
       });
-      afterEach(function() {
-        methods.forEach(function(m) {
+      afterEach(function () {
+        methods.forEach(function (m) {
           c[m].restore();
         });
       });
-      methods.forEach(function(m) {
-        it(m, function() {
+      methods.forEach(function (m) {
+        it(m, function () {
           c.loadStep();
           expect(c[m].calledOnce).to.equal(true);
         });
       });
     });
-    it('should update HBASE if App.supports.multipleHBaseMasters is true', function() {
+    it('should update HBASE if App.supports.multipleHBaseMasters is true', function () {
       App.set('supports.multipleHBaseMasters', true);
       sinon.spy(c, 'updateComponent');
       c.reopen({content: {services: Em.A([])}});
@@ -1037,34 +851,34 @@ describe('App.WizardStep5Controller', function () {
     });
   });
 
-  describe('#title', function() {
-    it('should be custom title for reassignMasterController', function() {
+  describe('#title', function () {
+    it('should be custom title for reassignMasterController', function () {
       c.set('content', {controllerName: 'reassignMasterController'});
       expect(c.get('title')).to.equal(Em.I18n.t('installer.step5.reassign.header'));
     });
-    it('should be default for other', function() {
+    it('should be default for other', function () {
       c.set('content', {controllerName: 'notReassignMasterController'});
       expect(c.get('title')).to.equal(Em.I18n.t('installer.step5.header'));
     });
   });
 
-  describe('#isSubmitDisabled', function() {
-    it('should be false if no isReassignWizard', function() {
+  describe('#isSubmitDisabled', function () {
+    it('should be false if no isReassignWizard', function () {
       c.reopen({isReassignWizard: false});
       expect(c.get('isSubmitDisabled')).to.equal(false);
     });
-    it('should be true if isReassignWizard', function() {
+    it('should be true if isReassignWizard', function () {
       var hostComponents = Em.A([
         Em.Object.create({componentName: 'c1', host: Em.Object.create({hostName: 'h1'})}),
         Em.Object.create({componentName: 'c1', host: Em.Object.create({hostName: 'h2'})})
       ]);
-      sinon.stub(App.HostComponent, 'find', function() {
+      sinon.stub(App.HostComponent, 'find', function () {
         return hostComponents;
       });
       c.reopen({
         isReassignWizard: true,
-        content:{
-          reassign:{
+        content: {
+          reassign: {
             component_name: 'c1'
           }
         },
@@ -1078,19 +892,19 @@ describe('App.WizardStep5Controller', function () {
       App.HostComponent.find.restore();
     });
 
-    it('should be false if isReassignWizard', function() {
+    it('should be false if isReassignWizard', function () {
       var hostComponents = Em.A([
         Em.Object.create({componentName: 'c1', host: Em.Object.create({hostName: 'h1'})}),
         Em.Object.create({componentName: 'c1', host: Em.Object.create({hostName: 'h2'})}),
         Em.Object.create({componentName: 'c1', host: Em.Object.create({hostName: 'h3'})})
       ]);
-      sinon.stub(App.HostComponent, 'find', function() {
+      sinon.stub(App.HostComponent, 'find', function () {
         return hostComponents;
       });
       c.reopen({
         isReassignWizard: true,
-        content:{
-          reassign:{
+        content: {
+          reassign: {
             component_name: 'c1'
           }
         },
@@ -1105,7 +919,7 @@ describe('App.WizardStep5Controller', function () {
 
   });
 
-  describe('#masterHostMapping', function() {
+  describe('#masterHostMapping', function () {
     Em.A([
         {
           selectedServicesMasters: [
@@ -1119,8 +933,13 @@ describe('App.WizardStep5Controller', function () {
           ],
           m: 'Two hosts',
           e: [
-            {host_name: 'h1', hostInfo: {}, masterServices: [{}, {}]},
-            {host_name: 'h2', hostInfo: {}, masterServices: [{}]}
+            {host_name: 'h1', hostInfo: {}, masterServices: [
+              {},
+              {}
+            ]},
+            {host_name: 'h2', hostInfo: {}, masterServices: [
+              {}
+            ]}
           ]
         },
         {
@@ -1139,7 +958,10 @@ describe('App.WizardStep5Controller', function () {
           ],
           m: 'One host',
           e: [
-            {host_name: 'h1', hostInfo: {}, masterServices: [{}, {}]}
+            {host_name: 'h1', hostInfo: {}, masterServices: [
+              {},
+              {}
+            ]}
           ]
         }
       ]).forEach(function (test) {
@@ -1150,7 +972,7 @@ describe('App.WizardStep5Controller', function () {
           });
           var result = c.get('masterHostMapping');
           expect(result.length).to.equal(test.e.length);
-          result.forEach(function(r, i) {
+          result.forEach(function (r, i) {
             expect(r.get('host_name')).to.equal(test.e[i].host_name);
             expect(r.get('masterServices.length')).to.equal(test.e[i].masterServices.length);
             expect(r.get('hostInfo')).to.be.an.object;
@@ -1159,7 +981,7 @@ describe('App.WizardStep5Controller', function () {
       });
   });
 
-  describe('#loadComponents', function() {
+  describe('#loadComponents', function () {
     Em.A([
         {
           services: [
@@ -1218,8 +1040,7 @@ describe('App.WizardStep5Controller', function () {
             display_name: 'c1d',
             selectedHost: 'h3',
             isInstalled: false,
-            serviceId: 's1',
-            isHiveCoHost: false
+            serviceId: 's1'
           }
         },
         {
@@ -1239,8 +1060,7 @@ describe('App.WizardStep5Controller', function () {
             display_name: 'c1d',
             selectedHost: 'h3',
             isInstalled: false,
-            serviceId: 's1',
-            isHiveCoHost: false
+            serviceId: 's1'
           }
         },
         {
@@ -1260,8 +1080,7 @@ describe('App.WizardStep5Controller', function () {
             display_name: 'c1d',
             selectedHost: 'h2',
             isInstalled: true,
-            serviceId: 's1',
-            isHiveCoHost: false
+            serviceId: 's1'
           }
         },
         {
@@ -1281,76 +1100,34 @@ describe('App.WizardStep5Controller', function () {
             display_name: 'c1d',
             selectedHost: 'h2',
             isInstalled: true,
-            serviceId: 's1',
-            isHiveCoHost: false
+            serviceId: 's1'
           }
         }
       ]).forEach(function (test) {
-        it(test.m, function() {
+        it(test.m, function () {
           c.reopen({
             content: {
-              services: test.services,
               masterComponentHosts: test.masterComponentHosts
             }
           });
-          sinon.stub(App.StackServiceComponent, 'find', function() {
+          sinon.stub(App.StackService, 'find', function () {
+            return test.services;
+          });
+          sinon.stub(App.StackServiceComponent, 'find', function () {
             return test.masterComponents;
           });
-          sinon.stub(c, 'selectHost', function() {
+          sinon.stub(c, 'selectHost', function () {
             return test.selectHost;
           });
           var r = c.loadComponents();
+          App.StackService.find.restore();
           App.StackServiceComponent.find.restore();
           c.selectHost.restore();
           expect(r.length).to.equal(1);
-          Em.keys(test.e).forEach(function(k) {
+          Em.keys(test.e).forEach(function (k) {
             expect(r[0][k]).to.equal(test.e[k]);
           });
         });
       });
   });
-
-  describe('#_isHiveCoHost', function() {
-    Em.A([
-        {
-          componentName: 'HIVE_METASTORE',
-          isReassignWizard: false,
-          e: true
-        },
-        {
-          componentName: 'WEBHCAT_SERVER',
-          isReassignWizard: false,
-          e: true
-        },
-        {
-          componentName: 'HIVE_METASTORE',
-          isReassignWizard: true,
-          e: false
-        },
-        {
-          componentName: 'WEBHCAT_SERVER',
-          isReassignWizard: true,
-          e: false
-        },
-        {
-          componentName: 'C1',
-          isReassignWizard: false,
-          e: false
-        },
-        {
-          componentName: 'C1',
-          isReassignWizard: true,
-          e: false
-        }
-      ]).forEach(function (test) {
-        it(test.componentName.toString() + ' ' + test.isReassignWizard.toString(), function () {
-          c.reopen({
-            isReassignWizard: test.isReassignWizard
-          });
-          var r = c._isHiveCoHost(test.componentName);
-          expect(r).to.equal(test.e);
-        });
-      });
-  });
-
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/wizard/step6_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step6_test.js b/ambari-web/test/controllers/wizard/step6_test.js
index 536503f..7b28e1f 100644
--- a/ambari-web/test/controllers/wizard/step6_test.js
+++ b/ambari-web/test/controllers/wizard/step6_test.js
@@ -56,9 +56,6 @@ describe('App.WizardStep6Controller', function () {
       masterComponentHosts: {},
       services: services
     });
-    sinon.stub(controller, 'getComponentDisplayName', function (c) {
-      return App.format.components[c];
-    });
 
     var h = {}, m = [];
     Em.A(['host0', 'host1', 'host2', 'host3']).forEach(function (hostName) {
@@ -77,9 +74,6 @@ describe('App.WizardStep6Controller', function () {
 
   });
 
-  afterEach(function () {
-    controller.getComponentDisplayName.restore();
-  });
 
   describe('#loadStep', function () {
     Em.A([

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/wizard/step8_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js
index aa147d4..7a329e5 100644
--- a/ambari-web/test/controllers/wizard/step8_test.js
+++ b/ambari-web/test/controllers/wizard/step8_test.js
@@ -17,6 +17,7 @@
  */
 
 var App = require('app');
+var modelSetup = require('test/init_model_test');
 require('utils/ajax/ajax_queue');
 require('controllers/main/admin/security');
 require('controllers/main/service/info/configs');
@@ -487,6 +488,158 @@ describe('App.WizardStep8Controller', function () {
       });
   });
 
+  describe('#loadServices()', function() {
+    var serviceComponentGenerator = function(componentName, displayName, componentValue) {
+      return Em.Object.create({
+        component_name: componentName,
+        display_name: displayName,
+        component_value: componentValue
+      })
+    };
+
+    var slaveComponentGenerator = function(componentName, hosts) {
+      return Em.Object.create({
+        componentName: componentName,
+        hosts: hosts.map(function(host) { return {'hostName' : host } })
+      });
+    };
+    var masterComponentGenerator = function(componentName, hostName) {
+      return Em.Object.create({
+        component: componentName,
+        hostName: hostName
+      });
+    };
+
+    var serviceConfigGenerator = function(name, value) {
+      return Em.Object.create({
+        name: name,
+        value: value
+      });
+    }
+    before(function() {
+      modelSetup.setupStackServiceComponent();
+      var services = ['HDFS', 'YARN', 'TEZ', 'NAGIOS', 'GANGLIA','OOZIE'];
+      this.controller = App.WizardStep8Controller.create({
+        content: {
+          services: App.StackService.find().setEach('isSelected', true).setEach('isInstalled', false).filterProperty('stackVersion', '2.1').filter(function(service) {
+            return services.contains(service.get('serviceName'));
+          }),
+          slaveComponentHosts: Em.A([
+            slaveComponentGenerator('DATANODE', ['h1','h2']),
+            slaveComponentGenerator('NODEMANAGER', ['h1']),
+            slaveComponentGenerator('CLIENT', ['h1'])
+          ]),
+          masterComponentHosts: Em.A([
+            masterComponentGenerator('NAMENODE', 'h1'),
+            masterComponentGenerator('SECONDARY_NAMENODE', 'h2'),
+            masterComponentGenerator('APP_TIMELINE_SERVER', 'h1'),
+            masterComponentGenerator('RESOURCEMANAGER', 'h1'),
+            masterComponentGenerator('NAGIOS_SERVER', 'h1'),
+            masterComponentGenerator('GANGLIA_SERVER', 'h2'),
+            masterComponentGenerator('OOZIE_SERVER', 'h2')
+          ]),
+          serviceConfigProperties: Em.A([
+            serviceConfigGenerator('nagios_web_login', 'admin'),
+            serviceConfigGenerator('nagios_contact', 'admin@admin.com'),
+            serviceConfigGenerator('oozie_database', 'New Derby Database'),
+            serviceConfigGenerator('oozie_derby_database', '')
+          ])
+        }
+      });
+      var _this = this;
+      this.controller.reopen({
+        wizardController: {
+          getDBProperty: function() {
+            return _this.controller.get('content.serviceConfigProperties')
+          }
+        }
+      });
+      this.controller.loadServices();
+    });
+
+    var tests = [
+      {
+        service_name: 'HDFS',
+        display_name: 'HDFS',
+        service_components: Em.A([
+          serviceComponentGenerator('NAMENODE', 'NameNode', 'h1'),
+          serviceComponentGenerator('DATANODE', 'DataNode', '2 hosts'),
+          serviceComponentGenerator('SECONDARY_NAMENODE', 'SNameNode', 'h2')
+        ])
+      },
+      {
+        service_name: 'YARN',
+        display_name: 'YARN + MapReduce2',
+        service_components: Em.A([
+          serviceComponentGenerator('RESOURCEMANAGER', 'ResourceManager', 'h1'),
+          serviceComponentGenerator('NODEMANAGER', 'NodeManager', '1 host'),
+          serviceComponentGenerator('APP_TIMELINE_SERVER', 'App Timeline Server', 'h1')
+        ])
+      },
+      {
+        service_name: 'TEZ',
+        display_name: 'Tez',
+        service_components: Em.A([
+          serviceComponentGenerator('CLIENT', 'Clients', '1 host')
+        ])
+      },
+      {
+        service_name: 'NAGIOS',
+        display_name: 'Nagios',
+        service_components: Em.A([
+          serviceComponentGenerator('NAGIOS_SERVER', 'Server', 'h1'),
+          serviceComponentGenerator('Custom', 'Administrator', 'admin / (admin@admin.com)')
+        ])
+      },
+      {
+        service_name: 'GANGLIA',
+        display_name: 'Ganglia',
+        service_components: Em.A([
+          serviceComponentGenerator('GANGLIA_SERVER', 'Server', 'h2')
+        ])
+      },
+      {
+        service_name: 'OOZIE',
+        display_name: 'Oozie',
+        service_components: Em.A([
+          serviceComponentGenerator('OOZIE_SERVER', 'Server', 'h2'),
+          serviceComponentGenerator('Custom', 'Database', ' (New Derby Database)')
+        ])
+      }
+    ];
+
+    tests.forEach(function(test) {
+      describe('Load review for `' + test.service_name + '` service', function(){
+        it('{0} service should be displayed as {1}'.format(test.service_name, test.display_name), function() {
+          expect(this.controller.get('services').findProperty('service_name', test.service_name).get('display_name')).to.eql(test.display_name);
+        });
+        it('{0}: all components present'.format(test.service_name), function() {
+          var serviceObj = this.controller.get('services').findProperty('service_name', test.service_name);
+          expect(test.service_components.length).to.be.eql(serviceObj.get('service_components.length'));
+        });
+        test.service_components.forEach(function(serviceComponent) {
+          var testMessage = '`{0}` component present with `{1}` value and displayed as `{2}`';
+          it(testMessage.format(serviceComponent.get('component_name'), serviceComponent.get('component_value'), serviceComponent.get('display_name')), function() {
+            var serviceObj = this.controller.get('services').findProperty('service_name', test.service_name);
+            var component;
+            if (serviceComponent.get('component_name') === 'Custom') {
+              component = serviceObj.get('service_components').findProperty('display_name', serviceComponent.get('display_name'));
+            } else
+              component = serviceObj.get('service_components').findProperty('component_name', serviceComponent.get('component_name'));
+            if (serviceComponent.get('component_name') !== 'Custom')
+              expect(component.get('component_name')).to.eql(serviceComponent.get('component_name'));
+            expect(component.get('component_value')).to.eql(serviceComponent.get('component_value'));
+            expect(component.get('display_name')).to.eql(serviceComponent.get('display_name'));
+          });
+        });
+      })
+    });
+
+    after(function() {
+      modelSetup.cleanStackServiceComponent();
+    });
+  });
+
   describe('#removeHiveConfigs', function () {
     Em.A([
         {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/controllers/wizard/step9_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step9_test.js b/ambari-web/test/controllers/wizard/step9_test.js
index b7972fe..b9c57e0 100644
--- a/ambari-web/test/controllers/wizard/step9_test.js
+++ b/ambari-web/test/controllers/wizard/step9_test.js
@@ -23,6 +23,8 @@ require('models/stack_service_component');
 require('models/hosts');
 require('controllers/wizard/step9_controller');
 require('utils/helper');
+require('utils/ajax/ajax');
+
 var modelSetup = require('test/init_model_test');
 var c, obj;
 describe('App.InstallerStep9Controller', function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/test/init_model_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/init_model_test.js b/ambari-web/test/init_model_test.js
index 3ed3b06..1b4b183 100644
--- a/ambari-web/test/init_model_test.js
+++ b/ambari-web/test/init_model_test.js
@@ -19,21 +19,15 @@
 var App = require('app');
 require('models/stack_service_component');
 require('mappers/server_data_mapper');
-require('mappers/stack_service_component_mapper');
+require('mappers/stack_service_mapper');
 
 module.exports = {
   setupStackServiceComponent: function() {
     /**
-     * initialization of App.StackServiceComponent model
+     * initialization of App.StackServiceComponent and App.StackService models
      * @type {*}
      */
-    var data = {items: Em.A([])};
-    require('test/service_components').items.forEach(function(i) {
-      i.serviceComponents.forEach(function(sc) {
-        data.items.pushObject(sc.StackServiceComponents);
-      });
-    });
-    App.stackServiceComponentMapper.map(data);
+    App.stackServiceMapper.map(require('test/service_components'));
   },
   cleanStackServiceComponent: function(){
     App.StackServiceComponent.find().set('content',[]);


[4/6] AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Posted by yu...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/HDP2/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2/site_properties.js b/ambari-web/app/data/HDP2/site_properties.js
index 981f7c6..49a5344 100644
--- a/ambari-web/app/data/HDP2/site_properties.js
+++ b/ambari-web/app/data/HDP2/site_properties.js
@@ -31,7 +31,7 @@ module.exports =
       "displayType": "directory",
       "isOverridable": false,
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 1
     },
     {
@@ -52,7 +52,7 @@ module.exports =
       "displayType": "directories",
       "isOverridable": false,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 1
     },
     {
@@ -70,7 +70,7 @@ module.exports =
       "name": "dfs.datanode.failed.volumes.tolerated",
       "displayName": "DataNode volumes failure toleration",
       "displayType": "int",
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "index": 3
     },
@@ -80,7 +80,7 @@ module.exports =
       "displayName": "DataNode directories",
       "defaultDirectory": "/hadoop/hdfs/data",
       "displayType": "directories",
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "index": 1
     },
@@ -89,7 +89,7 @@ module.exports =
       "name": "dfs.datanode.data.dir.perm",
       "displayName": "DataNode directories permission",
       "displayType": "int",
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS"
     },
     {
@@ -148,7 +148,7 @@ module.exports =
       "displayName": "yarn.acl.enable",
       "displayType": "checkbox",
       "serviceName": "YARN",
-      "category": "ResourceManager"
+      "category": "RESOURCEMANAGER"
     },
     {
       "id": "site property",
@@ -156,7 +156,7 @@ module.exports =
       "displayName": "yarn.admin.acl",
       "isRequired": false,
       "serviceName": "YARN",
-      "category": "ResourceManager"
+      "category": "RESOURCEMANAGER"
     },
     {
       "id": "site property",
@@ -164,7 +164,7 @@ module.exports =
       "displayName": "yarn.log-aggregation-enable",
       "displayType": "checkbox",
       "serviceName": "YARN",
-      "category": "ResourceManager"
+      "category": "RESOURCEMANAGER"
     },
     {
       "id": "site property",
@@ -195,21 +195,21 @@ module.exports =
       "displayName": "yarn.nodemanager.resource.memory-mb",
       "displayType": "int",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
       "name": "yarn.nodemanager.vmem-pmem-ratio",
       "displayName": "yarn.nodemanager.vmem-pmem-ratio",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
       "name": "yarn.nodemanager.linux-container-executor.group",
       "displayName": "yarn.nodemanager.linux-container-executor.group",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
@@ -218,7 +218,7 @@ module.exports =
       "defaultDirectory": "/hadoop/yarn/log",
       "displayType": "directories",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
@@ -227,7 +227,7 @@ module.exports =
       "defaultDirectory": "/hadoop/yarn/local",
       "displayType": "directories",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
@@ -235,28 +235,28 @@ module.exports =
       "displayName": "yarn.nodemanager.remote-app-log-dir",
       "displayType": "directory",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
       "name": "yarn.nodemanager.remote-app-log-dir-suffix",
       "displayName": "yarn.nodemanager.remote-app-log-dir-suffix",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
       "name": "yarn.nodemanager.aux-services",
       "displayName": "yarn.nodemanager.aux-services",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
       "name": "yarn.nodemanager.log.retain-second",
       "displayName": "yarn.nodemanager.log.retain-second",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     {
       "id": "site property",
@@ -269,7 +269,7 @@ module.exports =
       "id": "site property",
       "name": "yarn.timeline-service.enabled",
       "displayName": "yarn.timeline-service.enabled",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "displayType": "checkbox",
       "serviceName": "YARN"
     },
@@ -278,7 +278,7 @@ module.exports =
       "name": "yarn.timeline-service.leveldb-timeline-store.path",
       "displayName": "yarn.timeline-service.leveldb-timeline-store.path",
       "defaultDirectory": "/hadoop/yarn/timeline",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "displayType": "directory",
       "serviceName": "YARN"
     },
@@ -287,14 +287,14 @@ module.exports =
       "name": "yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms",
       "displayName": "yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms",
       "displayType": "int",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
       "id": "site property",
       "name": "yarn.timeline-service.store-class",
       "displayName": "yarn.timeline-service.store-class",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
@@ -302,7 +302,7 @@ module.exports =
       "name": "yarn.timeline-service.ttl-enable",
       "displayName": "yarn.timeline-service.ttl-enable",
       "displayType": "checkbox",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
@@ -310,14 +310,14 @@ module.exports =
       "name": "yarn.timeline-service.ttl-ms",
       "displayName": "yarn.timeline-service.ttl-ms",
       "displayType": "int",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
       "id": "site property",
       "name": "yarn.timeline-service.generic-application-history.store-class",
       "displayName": "yarn.timeline-service.generic-application-history.store-class",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
@@ -325,7 +325,7 @@ module.exports =
       "name": "yarn.timeline-service.webapp.address",
       "displayName": "yarn.timeline-service.webapp.address",
       "displayType": "string",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
@@ -333,7 +333,7 @@ module.exports =
       "name": "yarn.timeline-service.webapp.https.address",
       "displayName": "yarn.timeline-service.webapp.https.address",
       "displayType": "string",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
     {
@@ -341,7 +341,7 @@ module.exports =
       "name": "yarn.timeline-service.address",
       "displayName": "yarn.timeline-service.address",
       "displayType": "string",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
     },
   /**********************************************MAPREDUCE2***************************************/
@@ -397,7 +397,7 @@ module.exports =
       "isOverridable": false,
       "displayType": "host",
       "isObserved": true,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 4
     },
@@ -407,7 +407,7 @@ module.exports =
       "displayName": "Database Username",
       "isOverridable": false,
       "displayType": "host",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 5
     },
@@ -417,7 +417,7 @@ module.exports =
       "displayName": "Database Password",
       "isOverridable": false,
       "displayType": "password",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "filename": "oozie-site.xml",
       "index": 6
@@ -427,7 +427,7 @@ module.exports =
       "name": "oozie.service.JPAService.jdbc.driver", // the default value of this property is overriden in code
       "displayName": "JDBC Driver Class",
       "isOverridable": false,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 7
     },
@@ -437,7 +437,7 @@ module.exports =
       "displayName": "Database URL",
       "isOverridable": false,
       "displayType": "advanced",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 8
     },
@@ -448,7 +448,7 @@ module.exports =
       "name": "javax.jdo.option.ConnectionDriverName",  // the default value is overwritten in code
       "displayName": "JDBC Driver Class",
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 7
     },
@@ -469,7 +469,7 @@ module.exports =
       "displayName": "Database Username",
       "displayType": "host",
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 5
     },
@@ -479,7 +479,7 @@ module.exports =
       "displayName": "Database Password",
       "displayType": "password",
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 6
     },
@@ -489,7 +489,7 @@ module.exports =
       "displayName": "Database URL",
       "displayType": "advanced",
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 8
     },
@@ -501,7 +501,7 @@ module.exports =
       "isOverridable": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 4
     },
     {
@@ -685,7 +685,7 @@ module.exports =
       "name": "hbase.regionserver.handler.count",
       "displayName": "RegionServer Handler",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 2
     },
@@ -695,7 +695,7 @@ module.exports =
       "displayName": "HBase Region Major Compaction",
       "displayType": "int",
       "unit": "ms",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 3
     },
@@ -704,7 +704,7 @@ module.exports =
       "name": "hbase.hregion.memstore.block.multiplier",
       "displayName": "HBase Region Block Multiplier",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 4
     },
@@ -722,7 +722,7 @@ module.exports =
       "displayName": "HBase Region Memstore Flush Size",
       "displayType": "int",
       "unit": "bytes",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 5
     },
@@ -946,7 +946,7 @@ module.exports =
       "displayType": "masterHost",
       "isOverridable": false,
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     {
       "id": "site property",
@@ -954,7 +954,7 @@ module.exports =
       "displayName": "nimbus.thrift.port",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     {
       "id": "site property",
@@ -962,7 +962,7 @@ module.exports =
       "displayName": "nimbus.thrift.max_buffer_size",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "bytes"
     },
     {
@@ -972,7 +972,7 @@ module.exports =
       "displayType": "multiLine",
       "isOverridable": false,
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "filename": "storm-site.xml"
     },
     {
@@ -981,7 +981,7 @@ module.exports =
       "displayName": "nimbus.task.timeout.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -990,7 +990,7 @@ module.exports =
       "displayName": "nimbus.supervisor.timeout.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -999,7 +999,7 @@ module.exports =
       "displayName": "nimbus.monitor.freq.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -1008,7 +1008,7 @@ module.exports =
       "displayName": "nimbus.cleanup.inbox.freq.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -1017,7 +1017,7 @@ module.exports =
       "displayName": "nimbus.inbox.jar.expiration.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -1026,7 +1026,7 @@ module.exports =
       "displayName": "nimbus.task.launch.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -1036,7 +1036,7 @@ module.exports =
       "displayType": "checkbox",
       "isReconfigurable": true,
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     {
       "id": "site property",
@@ -1044,7 +1044,7 @@ module.exports =
       "displayName": "nimbus.file.copy.expiration.secs",
       "displayType": "int",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
     },
     {
@@ -1052,7 +1052,7 @@ module.exports =
       "name": "nimbus.topology.validator",
       "displayName": "nimbus.topology.validator",
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     {
       "id": "site property",
@@ -1060,13 +1060,13 @@ module.exports =
       "displayName": "supervisor.slots.ports",
       "displayType": "string",
       "serviceName": "STORM",
-      "category": "Supervisor"
+      "category": "SUPERVISOR"
     },
     {
       "id": "site property",
       "isOverrideable": false,
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.childopts",
       "name": "supervisor.childopts",
       "displayType": "multiLine",
@@ -1075,7 +1075,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.worker.start.timeout.secs",
       "name": "supervisor.worker.start.timeout.secs",
       "displayType": "int",
@@ -1084,7 +1084,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.worker.timeout.secs",
       "name": "supervisor.worker.timeout.secs",
       "displayType": "int",
@@ -1093,7 +1093,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.monitor.frequency.secs",
       "name": "supervisor.monitor.frequency.secs",
       "displayType": "int",
@@ -1102,7 +1102,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.heartbeat.frequency.secs",
       "name": "supervisor.heartbeat.frequency.secs",
       "displayType": "int",
@@ -1111,7 +1111,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.port",
       "name": "drpc.port",
       "displayType": "int"
@@ -1119,7 +1119,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.worker.threads",
       "name": "drpc.worker.threads",
       "displayType": "int"
@@ -1127,7 +1127,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.queue.size",
       "name": "drpc.queue.size",
       "displayType": "int"
@@ -1135,7 +1135,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.invocations.port",
       "name": "drpc.invocations.port",
       "displayType": "int"
@@ -1143,7 +1143,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.request.timeout.secs",
       "name": "drpc.request.timeout.secs",
       "displayType": "int",
@@ -1152,7 +1152,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.childopts",
       "name": "drpc.childopts",
       "displayType": "string"
@@ -1160,7 +1160,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "StormUIServer",
+      "category": "STORM_UI_SERVER",
       "displayName": "ui.port",
       "name": "ui.port",
       "displayType": "int"
@@ -1168,7 +1168,7 @@ module.exports =
     {
       "id": "site property",
       "serviceName": "STORM",
-      "category": "StormUIServer",
+      "category": "STORM_UI_SERVER",
       "displayName": "ui.childopts",
       "name": "ui.childopts",
       "displayType": "string"
@@ -1763,7 +1763,7 @@ module.exports =
       "isRequired": false,
       "displayType": "content",
       "serviceName": "FLUME",
-      "category": "FlumeAgent",
+      "category": "FLUME_HANDLER",
       "filename": "flume-conf.xml"
     }
   ]

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/global_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/global_properties.js b/ambari-web/app/data/global_properties.js
index 9a97b22..f61d354 100644
--- a/ambari-web/app/data/global_properties.js
+++ b/ambari-web/app/data/global_properties.js
@@ -92,7 +92,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 0
     },
     {
@@ -106,7 +106,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 2
     },
     {
@@ -120,7 +120,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 3
     },
     {
@@ -135,7 +135,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 0
     },
     {
@@ -152,7 +152,7 @@ module.exports =
       "isVisible": true,
       "domain": "datanode-global",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 0
     },
     {
@@ -166,7 +166,7 @@ module.exports =
       "isVisible": true,
       "domain": "datanode-global",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 2
     },
     {
@@ -218,7 +218,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode"
+      "category": "NAMENODE"
     },
     {
       "id": "puppet var",
@@ -244,7 +244,7 @@ module.exports =
       "displayType": "directory",
       "isVisible": false,
       "serviceName": "HDFS",
-      "category": "NameNode"
+      "category": "NAMENODE"
     },
 
   /**********************************************GLUSTERFS***************************************/
@@ -386,7 +386,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
-      "category": "HistoryServer",
+      "category": "HISTORYSERVER",
       "index": 0
     },
     {
@@ -401,7 +401,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 0
     },
     {
@@ -415,7 +415,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 1
     },
     {
@@ -429,7 +429,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 2
     },
     {
@@ -443,7 +443,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 3
     },
     {
@@ -458,9 +458,8 @@ module.exports =
       "isVisible": true,
       "isRequired": false,
       "isRequiredByAgent": false,
-      "domain": "tasktracker-global",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 0
     },
     {
@@ -472,7 +471,7 @@ module.exports =
       "displayType": "int",
       "unit": "MB",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 1
     },
     {
@@ -526,7 +525,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 0
     },
     {
@@ -540,7 +539,7 @@ module.exports =
       "isOverridable": true,
       "isVisible": true,
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 1
     },
     {
@@ -557,7 +556,7 @@ module.exports =
       "isRequired": false,
       "domain": "regionserver-global",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 0
     },
     {
@@ -571,7 +570,7 @@ module.exports =
       "isVisible": true,
       "domain": "regionserver-global",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 1
     },
     {
@@ -613,7 +612,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 0
     },
     // for existing MySQL
@@ -629,7 +628,7 @@ module.exports =
       "isVisible": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     // for existing PostgreSQL
@@ -645,7 +644,7 @@ module.exports =
       "isVisible": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     // for existing Oracle
@@ -661,7 +660,7 @@ module.exports =
       "isOverridable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     // for new MySQL
@@ -676,7 +675,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     {
@@ -711,7 +710,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 2
     },
     {
@@ -726,7 +725,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -742,7 +741,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -758,7 +757,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -774,7 +773,7 @@ module.exports =
         "isVisible": false,
         "isObserved": true,
         "serviceName": "HIVE",
-        "category": "Hive Metastore",
+        "category": "HIVE_METASTORE",
         "index": 3
       },
     {
@@ -790,7 +789,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -857,7 +856,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "WEBHCAT",
-      "category": "WebHCat Server"
+      "category": "WEBHCAT_SERVER"
     },
     {
       "id": "puppet var",
@@ -898,7 +897,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 0
     },
     // for existing PostgreSQL
@@ -914,7 +913,7 @@ module.exports =
       "isVisible": false,
       "isReconfigurable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for existing Oracle
@@ -931,7 +930,7 @@ module.exports =
       "isReconfigurable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for current derby
@@ -947,7 +946,7 @@ module.exports =
       "isReconfigurable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for existing MySQL oozie
@@ -963,7 +962,7 @@ module.exports =
       "isReconfigurable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     {
@@ -999,7 +998,7 @@ module.exports =
       "radioName": "oozie-database",
       "isVisible": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 2
     },
     {
@@ -1013,7 +1012,7 @@ module.exports =
       "displayType": "host",
       "isVisible": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1029,7 +1028,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1045,7 +1044,7 @@ module.exports =
       "isVisible": false,   // This is dynamically set to true if database selected by the user is existing postgresql
       "isObserved": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1061,7 +1060,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1077,7 +1076,7 @@ module.exports =
       "displayType": "masterHost",
       "isVisible": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1093,7 +1092,7 @@ module.exports =
       "isVisible": true,
       "isRequired": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 8
     },
 
@@ -1187,7 +1186,7 @@ module.exports =
       "isOverridable": false,
       "isRequired": false,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 0
     },
     {
@@ -1201,7 +1200,7 @@ module.exports =
       "displayType": "directory",
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 1
     },
     {
@@ -1215,7 +1214,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 2
     },
     {
@@ -1228,7 +1227,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 3
     },
     {
@@ -1241,7 +1240,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 4
     },
     {
@@ -1254,7 +1253,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 5
     },
     {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/review_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/review_configs.js b/ambari-web/app/data/review_configs.js
deleted file mode 100644
index b9e04ae..0000000
--- a/ambari-web/app/data/review_configs.js
+++ /dev/null
@@ -1,368 +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.
- */
-
-var App = require('app');
-
-module.exports = [
-
-  {
-    config_name: 'Admin',
-    display_name: 'Admin Name',
-    config_value: ''
-  },
-  {
-    config_name: 'cluster',
-    display_name: 'Cluster Name',
-    config_value: ''
-  },
-  {
-    config_name: 'hosts',
-    display_name: 'Total Hosts',
-    config_value: ''
-  },
-  {
-    config_name: 'Repo',
-    display_name: 'Local Repository',
-    config_value: ''
-  },
-  {
-    config_name: 'services',
-    display_name: 'Services',
-    config_value: [
-      Ember.Object.create({
-        service_name: 'HDFS',
-        display_name: 'HDFS',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'NameNode',
-            component_name: 'NAMENODE',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'SecondaryNameNode',
-            component_name: 'SECONDARY_NAMENODE',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'DataNodes',
-            component_name: 'DATANODE',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'GLUSTERFS',
-        display_name: 'GLUSTERFS',
-        service_components: []
-      }),  
-      Ember.Object.create({
-        service_name: 'MAPREDUCE',
-        display_name: 'MapReduce',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'JobTracker',
-            component_name: 'JOBTRACKER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'TaskTrackers',
-            component_name: 'TASKTRACKER',
-            component_value: '',
-            isMaster: false
-          }),
-          Ember.Object.create({
-            display_name: 'History Server',
-            component_name: 'HISTORYSERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'YARN',
-        display_name: 'YARN + MapReduce2',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'NodeManager',
-            component_name: 'NODEMANAGER',
-            component_value: '',
-            isMaster: false
-          }),
-          Ember.Object.create({
-            display_name: 'ResourceManager',
-            component_name: 'RESOURCEMANAGER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'History Server',
-            component_name: 'HISTORYSERVER',
-            component_value: '',
-            isMaster: true
-          })
-          // @todo uncomment after Application Timeline Server API implementation
-//          Ember.Object.create({
-//            display_name: 'App Timeline Server',
-//            component_name: 'APP_TIMELINE_SERVER',
-//            component_value: '',
-//            isMaster: true
-//          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'HIVE',
-        display_name: 'Hive + HCatalog',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Hive Metastore',
-            component_name: 'HIVE_METASTORE',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Database',
-            component_value: '',
-            customHandler: 'loadHiveDbValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'HBASE',
-        display_name: 'HBase',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Master',
-            component_name: 'HBASE_MASTER',
-            component_value: '',
-            customHandler: 'loadHbaseMasterValue'
-          }),
-          Ember.Object.create({
-            display_name: 'RegionServers',
-            component_name: 'HBASE_REGIONSERVER',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'ZOOKEEPER',
-        display_name: 'ZooKeeper',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Servers',
-            component_name: 'ZOOKEEPER_SERVER',
-            component_value: '',
-            customHandler: 'loadZkServerValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'OOZIE',
-        display_name: 'Oozie',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'OOZIE_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          // TODO: uncomment when ready to integrate with database other than Derby
-          Ember.Object.create({
-            display_name: 'Database',
-            component_value: '',
-            customHandler: 'loadOozieDbValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'NAGIOS',
-        display_name: 'Nagios',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'NAGIOS_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Administrator',
-            component_value: '',
-            customHandler: 'loadNagiosAdminValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'GANGLIA',
-        display_name: 'Ganglia',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'GANGLIA_SERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-     /* Ember.Object.create({
-        service_name: 'TEZ',
-        display_name: 'TEZ',
-        service_components: []
-      }),
-      Ember.Object.create({
-        service_name: 'PIG',
-        display_name: 'Pig',
-        service_components: []
-      }),
-      Ember.Object.create({
-        service_name: 'SQOOP',
-        display_name: 'Sqoop',
-        service_components: []
-      }),
-      Ember.Object.create({
-        service_name: 'HCATALOG',
-        display_name: 'HCatalog',
-        service_components: []
-      }),*/
-      Ember.Object.create({
-        service_name: 'HUE',
-        display_name: 'Hue',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'HUE_SERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'FALCON',
-        display_name: 'Falcon',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'FALCON_SERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'STORM',
-        display_name: 'Storm',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Nimbus',
-            component_name: 'NIMBUS',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Storm REST API Server',
-            component_name: 'STORM_REST_API',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Storm UI Server',
-            component_name: 'STORM_UI_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'DRPC Server',
-            component_name: 'DRPC_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Supervisor',
-            component_name: 'SUPERVISOR',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'PIG',
-        display_name: 'Pig',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Clients',
-            component_name: 'CLIENT',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'SQOOP',
-        display_name: 'Sqoop',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Clients',
-            component_name: 'CLIENT',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'TEZ',
-        display_name: 'Tez',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Clients',
-            component_name: 'CLIENT',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'FLUME',
-        display_name: 'Flume',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Flume Agent',
-            component_name: 'FLUME_HANDLER',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      })
-    ]
-  }
-];
-
-// @todo remove after Application Timeline Server API implementation
-if (App.supports.appTimelineServer) {
-  var yarnServiceComponents = module.exports.findProperty('config_name', 'services').config_value.findProperty('service_name','YARN').get('service_components');
-  yarnServiceComponents.push(
-    Ember.Object.create({
-      display_name: 'App Timeline Server',
-      component_name: "APP_TIMELINE_SERVER",
-      component_value: '',
-      isMaster: true
-    })
-  )
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/service_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/service_configs.js b/ambari-web/app/data/service_configs.js
index 5b076b5..26986d1 100644
--- a/ambari-web/app/data/service_configs.js
+++ b/ambari-web/app/data/service_configs.js
@@ -18,279 +18,15 @@
 
 var App = require('app');
 require('models/service_config');
-require('utils/configs/defaults_providers/yarn_defaults_provider');
-require('utils/configs/defaults_providers/tez_defaults_provider');
-require('utils/configs/defaults_providers/hive_defaults_provider');
-require('utils/configs/defaults_providers/storm_defaults_provider');
-require('utils/configs/defaults_providers/oozie_defaults_provider');
 require('utils/configs/defaults_providers/user_defaults_provider');
-require('utils/configs/validators/yarn_configs_validator');
-require('utils/configs/validators/hive_configs_validator');
-require('utils/configs/validators/tez_configs_validator');
-require('utils/configs/validators/mapreduce2_configs_validator');
-require('utils/configs/validators/storm_configs_validator');
 require('utils/configs/validators/user_configs_validator');
 
+/**
+ * This
+ * @type {Array} Array of non-service tabs that will appears on  Customizes services page
+ */
 module.exports = [
-  {
-    serviceName: 'HDFS',
-    displayName: 'HDFS',
-    filename: 'hdfs-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'NameNode', displayName : 'NameNode', hostComponentNames : ['NAMENODE']}),
-      App.ServiceConfigCategory.create({ name: 'SNameNode', displayName : 'Secondary NameNode', hostComponentNames : ['SECONDARY_NAMENODE']}),
-      App.ServiceConfigCategory.create({ name: 'DataNode', displayName : 'DataNode', hostComponentNames : ['DATANODE']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedCoreSite', displayName : 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHDFSSite', displayName : 'Custom hdfs-site.xml', siteFileName: 'hdfs-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHDFSLog4j', displayName : 'Custom log4j.properties', siteFileName: 'hdfs-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'core-site', 'hdfs-site', 'hdfs-log4j'],
-    configs: []
-  },
-  {
-    serviceName: 'GLUSTERFS',
-    displayName: 'GLUSTERFS',
-    filename: 'core-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),     
-      App.ServiceConfigCategory.create({ name: 'AdvancedGlusterFSSite', displayName : 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true})
-    ],
-    sites: ['core-site'],
-    configs: []
-  },
-
-  {
-    serviceName: 'MAPREDUCE',
-    displayName: 'MapReduce',
-    filename: 'mapred-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'HistoryServer', displayName : 'History Server', hostComponentNames : ['HISTORYSERVER']}),
-      App.ServiceConfigCategory.create({ name: 'JobTracker', displayName : 'JobTracker', hostComponentNames : ['JOBTRACKER']}),
-      App.ServiceConfigCategory.create({ name: 'TaskTracker', displayName : 'TaskTracker', hostComponentNames : ['TASKTRACKER']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName : 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName : 'Custom log4j.properties', siteFileName: 'mapreduce-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'mapred-site', 'mapred-queue-acls', 'mapreduce-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'YARN',
-    displayName: 'YARN',
-    configsValidator: App.YARNConfigsValidator,
-    defaultsProviders: [App.YARNDefaultsProvider.create()],
-    filename: 'yarn-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'ResourceManager', displayName : 'Resource Manager', hostComponentNames : ['RESOURCEMANAGER']}),
-      App.ServiceConfigCategory.create({ name: 'NodeManager', displayName : 'Node Manager', hostComponentNames : ['NODEMANAGER']}),
-      App.ServiceConfigCategory.create({ name: 'AppTimelineServer', displayName : 'Application Timeline Server', hostComponentNames : ['APP_TIMELINE_SERVER']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName : 'Scheduler', isCapacityScheduler : true, isCustomView: true, siteFileName: 'capacity-scheduler.xml', siteFileNames: ['capacity-scheduler.xml', 'mapred-queue-acls.xml'], canAddProperty: App.supports.capacitySchedulerUi}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedYARNSite', displayName : 'Custom yarn-site.xml', siteFileName: 'yarn-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedYARNLog4j', displayName : 'Custom log4j.properties', siteFileName: 'yarn-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'yarn-site', 'capacity-scheduler', 'yarn-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'MAPREDUCE2',
-    displayName: 'MapReduce 2',
-    filename: 'mapred-site',
-    configsValidator: App.MapReduce2ConfigsValidator,
-    defaultsProviders: [App.YARNDefaultsProvider.create()],
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'HistoryServer', displayName : 'History Server', hostComponentNames : ['HISTORYSERVER']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName : 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName : 'Custom log4j.properties', siteFileName: 'mapreduce2-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'mapred-site', 'mapred-queue-acls', 'mapreduce2-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'HIVE',
-    displayName: 'Hive',
-    filename: 'hive-site',
-    configsValidator: App.HiveConfigsValidator,
-    defaultsProviders: [App.HiveDefaultsProvider.create()],
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Hive Metastore', displayName : 'Hive Metastore'}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHiveSite', displayName : 'Custom hive-site.xml', siteFileName: 'hive-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHiveLog4j', displayName : 'Custom log4j.properties', siteFileName: 'hive-log4j.xml', canAddProperty: false}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHiveExecLog4j', displayName : 'Custom hive-exec-log4j', siteFileName: 'hive-exec-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'hive-site', 'hive-log4j', 'hive-exec-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'WEBHCAT',
-    displayName: 'WebHCat',
-    filename: 'webhcat-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'WebHCat Server', displayName : 'WebHCat Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedWebHCatSite', displayName : 'Custom webhcat-site.xml', siteFileName: 'webhcat-site.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'webhcat-site'],
-    configs: []
-  },
-
-  {
-    serviceName: 'HBASE',
-    displayName: 'HBase',
-    filename: 'hbase-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'HBase Master', displayName : 'HBase Master'}),
-      App.ServiceConfigCategory.create({ name: 'RegionServer', displayName : 'RegionServer'}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHbaseSite', displayName : 'Custom hbase-site.xml', siteFileName: 'hbase-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHbaseLog4j', displayName : 'Custom log4j.properties', siteFileName: 'hbase-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'hbase-site', 'hbase-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'ZOOKEEPER',
-    displayName: 'ZooKeeper',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'ZooKeeper Server', displayName : 'ZooKeeper Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedZooLog4j', displayName : 'Custom log4j.properties', siteFileName: 'zookeeper-log4j.xml', canAddProperty: false}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedZooCfg', displayName : 'Custom zoo.cfg', siteFileName: 'zoo.cfg', canAddProperty: true})
-    ],
-    sites: ['global', 'zookeeper-log4j', 'zoo.cfg'],
-    configs: []
-  },
-
-  {
-    serviceName: 'OOZIE',
-    displayName: 'Oozie',
-    defaultsProviders: [App.OOZIEDefaultsProvider.create()],
-    filename: 'oozie-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Oozie Server', displayName : 'Oozie Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedOozieSite', displayName : 'Custom oozie-site.xml', siteFileName: 'oozie-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedOozieLog4j', displayName : 'Custom log4j.properties', siteFileName: 'oozie-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'oozie-site', 'oozie-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'NAGIOS',
-    displayName: 'Nagios',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'})
-    ],
-    sites: ['global'],
-    configs: []
-  },
-
-  {
-    serviceName: 'GANGLIA',
-    displayName: 'Ganglia',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'})
-    ],
-    sites: ['global'],
-    configs: []
-  },
-
-  {
-    serviceName: 'HUE',
-    displayName: 'Hue',
-    filename: 'hue-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Hue Server', displayName : 'Hue Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'})
-    ],
-    sites: ['hue-site'],
-    configs: []
-  },
-
-  {
-    serviceName: 'PIG',
-    displayName: 'Pig',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Custom pig.properties', siteFileName: 'pig-properties.xml', canAddProperty: false}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedPigLog4j', displayName : 'Custom log4j.properties', siteFileName: 'pig-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['pig-properties','pig-log4j'],
-    configs: []
-  },
-  {
-    serviceName: 'FALCON',
-    displayName: 'Falcon',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Falcon', displayName : 'Falcon Server'}),
-      App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName : 'Falcon - Oozie integration'}),
-      App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName : 'Falcon startup.properties'}),
-      App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName : 'Falcon runtime.properties'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedFalconStartupSite', displayName : 'Custom startup.properties', siteFileName: 'falcon-startup.properties.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedFalconRuntimeSite', displayName : 'Custom runtime.properties', siteFileName: 'falcon-runtime.properties.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'oozie-site','falcon-startup.properties', 'falcon-runtime.properties'],
-    configs: []
-  },
-
-  {
-    serviceName: 'STORM',
-    displayName: 'Storm',
-    configsValidator: App.STORMConfigsValidator,
-    defaultsProviders: [App.STORMDefaultsProvider.create()],
-    filename: 'storm-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Nimbus', displayName : 'Nimbus'}),
-      App.ServiceConfigCategory.create({ name: 'Supervisor', displayName : 'Supervisor'}),
-      App.ServiceConfigCategory.create({ name: 'StormUIServer', displayName : 'Storm UI Server'}),
-      App.ServiceConfigCategory.create({ name: 'StormRestApi', displayName : 'Storm REST API Server'}),
-      App.ServiceConfigCategory.create({ name: 'DRPCServer', displayName : 'DRPC Server'}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedStormSite', displayName : 'Custom storm.yaml', siteFileName: 'storm-site.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'storm-site'],
-    configs: []
-  },
-  {
-    serviceName: 'TEZ',
-    displayName: 'Tez',
-    filename: 'tez-site',
-    configsValidator: App.TezConfigsValidator,
-    defaultsProviders: [App.TezDefaultsProvider.create()],
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedTezSite', displayName : 'Custom tez-site.xml', siteFileName: 'tez-site.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'tez-site'],
-    configs: []
-  },
-  {
-    serviceName: 'FLUME',
-    displayName: 'Flume',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'FlumeAgent', displayName : 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false})
-    ],
-    sites: ['flume-conf'],
-    configs: []
-  },
-  {
+  Em.Object.create({
     serviceName: 'MISC',
     displayName: 'Misc',
     configsValidator: App.userConfigsValidator,
@@ -299,8 +35,7 @@ module.exports = [
       App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
       App.ServiceConfigCategory.create({ name: 'Users and Groups', displayName : 'Users and Groups'})
     ],
-    sites: ['global'],
+    configTypes: ['global'],
     configs: []
-  }
-
+  })
 ];

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/services.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/services.js b/ambari-web/app/data/services.js
deleted file mode 100644
index f94440b..0000000
--- a/ambari-web/app/data/services.js
+++ /dev/null
@@ -1,189 +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.
- */
-
-var App = require('app');
-
-module.exports = [
-  {
-    serviceName: 'HDFS',
-    displayName: 'HDFS',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.hdfs.description')
-  },
-  {
-    serviceName: 'GLUSTERFS',
-    displayName: 'GLUSTERFS',
-    isDisabled: false,
-    isSelected: false,
-    canBeSelected: true,
-    description: Em.I18n.t('services.glusterfs.description')
-  },
-  {
-    serviceName: 'MAPREDUCE',
-    displayName: 'MapReduce',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.mapreduce.description')
-  },
-  {
-    serviceName: 'MAPREDUCE2',
-    displayName: 'MapReduce 2',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: true,
-    description: Em.I18n.t('services.mapreduce2.description')
-  },
-  {
-    serviceName: 'YARN',
-    displayName: 'YARN + MapReduce2',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.yarn.description')
-  },
-  {
-    serviceName: 'TEZ',
-    displayName: 'Tez',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.tez.description')
-  },
-  {
-    serviceName: 'NAGIOS',
-    displayName: 'Nagios',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.nagios.description')
-  },
-  {
-    serviceName: 'GANGLIA',
-    displayName: 'Ganglia',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.ganglia.description')
-  },
-  {
-    serviceName: 'HIVE',
-    displayName: 'Hive + HCat',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.hive.description')
-  },
-  {
-    serviceName: 'HCATALOG',
-    displayName: 'HCatalog',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: true
-  },
-  {
-    serviceName: 'WEBHCAT',
-    displayName: 'WebHCat',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: true
-  },
-  {
-    serviceName: 'HBASE',
-    displayName: 'HBase',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.hbase.description')
-  },
-  {
-    serviceName: 'PIG',
-    displayName: 'Pig',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.pig.description')
-  },
-  {
-    serviceName: 'SQOOP',
-    displayName: 'Sqoop',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.sqoop.description')
-  },
-  {
-    serviceName: 'OOZIE',
-    displayName: 'Oozie',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.oozie.description')
-  },
-  {
-    serviceName: 'ZOOKEEPER',
-	  displayName: 'ZooKeeper',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.zookeeper.description')
-  },
-  {
-    serviceName: 'HUE',
-    displayName: 'Hue',
-    isDisabled: false,
-    isSelected: App.supports.hue,
-    canBeSelected: App.supports.hue,
-    isHidden: !App.supports.hue
-  },
-  {
-    serviceName: 'FALCON',
-    displayName: 'Falcon',
-    isDisabled: false,
-    isSelected: App.supports.falcon,
-    canBeSelected: App.supports.falcon,
-    isHidden: !App.supports.falcon,
-    description: Em.I18n.t('services.falcon.description')
-  },
-  {
-    serviceName: 'STORM',
-    displayName: 'Storm',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: false,
-    description: Em.I18n.t('services.storm.description')
-  }
-];
-
-if (App.supports.flume) {
-  var flume = {
-    serviceName: 'FLUME',
-    displayName: 'Flume',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: false
-  };
-  module.exports.push(flume);
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/site_properties.js b/ambari-web/app/data/site_properties.js
index 133b002..36ae907 100644
--- a/ambari-web/app/data/site_properties.js
+++ b/ambari-web/app/data/site_properties.js
@@ -30,7 +30,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 1
     },
     {
@@ -70,7 +70,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 1
     },
     {
@@ -93,7 +93,7 @@ module.exports =
       "defaultValue": "",
       "displayType": "int",
       "isVisible": true,
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "index": 3
     },
@@ -106,7 +106,7 @@ module.exports =
       "defaultDirectory": "/hadoop/hdfs/data",
       "displayType": "directories",
       "isVisible": true,
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "index": 1
     },
@@ -118,7 +118,7 @@ module.exports =
       "defaultValue": "",
       "displayType": "int",
       "isVisible": true,
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS"
     },
     {
@@ -156,7 +156,7 @@ module.exports =
       "defaultDirectory": "/hadoop/mapred",
       "displayType": "directories",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 1
     },
     {
@@ -178,7 +178,7 @@ module.exports =
       "defaultValue": "",
       "displayType": "int",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 2
     },
     {
@@ -189,7 +189,7 @@ module.exports =
       "defaultValue": "",
       "displayType": "int",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 3
     },
     {
@@ -341,7 +341,7 @@ module.exports =
       "description": "Java options for the TaskTracker child processes.",
       "defaultValue": "",
       "displayType": "advanced",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "serviceName": "MAPREDUCE",
       "index": 4
     },
@@ -357,7 +357,7 @@ module.exports =
       "displayType": "host",
       "isVisible": true,
       "isObserved": true,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 3
     },
@@ -369,7 +369,7 @@ module.exports =
       "defaultValue": "",
       "isOverridable": false,
       "displayType": "host",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 4
     },
@@ -382,7 +382,7 @@ module.exports =
       "isOverridable": false,
       "displayType": "password",
       "isVisible": true,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "filename": "oozie-site.xml",
       "index": 5
@@ -396,7 +396,7 @@ module.exports =
       "isVisible": true,
       "isOverridable": false,
       "description": "Database name used for the Oozie",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 6
     },
@@ -408,7 +408,7 @@ module.exports =
       "defaultValue": "",
       "isOverridable": false,
       "displayType": "advanced",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "index": 7
     },
@@ -423,7 +423,7 @@ module.exports =
       "isVisible": true,
       "isOverridable": false,
       "description": "Driver class name for a JDBC metastore",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 7
     },
@@ -448,7 +448,7 @@ module.exports =
       "defaultValue": "hive",
       "displayType": "host",
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 5
     },
@@ -461,7 +461,7 @@ module.exports =
       "displayType": "password",
       "isOverridable": false,
       "isVisible": true,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 6
     },
@@ -475,7 +475,7 @@ module.exports =
       "displayType": "advanced",
       "isOverridable": false,
       "isVisible": true,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "index": 8
     },
@@ -490,7 +490,7 @@ module.exports =
       "isOverridable": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 4
     },
     {
@@ -610,7 +610,7 @@ module.exports =
       "description": "Count of RPC Listener instances spun up on RegionServers",
       "defaultValue": "60",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 2
     },
@@ -623,7 +623,7 @@ module.exports =
       "displayType": "int",
       "unit": "ms",
       "isVisible": true,
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 3
     },
@@ -634,7 +634,7 @@ module.exports =
       "description": "Block updates if memstore has \"Multiplier * HBase Region Memstore Flush Size\" bytes. Useful preventing runaway memstore during spikes in update traffic",
       "defaultValue": "",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 4
     },
@@ -659,7 +659,7 @@ module.exports =
       "defaultValue": "",
       "displayType": "int",
       "unit": "bytes",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "index": 5
     },

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/mappers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js
index 6bde2fb..2b3da60 100644
--- a/ambari-web/app/mappers.js
+++ b/ambari-web/app/mappers.js
@@ -18,7 +18,7 @@
 
 //load all mappers
 require('mappers/server_data_mapper');
-require('mappers/stack_service_component_mapper');
+require('mappers/stack_service_mapper');
 require('mappers/hosts_mapper');
 require('mappers/cluster_mapper');
 require('mappers/jobs_mapper');

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/mappers/service_metrics_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_metrics_mapper.js b/ambari-web/app/mappers/service_metrics_mapper.js
index 05b3cb6..ba3c810 100644
--- a/ambari-web/app/mappers/service_metrics_mapper.js
+++ b/ambari-web/app/mappers/service_metrics_mapper.js
@@ -273,7 +273,8 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
         }
       }, this);
 
-      result = misc.sortByOrder(App.Service.servicesSortOrder, result);
+      var stackServices = App.StackService.find().mapProperty('serviceName');
+      result = misc.sortByOrder(stackServices, result);
 
       //load services to model
       App.store.loadMany(this.get('model'), result);
@@ -308,7 +309,7 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
     var isSecondaryNamenode = hostComponents.findProperty('component_name', 'SECONDARY_NAMENODE');
     services.setEach('tool_tip_content', '');
     // set tooltip for client-only services
-    var clientOnlyServiceNames = Em.A(['TEZ', 'SQOOP', 'PIG']);
+    var clientOnlyServiceNames = App.get('services.clientOnly');
     clientOnlyServiceNames.forEach(function(serviceName) {
       var service = services.findProperty('ServiceInfo.service_name', serviceName);
       if (service) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/mappers/stack_service_component_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/stack_service_component_mapper.js b/ambari-web/app/mappers/stack_service_component_mapper.js
deleted file mode 100644
index 86488e4..0000000
--- a/ambari-web/app/mappers/stack_service_component_mapper.js
+++ /dev/null
@@ -1,44 +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.
- */
-
-var App = require('app');
-
-App.stackServiceComponentMapper = App.QuickDataMapper.create({
-  model: App.StackServiceComponent,
-  config: {
-    id: 'component_name',
-    component_name: 'component_name',
-    service_name: 'service_name',
-    component_category: 'component_category',
-    is_master: 'is_master',
-    is_client: 'is_client',
-    stack_name: 'stack_name',
-    stack_version: 'stack_version'
-  },
-
-  map: function (json) {
-    var model = this.get('model');
-    if (json.items) {
-      var result = [];
-      json.items.forEach(function (item) {
-        result.push(this.parseIt(item, this.get('config')));
-      }, this);
-      App.store.loadMany(model, result);
-    }
-  }
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/mappers/stack_service_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/stack_service_mapper.js b/ambari-web/app/mappers/stack_service_mapper.js
new file mode 100644
index 0000000..5a904e4
--- /dev/null
+++ b/ambari-web/app/mappers/stack_service_mapper.js
@@ -0,0 +1,90 @@
+/**
+ * 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');
+
+App.stackServiceMapper = App.QuickDataMapper.create({
+  model: App.StackService,
+  component_model: App.StackServiceComponent,
+
+  config: {
+    id: 'service_name',
+    service_name: 'service_name',
+    config_types: 'config_types',
+    comments: 'comments',
+    service_version: 'service_version',
+    stack_name: 'stack_name',
+    stack_version: 'stack_version',
+    is_selected: 'is_selected',
+    is_installed: 'is_installed',
+    service_components_key: 'service_components',
+    service_components_type: 'array',
+    service_components: {
+      item: 'id'
+    }
+  },
+
+  component_config: {
+    id: 'component_name',
+    component_name: 'component_name',
+    service_name: 'service_name',
+    component_category: 'component_category',
+    is_master: 'is_master',
+    is_client: 'is_client',
+    stack_name: 'stack_name',
+    stack_version: 'stack_version',
+    stack_service_id: 'service_name',
+    dependencies_key: 'dependencies',
+    dependencies_type: 'array',
+    dependencies: {
+      item: 'Dependencies.component_name'
+    }
+  },
+
+  map: function (json) {
+    var model = this.get('model');
+    var result = [];
+    var stackServiceComponents = [];
+    this.rearrangeServicesForDisplayOrder(json.items, App.StackService.displayOrder);
+    json.items.forEach(function (item) {
+      //@TODO: Remove the condition when Flume becomes supported service in any stack
+      if (item.StackServices.service_name !== 'FLUME' || App.supports.flume) {
+        var stackService = item.StackServices;
+        var serviceComponents = [];
+        item.serviceComponents.forEach(function (serviceComponent) {
+          serviceComponent.StackServiceComponents.id = serviceComponent.StackServiceComponents.component_name;
+          serviceComponent.StackServiceComponents.dependencies = serviceComponent.dependencies;
+          serviceComponents.push(serviceComponent.StackServiceComponents);
+          stackServiceComponents.push(this.parseIt(serviceComponent.StackServiceComponents, this.get('component_config')));
+        }, this);
+        stackService.service_components = serviceComponents;
+        result.push(this.parseIt(stackService, this.get('config')));
+      }
+    }, this);
+    App.store.loadMany(this.get('component_model'), stackServiceComponents);
+    App.store.loadMany(model, result);
+  },
+
+  rearrangeServicesForDisplayOrder: function (array, displayOrderArray) {
+    return array.sort(function (a, b) {
+      var aValue = displayOrderArray.indexOf(a.StackServices.service_name) != -1 ? displayOrderArray.indexOf(a.StackServices.service_name) : array.length;
+      var bValue = displayOrderArray.indexOf(b.StackServices.service_name) != -1 ? displayOrderArray.indexOf(b.StackServices.service_name) : array.length;
+      return aValue - bValue;
+    });
+  }
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 5cfe957..dd6723e 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -580,28 +580,20 @@ Em.I18n.translations = {
 
   'installer.step4.header':'Choose Services',
   'installer.step4.body':'Choose which services you want to install on your cluster.',
-  'installer.step4.hdfsCheck.popup.header':'File System Required',
-  'installer.step4.hdfsCheck.popup.body':'You did not select a File System but one is required. We will automatically add HDFS. Is this OK?',
+  'installer.step4.fsCheck.popup.header':'File System Required',
+  'installer.step4.fsCheck.popup.body':'You did not select a File System but one is required. We will automatically add {0}. Is this OK?',
   'installer.step4.multipleDFS.popup.header':'Multiple File Systems Selected',
-  'installer.step4.multipleDFS.popup.body':'You selected more than one file system. We will automatically select only HDFS. Is this OK?',
-  'installer.step4.mapreduceCheck.popup.header':'MapReduce Needed',
-  'installer.step4.mapreduceCheck.popup.body':'You did not select MapReduce, but it is needed by other services you selected. We will automatically add MapReduce. Is this OK?',
-  'installer.step4.yarnCheck.popup.header':'YARN+MapReduce2 Needed',
-  'installer.step4.yarnCheck.popup.body':'You did not select YARN+MapReduce2, but it is needed by other services you selected. We will automatically add YARN+MapReduce2. Is this OK?',
-  'installer.step4.zooKeeperCheck.popup.header':'ZooKeeper Needed',
-  'installer.step4.zooKeeperCheck.popup.body':'You did not select ZooKeeper, but it is needed by other services you selected. We will automatically add ZooKeeper. Is this OK?',
-  'installer.step4.oozieCheck.popup.header':'Oozie Needed',
-  'installer.step4.oozieCheck.popup.body':'You did not select Oozie, but it is needed by other services you selected. We will automatically add Oozie. Is this OK?',
-  'installer.step4.tezCheck.popup.header':'Tez Needed',
-  'installer.step4.tezCheck.popup.body':'You did not select Tez, but it is needed by other services you selected. We will automatically add Tez. Is this OK?',
+  'installer.step4.multipleDFS.popup.body':'You selected more than one file system. We will automatically select only {0}. Is this OK?',
+  'installer.step4.serviceCheck.popup.header':'{0} Needed',
+  'installer.step4.serviceCheck.popup.body':'You did not select {0}, but it is needed by other services you selected. We will automatically add {0}. Is this OK?',
   'installer.step4.monitoringCheck.popup.header':'Limited Functionality Warning',
-  'installer.step4.monitoringCheck.popup.body':'You did not select Nagios and/or Ganglia. If both are not selected, monitoring and alerts will not function properly. Is this OK?',
+  'installer.step4.monitoringCheck.popup.body':'You did not select {0}. If {1} is not selected, monitoring and alerts will not function properly. Is this OK?',
 
   'installer.step5.header':'Assign Masters',
   'installer.step5.reassign.header':'Select Target Host',
   'installer.step5.attention':' hosts not running master services',
   'installer.step5.body':'Assign master components to hosts you want to run them on.',
-  'installer.step5.body.hive':'<i class="icon-asterisks">&#10037;</i> HiveServer2, Hive Metastore, and WebHCat Server will be hosted on the same server.',
+  'installer.step5.body.coHostedComponents':'<i class="icon-asterisks">&#10037;</i> {0} will be hosted on the same host.',
   'installer.step5.hostInfo':'%@ (%@, %@ cores)',
   'installer.step5.hiveGroup':'HiveServer2, WebHCat Server, MySQL Server',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/mixins.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js
index e8a89a8..ba5d51f 100644
--- a/ambari-web/app/mixins.js
+++ b/ambari-web/app/mixins.js
@@ -21,6 +21,7 @@
 
 require('mixins/common/localStorage');
 require('mixins/common/userPref');
+require('mixins/models/service_mixin');
 require('mixins/common/tableServerProvider');
 require('mixins/main/host/details/host_components/decommissionable');
-require('mixins/wizard/selectHost');
\ No newline at end of file
+require('mixins/wizard/selectHost');

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/mixins/models/service_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/models/service_mixin.js b/ambari-web/app/mixins/models/service_mixin.js
new file mode 100644
index 0000000..4c6b069
--- /dev/null
+++ b/ambari-web/app/mixins/models/service_mixin.js
@@ -0,0 +1,30 @@
+/**
+ * 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');
+
+/**
+ * Service Mixin that used for App.StackService and App.Service models.
+ *
+ **/
+App.ServiceModelMixin = Em.Mixin.create({
+  serviceName: DS.attr('string'),
+  displayName: function() {
+    return App.format.role(this.get('serviceName'));
+  }.property('serviceName')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index b9239fb..2c3bce0 100644
--- a/ambari-web/app/models.js
+++ b/ambari-web/app/models.js
@@ -24,6 +24,7 @@ require('models/authentication');
 require('models/cluster');
 require('models/cluster_states');
 require('models/hosts');
+require('models/stack_service');
 require('models/stack_service_component');
 require('models/quick_links');
 require('models/service');

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/models/host_component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/host_component.js b/ambari-web/app/models/host_component.js
index 0671552..adcecb2 100644
--- a/ambari-web/app/models/host_component.js
+++ b/ambari-web/app/models/host_component.js
@@ -33,11 +33,7 @@ App.HostComponent = DS.Model.extend({
    * @returns {bool}
    */
   isClient:function () {
-    if(['PIG', 'SQOOP', 'HCAT', 'MAPREDUCE2_CLIENT'].contains(this.get('componentName'))){
-      return true;
-    }
-
-    return Boolean(this.get('componentName').match(/_client/gi));
+    return App.get('components.clients').contains(this.get('componentName'));
   }.property('componentName'),
   /**
    * Determine if component is running now

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/models/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js
index d6f39a6..9952855 100644
--- a/ambari-web/app/models/service.js
+++ b/ambari-web/app/models/service.js
@@ -19,10 +19,9 @@
 
 var App = require('app');
 require('utils/config');
+require('mixins/models/service_mixin');
 
-App.Service = DS.Model.extend({
-
-  serviceName: DS.attr('string'),
+App.Service = DS.Model.extend(App.ServiceModelMixin, {
   passiveState: DS.attr('string'),
   workStatus: DS.attr('string'),
   rand: DS.attr('string'),
@@ -72,35 +71,6 @@ App.Service = DS.Model.extend({
     return this.get('workStatus') === 'STARTED';
   }.property('workStatus'),
 
-  isClientsOnly: function() {
-    var clientsOnly = ['GLUSTERFS','SQOOP','PIG','TEZ','HCATALOG'];
-    return clientsOnly.contains(this.get('serviceName'));
-  }.property('serviceName'),
-
-  isConfigurable: function () {
-    var configurableServices = [
-      "HDFS",
-      "GLUSTERFS",
-      "YARN",
-      "MAPREDUCE",
-      "MAPREDUCE2",
-      "HBASE",
-      "OOZIE",
-      "HIVE",
-      "WEBHCAT",
-      "ZOOKEEPER",
-      "PIG",
-      "NAGIOS",
-      "GANGLIA",
-      "HUE",
-      "TEZ",
-      "STORM",
-      "FALCON",
-      "FLUME"
-    ];
-    return configurableServices.contains(this.get('serviceName'));
-  }.property('serviceName'),
-
   /**
    * Service Tagging by their type.
    * @type {String[]}
@@ -230,29 +200,6 @@ App.Service.DisplayNames = {
   'STORM': 'Storm'
 };
 
-App.Service.servicesSortOrder = [
-  'HDFS',
-  'GLUSTERFS',
-  'YARN',
-  'MAPREDUCE',
-  'MAPREDUCE2',
-  'TEZ',
-  'HBASE',
-  'HIVE',
-  'HCATALOG',
-  'WEBHCAT',
-  'FLUME',
-  'FALCON',
-  'STORM',
-  'OOZIE',
-  'GANGLIA',
-  'NAGIOS',
-  'ZOOKEEPER',
-  'PIG',
-  'SQOOP',
-  'HUE'
-];
-
 /**
  * association between service and extended model name
  * @type {Object}


[3/6] AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Posted by yu...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/models/stack_service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack_service.js b/ambari-web/app/models/stack_service.js
new file mode 100644
index 0000000..8085a03
--- /dev/null
+++ b/ambari-web/app/models/stack_service.js
@@ -0,0 +1,382 @@
+/**
+ * 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');
+require('utils/helper');
+require('mixins/models/service_mixin');
+require('models/service_config');
+require('utils/configs/defaults_providers/yarn_defaults_provider');
+require('utils/configs/defaults_providers/tez_defaults_provider');
+require('utils/configs/defaults_providers/hive_defaults_provider');
+require('utils/configs/defaults_providers/storm_defaults_provider');
+require('utils/configs/defaults_providers/oozie_defaults_provider');
+require('utils/configs/validators/yarn_configs_validator');
+require('utils/configs/validators/hive_configs_validator');
+require('utils/configs/validators/tez_configs_validator');
+require('utils/configs/validators/mapreduce2_configs_validator');
+require('utils/configs/validators/storm_configs_validator');
+
+/**
+ * This model loads all services supported by the stack
+ * The model maps to the  http://hostname:8080/api/v1/stacks2/HDP/versions/${versionNumber}/stackServices?fields=StackServices/*,serviceComponents/*
+ * @type {*}
+ */
+App.StackService = DS.Model.extend(App.ServiceModelMixin, {
+  comments: DS.attr('string'),
+  configTypes: DS.attr('array'),
+  serviceVersion: DS.attr('string'),
+  stackName: DS.attr('string'),
+  stackVersion: DS.attr('string'),
+  isSelected: DS.attr('boolean', {defaultValue: true}),
+  isInstalled: DS.attr('boolean', {defaultValue: false}),
+  serviceComponents: DS.hasMany('App.StackServiceComponent'),
+  configs: DS.attr('array'),
+
+  // Is the service a distributed filesystem
+  isDFS: function () {
+    var dfsServices = ['HDFS', 'GLUSTERFS'];
+    return dfsServices.contains(this.get('serviceName'));
+  }.property('serviceName'),
+
+  // Primary DFS. used if there is more than one DFS in a stack.
+  // Only one service in the stack should be tagged as primary DFS.
+  isPrimaryDFS: function () {
+    return this.get('serviceName') === 'HDFS';
+  }.property('serviceName'),
+
+  displayNameOnSelectServicePage: function () {
+    var displayName = this.get('displayName');
+    var services = this.get('coSelectedServices').slice();
+    var serviceDisplayNames = services.map(function (item) {
+      return App.format.role(item);
+    }, this);
+    if (!!serviceDisplayNames.length) {
+      serviceDisplayNames.unshift(displayName);
+      displayName = serviceDisplayNames.join(" + ");
+    }
+    return displayName;
+  }.property('coSelectedServices', 'serviceName'),
+
+  isHiddenOnSelectServicePage: function () {
+    var hiddenServices = ['MAPREDUCE2', 'HCATALOG', 'WEBHCAT'];
+    return hiddenServices.contains(this.get('serviceName'));
+  }.property('serviceName'),
+
+  dependentServices: function () {
+    var serviceName = this.get('serviceName');
+    var dependentServices = [];
+    if (App.get('isHadoop2Stack')) {
+      dependentServices = App.StackService.dependency['HDP-2'][serviceName];
+    } else {
+      dependentServices = App.StackService.dependency['HDP-1'][serviceName];
+    }
+    return dependentServices;
+  }.property('serviceName'),
+
+  /**
+   * other services on which the service is dependent
+   */
+  serviceDependency: function () {
+    var serviceName = this.get('serviceName');
+    var serviceDependencyMap, key, serviceDependencies = [];
+    if (App.get('isHadoop2Stack')) {
+      serviceDependencyMap = App.StackService.dependency['HDP-2'];
+    } else {
+      serviceDependencyMap = App.StackService.dependency['HDP-1'];
+    }
+    for (key in serviceDependencyMap) {
+      if (serviceDependencyMap[key].contains(serviceName)) serviceDependencies.pushObject(key);
+    }
+    return  serviceDependencies;
+  }.property('serviceName'),
+
+  // Is the service required for monitoring of other hadoop ecosystem services
+  isMonitoringService: function () {
+    var services = ['NAGIOS', 'GANGLIA'];
+    return services.contains(this.get('serviceName'));
+  }.property('serviceName'),
+
+  coSelectedServices: function () {
+    var coSelectedServices = App.StackService.coSelected[this.get('serviceName')];
+    if (!!coSelectedServices) {
+      return coSelectedServices;
+    } else {
+      return [];
+    }
+  }.property('serviceName'),
+
+  hasClient: function () {
+    var serviceComponents = this.get('serviceComponents');
+    return serviceComponents.someProperty('isClient');
+  }.property('serviceName'),
+
+  isClientOnlyService: function () {
+    var serviceComponents = this.get('serviceComponents');
+    return serviceComponents.everyProperty('isClient');
+  }.property('serviceName'),
+
+  isNoConfigTypes: function () {
+   return !(this.get('configTypes') && this.get('configTypes').length);
+  }.property('configTypes'),
+
+  customReviewHandler: function () {
+    return App.StackService.reviewPageHandlers[this.get('serviceName')];
+  }.property('serviceName'),
+
+  defaultsProviders: function () {
+    var defaultConfigsHandler = App.StackService.defaultConfigsHandler[this.get('serviceName')];
+    return defaultConfigsHandler && defaultConfigsHandler.defaultsProviders;
+  }.property('serviceName'),
+
+  configsValidator: function () {
+    var defaultConfigsHandler = App.StackService.defaultConfigsHandler[this.get('serviceName')];
+    return defaultConfigsHandler && defaultConfigsHandler.configsValidator;
+  }.property('serviceName'),
+
+  /**
+   * configCategories are fetched from  App.StackService.configCategories.
+   * Also configCategories that does not match any serviceComponent of a service and not included in the permissible default pattern are omitted
+   */
+  configCategories: function () {
+    var configCategories = [];
+    var serviceName = this.get('serviceName');
+    var configTypes = this.get('configTypes');
+    var serviceComponents = this.get('serviceComponents');
+    if (configTypes.length) {
+      var pattern = ["General", "CapacityScheduler", "^Advanced", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
+      configCategories = App.StackService.configCategories(serviceName).filter(function (_configCategory) {
+        var serviceComponentName = _configCategory.get('name');
+        var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName);
+        if (isServiceComponent) return  isServiceComponent;
+        var result = false;
+        pattern.forEach(function (_pattern) {
+          var regex = new RegExp(_pattern);
+          if (regex.test(serviceComponentName)) result = true;
+        });
+        return result;
+      });
+    }
+    return configCategories;
+  }.property('serviceName', 'configTypes', 'serviceComponents'),
+
+  serviceConfigs: function () {
+    var configCategories = [];
+    var serviceName = this.get('serviceName');
+    var serviceComponents = this.get('serviceComponents');
+    configCategories = App.StackService.configCategories(serviceName).filter(function (_configCategory) {
+      var serviceComponentName = _configCategory.get('name');
+      return serviceComponents.someProperty('componentName', serviceComponentName);
+    });
+    return configCategories;
+  }.observes('serviceName', 'serviceComponents')
+
+});
+
+App.StackService.FIXTURES = [];
+
+App.StackService.displayOrder = [
+  'HDFS',
+  'MAPREDUCE',
+  'MAPREDUCE2',
+  'YARN',
+  'TEZ',
+  'NAGIOS',
+  'GANGLIA',
+  'HIVE',
+  'HCATALOG',
+  'WEBHCAT',
+  'HBASE',
+  'PIG',
+  'SQOOP',
+  'OOZIE',
+  'ZOOKEEPER',
+  'HUE',
+  'FALCON',
+  'STORM',
+  'FLUME'
+];
+
+App.StackService.dependency = {
+  'HDP-1': {
+    'MAPREDUCE': ['PIG', 'OOZIE', 'HIVE'],
+    'ZOOKEEPER': ['HBASE', 'HIVE', 'WEBHCAT']
+  },
+  'HDP-2': {
+    'YARN': ['PIG', 'OOZIE', 'HIVE', 'TEZ'],
+    'TEZ': ['YARN'],
+    'OOZIE': ['FALCON'],
+    'ZOOKEEPER': ['HDFS', 'HBASE', 'HIVE', 'WEBHCAT', 'STORM']
+  }
+};
+
+//@TODO: Write unit test for no two keys in the object should have any intersecting elements in their values
+App.StackService.coSelected = {
+  'YARN': ['MAPREDUCE2'],
+  'HIVE': ['HCATALOG', 'WEBHCAT']
+};
+
+
+App.StackService.reviewPageHandlers = {
+  'HIVE': {
+    'Database': 'loadHiveDbValue'
+  },
+  'NAGIOS': {
+    'Administrator': 'loadNagiosAdminValue'
+  },
+  'OOZIE': {
+    'Database': 'loadOozieDbValue'
+  }
+};
+
+App.StackService.defaultConfigsHandler = {
+  YARN: {defaultsProviders: [App.YARNDefaultsProvider.create()], configsValidator: App.YARNConfigsValidator},
+  MAPREDUCE2: {defaultsProviders: [App.YARNDefaultsProvider.create()], configsValidator: App.MapReduce2ConfigsValidator},
+  HIVE: {defaultsProviders: [App.HiveDefaultsProvider.create()], configsValidator: App.HiveConfigsValidator},
+  STORM: {defaultsProviders: [App.STORMDefaultsProvider.create()], configsValidator: App.STORMConfigsValidator},
+  TEZ: {defaultsProviders: [App.TezDefaultsProvider.create()], configsValidator: App.TezConfigsValidator}
+};
+
+App.StackService.configCategories = function (serviceName) {
+  switch (serviceName) {
+    case 'HDFS':
+      return [
+        App.ServiceConfigCategory.create({ name: 'NAMENODE', displayName: 'NameNode'}),
+        App.ServiceConfigCategory.create({ name: 'SECONDARY_NAMENODE', displayName: 'Secondary NameNode'}),
+        App.ServiceConfigCategory.create({ name: 'DATANODE', displayName: 'DataNode'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedCoreSite', displayName: 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHDFSSite', displayName: 'Custom hdfs-site.xml', siteFileName: 'hdfs-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHDFSLog4j', displayName: 'Custom log4j.properties', siteFileName: 'hdfs-log4j.xml', canAddProperty: false})
+      ];
+    case 'GLUSTERFS':
+      return [
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedGlusterFSSite', displayName : 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true})
+      ];
+    case 'MAPREDUCE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server'}),
+        App.ServiceConfigCategory.create({ name: 'JOBTRACKER', displayName: 'JobTracker'}),
+        App.ServiceConfigCategory.create({ name: 'TASKTRACKER', displayName: 'TaskTracker'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName: 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName: 'Custom log4j.properties', siteFileName: 'mapreduce-log4j.xml', canAddProperty: false})
+      ];
+    case 'YARN':
+      return [
+        App.ServiceConfigCategory.create({ name: 'RESOURCEMANAGER', displayName: 'Resource Manager'}),
+        App.ServiceConfigCategory.create({ name: 'NODEMANAGER', displayName: 'Node Manager'}),
+        App.ServiceConfigCategory.create({ name: 'APP_TIMELINE_SERVER', displayName: 'Application Timeline Server'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName: 'Scheduler', isCapacityScheduler: true, isCustomView: true, siteFileName: 'capacity-scheduler.xml', siteFileNames: ['capacity-scheduler.xml', 'mapred-queue-acls.xml'], canAddProperty: App.supports.capacitySchedulerUi}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedYARNSite', displayName: 'Custom yarn-site.xml', siteFileName: 'yarn-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedYARNLog4j', displayName: 'Custom log4j.properties', siteFileName: 'yarn-log4j.xml', canAddProperty: false})
+      ];
+    case 'MAPREDUCE2':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName: 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName: 'Custom log4j.properties', siteFileName: 'mapreduce2-log4j.xml', canAddProperty: false})
+      ];
+    case 'HIVE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HIVE_METASTORE', displayName: 'Hive Metastore'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHiveSite', displayName: 'Custom hive-site.xml', siteFileName: 'hive-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHiveLog4j', displayName: 'Custom log4j.properties', siteFileName: 'hive-log4j.xml', canAddProperty: false}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHiveExecLog4j', displayName: 'Custom hive-exec-log4j', siteFileName: 'hive-exec-log4j.xml', canAddProperty: false})
+      ];
+    case 'WEBHCAT':
+      return [
+        App.ServiceConfigCategory.create({ name: 'WEBHCAT_SERVER', displayName: 'WebHCat Server'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedWebHCatSite', displayName: 'Custom webhcat-site.xml', siteFileName: 'webhcat-site.xml', canAddProperty: true})
+      ];
+    case 'HBASE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HBASE_MASTER', displayName: 'HBase Master'}),
+        App.ServiceConfigCategory.create({ name: 'HBASE_REGIONSERVER', displayName: 'RegionServer'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHbaseSite', displayName: 'Custom hbase-site.xml', siteFileName: 'hbase-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHbaseLog4j', displayName: 'Custom log4j.properties', siteFileName: 'hbase-log4j.xml', canAddProperty: false})
+      ];
+    case 'ZOOKEEPER':
+      return [
+        App.ServiceConfigCategory.create({ name: 'ZOOKEEPER_SERVER', displayName: 'ZooKeeper Server'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedZooLog4j', displayName: 'Custom log4j.properties', siteFileName: 'zookeeper-log4j.xml', canAddProperty: false}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedZooCfg', displayName: 'Custom zoo.cfg', siteFileName: 'zoo.cfg', canAddProperty: true})
+      ];
+    case 'OOZIE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'OOZIE_SERVER', displayName: 'Oozie Server'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedOozieSite', displayName: 'Custom oozie-site.xml', siteFileName: 'oozie-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedOozieLog4j', displayName: 'Custom log4j.properties', siteFileName: 'oozie-log4j.xml', canAddProperty: false})
+      ];
+    case 'PIG':
+    return [
+      App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Custom pig.properties', siteFileName: 'pig-properties.xml', canAddProperty: false}),
+      App.ServiceConfigCategory.create({ name: 'AdvancedPigLog4j', displayName: 'Custom log4j.properties', siteFileName: 'pig-log4j.xml', canAddProperty: false})
+    ];
+    case 'FALCON':
+      return [
+        App.ServiceConfigCategory.create({ name: 'FALCON_SERVER', displayName: 'Falcon Server'}),
+        App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'}),
+        App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName: 'Falcon startup.properties'}),
+        App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName: 'Falcon runtime.properties'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedFalconStartupSite', displayName: 'Custom startup.properties', siteFileName: 'falcon-startup.properties.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedFalconRuntimeSite', displayName: 'Custom runtime.properties', siteFileName: 'falcon-runtime.properties.xml', canAddProperty: true})
+      ];
+    case 'STORM':
+      return [
+        App.ServiceConfigCategory.create({ name: 'NIMBUS', displayName: 'Nimbus'}),
+        App.ServiceConfigCategory.create({ name: 'SUPERVISOR', displayName: 'Supervisor'}),
+        App.ServiceConfigCategory.create({ name: 'STORM_UI_SERVER', displayName: 'Storm UI Server'}),
+        App.ServiceConfigCategory.create({ name: 'STORM_REST_API', displayName: 'Storm REST API Server'}),
+        App.ServiceConfigCategory.create({ name: 'DRPC_SERVER', displayName: 'DRPC Server'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedStormSite', displayName: 'Custom storm.yaml', siteFileName: 'storm-site.xml', canAddProperty: true})
+      ];
+    case 'TEZ':
+      return [
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedTezSite', displayName: 'Custom tez-site.xml', siteFileName: 'tez-site.xml', canAddProperty: true})
+      ];
+    case 'FLUME':
+      return [
+        App.ServiceConfigCategory.create({ name: 'FLUME_HANDLER', displayName: 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false})
+      ];
+    case 'HCATALOG':
+      return [];
+    default:
+      return [
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General', canAddProperty: false}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced', canAddProperty: false})
+      ];
+  }
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/models/stack_service_component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack_service_component.js b/ambari-web/app/models/stack_service_component.js
index 51f944a..10e9a51 100644
--- a/ambari-web/app/models/stack_service_component.js
+++ b/ambari-web/app/models/stack_service_component.js
@@ -23,15 +23,22 @@ var App = require('app');
  */
 App.StackServiceComponent = DS.Model.extend({
   componentName: DS.attr('string'),
+  dependencies: DS.attr('array'),
   serviceName: DS.attr('string'),
   componentCategory: DS.attr('string'),
   isMaster: DS.attr('boolean'),
   isClient: DS.attr('boolean'),
   stackName: DS.attr('string'),
   stackVersion: DS.attr('string'),
+  stackService: DS.belongsTo('App.StackService'),
+  serviceComponentId: DS.attr('number', {defaultValue: 1}), // this is used on Assign Master page for multiple masters
 
   displayName: function() {
-    return App.format.components[this.get('componentName')];
+    if (App.format.role(this.get('componentName'))) {
+      return App.format.role(this.get('componentName'));
+    } else {
+      return this.get('componentName');
+    }
   }.property('componentName'),
 
   isSlave: function() {
@@ -68,9 +75,140 @@ App.StackServiceComponent = DS.Model.extend({
 
   isShownOnInstallerAssignMasterPage: function() {
     var component = this.get('componentName');
-    var mastersNotShown = ['MYSQL_SERVER','JOURNALNODE'];
+    var mastersNotShown = ['MYSQL_SERVER'];
     return ((this.get('isMaster') && !mastersNotShown.contains(component)) || component === 'APP_TIMELINE_SERVER');
-  }.property('isMaster','componentName')
+  }.property('isMaster','componentName'),
+
+  isShownOnInstallerSlaveClientPage: function() {
+    var component = this.get('componentName');
+    var slavesNotShown = ['JOURNALNODE','ZKFC','APP_TIMELINE_SERVER','GANGLIA_MONITOR'];
+    return this.get('isSlave') && !slavesNotShown.contains(component);
+  }.property('isSlave','componentName'),
+
+  isShownOnAddServiceAssignMasterPage: function() {
+    var isVisible = this.get('isShownOnInstallerAssignMasterPage');
+    if (App.get('isHaEnabled')) {
+      isVisible =  isVisible && this.get('componentName') !== 'SECONDARY_NAMENODE';
+    }
+    return isVisible;
+  }.property('isShownOnInstallerAssignMasterPage','App.isHaEnabled'),
+
+  isMasterWithMultipleInstances: function() {
+    var masters = ['ZOOKEEPER_SERVER', 'HBASE_MASTER'];
+    return masters.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  /** Some non master components can be assigned as master **/
+  isMasterBehavior: function() {
+    var componentsName = ['APP_TIMELINE_SERVER'];
+    return componentsName.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  /** Some non client components can be assigned as clients **/
+  isClientBehavior: function() {
+    var componentName = ['GANGLIA_MONITOR'];
+    return componentName.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  /** Components that can be installed only if HA enabled **/
+  isHAComponentOnly: function() {
+    var HAComponentNames = ['ZKFC','JOURNALNODE'];
+    return HAComponentNames.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  // Is It require to install the components on all hosts. used in step-6 wizard controller
+  isRequiredOnAllHosts: function() {
+    var service = this.get('stackService');
+    return service.get('isMonitoringService') && this.get('isSlave') ;
+  }.property('stackService','isSlave'),
+
+  // components that are not to be installed with ambari server
+  isNotPreferableOnAmbariServerHost: function() {
+    var service = ['STORM_UI_SERVER', 'DRPC_SERVER', 'STORM_REST_API', 'NIMBUS', 'GANGLIA_SERVER', 'NAGIOS_SERVER', 'HUE_SERVER'];
+    return service.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  // default number of master hosts on Assign Master page:
+  defaultNoOfMasterHosts: function() {
+    var componentName = this.get('componentName');
+     if (this.get('isMasterWithMultipleInstances')) {
+       return App.StackServiceComponent.cardinality(componentName).min;
+     }
+  }.property('componentName'),
+
+  selectionSchemeForMasterComponent: function() {
+    return App.StackServiceComponent.selectionScheme(this.get('componentName'));
+  }.property('componentName'),
+
+  isMasterWithMultipleInstancesHaWizard: function() {
+    var masters = ['NAMENODE', 'JOURNALNODE'];
+    return masters.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  // components that are co-hosted with this component
+  coHostedComponents: function() {
+    var componentName = this.get('componentName');
+    var key, coHostedComponents = [];
+    for (key in App.StackServiceComponent.coHost) {
+      if (App.StackServiceComponent.coHost[key] === componentName) {
+        coHostedComponents.push(key)
+      }
+    }
+    return coHostedComponents;
+  }.property('componentName'),
+
+  // Is any other component co-hosted with this component
+  isOtherComponentCoHosted: function() {
+    return !!this.get('coHostedComponents').length;
+  }.property('coHostedComponents'),
+
+  // Is this component co-hosted with other component
+  isCoHostedComponent: function() {
+    var componentName = this.get('componentName');
+    return !!App.StackServiceComponent.coHost[componentName];
+  }.property('componentName')
+
 });
 
-App.StackServiceComponent.FIXTURES = [];
\ No newline at end of file
+App.StackServiceComponent.FIXTURES = [];
+
+App.StackServiceComponent.selectionScheme = function (componentName){
+  switch (componentName) {
+    case 'NAMENODE' :
+      return {"else": 0};
+    case 'SECONDARY_NAMENODE' :
+      return {"else": 1};
+    case 'HBASE_MASTER':
+      return {"6": 0, "31": 2, "else": 3};
+    case 'JOBTRACKER':
+    case 'HISTORYSERVER':
+    case 'RESOURCEMANAGER':
+    case 'APP_TIMELINE_SERVER':
+      return {"31": 1, "else": 2};
+    case 'OOZIE_SERVER':
+    case 'FALCON_SERVER' :
+      return {"6": 1, "31": 2, "else": 3};
+    case 'HIVE_SERVER' :
+    case 'HIVE_METASTORE' :
+    case 'WEBHCAT_SERVER' :
+      return {"6": 1, "31": 2, "else": 4};
+    default:
+      return {"else": 0};
+  }
+};
+
+App.StackServiceComponent.cardinality = function (componentName) {
+  switch (componentName) {
+    case 'ZOOKEEPER_SERVER':
+      return {min: 3};
+    case 'HBASE_MASTER':
+      return {min: 1};
+    default:
+      return {min:1, max:1};
+  }
+};
+
+App.StackServiceComponent.coHost = {
+  'HIVE_METASTORE': 'HIVE_SERVER',
+  'WEBHCAT_SERVER': 'HIVE_SERVER'
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/routes/add_host_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_host_routes.js b/ambari-web/app/routes/add_host_routes.js
index d73499c..2dad8dc 100644
--- a/ambari-web/app/routes/add_host_routes.js
+++ b/ambari-web/app/routes/add_host_routes.js
@@ -102,7 +102,6 @@ module.exports = App.WizardRoute.extend({
       controller.setCurrentStep('1');
       controller.set('hideBackButton', true);
       controller.dataLoading().done(function () {
-        controller.loadServicesFromServer();
         controller.loadAllPriorSteps();
         var wizardStep2Controller = router.get('wizardStep2Controller');
         wizardStep2Controller.set('wizardController', controller);
@@ -184,7 +183,6 @@ module.exports = App.WizardRoute.extend({
         var wizardStep6Controller = router.get('wizardStep6Controller');
         wizardStep6Controller.set('wizardController', controller);
         controller.connectOutlet('wizardStep6', controller.get('content'));
-        wizardStep6Controller.set('isMasters', false);
       });
     },
     back: Em.Router.transitionTo('step2'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/routes/add_service_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_service_routes.js b/ambari-web/app/routes/add_service_routes.js
index 6cd9d9c..9aa6edb 100644
--- a/ambari-web/app/routes/add_service_routes.js
+++ b/ambari-web/app/routes/add_service_routes.js
@@ -102,9 +102,9 @@ module.exports = App.WizardRoute.extend({
       console.log('in addService.step1:connectOutlets');
       var controller = router.get('addServiceController');
       controller.setCurrentStep('1');
+      controller.setDBProperty('services',undefined);
       controller.set('hideBackButton', true);
       controller.dataLoading().done(function () {
-        controller.loadServicesFromServer();
         controller.loadAllPriorSteps();
         controller.connectOutlet('wizardStep4', controller.get('content.services'));
       })
@@ -153,7 +153,6 @@ module.exports = App.WizardRoute.extend({
         var wizardStep6Controller = router.get('wizardStep6Controller');
         wizardStep6Controller.set('wizardController', controller);
         controller.connectOutlet('wizardStep6', controller.get('content'));
-        wizardStep6Controller.set('isMasters', false);
       })
     },
     back: function(router){

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/routes/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js
index e9c4288..637f8b9 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -204,7 +204,8 @@ module.exports = Em.Route.extend({
       var wizardStep3Controller = router.get('wizardStep3Controller');
       installerController.saveConfirmedHosts(wizardStep3Controller);
       installerController.setDBProperty('bootStatus', true);
-      installerController.loadServicesFromServer();
+      installerController.setDBProperty('selectedServiceNames', undefined);
+      installerController.setDBProperty('installedServiceNames', undefined);
       router.transitionTo('step4');
     },
     exit: function (router) {
@@ -230,7 +231,7 @@ module.exports = Em.Route.extend({
       var controller = router.get('installerController');
       controller.setCurrentStep('4');
       controller.loadAllPriorSteps();
-      controller.connectOutlet('wizardStep4', controller.get('content.services'));
+      controller.connectOutlet('wizardStep4', App.StackService.find());
     },
     back: Em.Router.transitionTo('step3'),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index b1f40dd..6b46d19 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -706,7 +706,7 @@ module.exports = Em.Route.extend({
           var item = router.get('mainServiceItemController.content');
           //if service is not existed then route to default service
           if (item.get('isLoaded')) {
-            if (item.get('isConfigurable')) {
+            if (router.get('mainServiceItemController.isConfigurable')) {
               router.get('mainServiceItemController').connectOutlet('mainServiceInfoConfigs', item);
             }
             else {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/highAvailability/step2.hbs b/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
index d731e89..5fb4964 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/step2.hbs
@@ -25,53 +25,54 @@
     <form class="form-horizontal" autocomplete="off">
       <!-- View for array controller -->
       {{#each servicesMasters}}
-      <div class="control-group">
-        <label class="control-label">
-          {{#if isCurNameNode}}
-            {{t common.current}}
-          {{/if}}
-          {{#if isAddNameNode}}
-            {{t common.additional}}
-          {{/if}}
-          {{display_name}}:
-        </label>
-        <div class="controls">
-          {{#if view.shouldUseInputs}}
-            {{view App.InputHostView
-            componentBinding="this"
-            disabledBinding="isInstalled" }}
-          {{else}}
-            {{view App.SelectHostView
-            componentBinding="this"
-            disabledBinding="isInstalled"
-            optionValuePath="content.host_name"
-            optionLabelPath="content.host_info" }}
-          {{/if}}
-          {{#if showAddControl}}
-          {{view App.AddControlView componentNameBinding="component_name"}}
-          {{/if}}
-          {{#if showRemoveControl}}
-          {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
-          {{/if}}
+        <div class="control-group">
+          <label class="control-label">
+            {{#if isCurNameNode}}
+              {{t common.current}}
+            {{/if}}
+            {{#if isAddNameNode}}
+              {{t common.additional}}
+            {{/if}}
+            {{display_name}}:
+          </label>
+
+          <div class="controls">
+            {{#if view.shouldUseInputs}}
+              {{view App.InputHostView
+              componentBinding="this"
+              disabledBinding="isInstalled" }}
+            {{else}}
+              {{view App.SelectHostView
+              componentBinding="this"
+              disabledBinding="isInstalled"
+              optionValuePath="content.host_name"
+              optionLabelPath="content.host_info" }}
+            {{/if}}
+            {{#if showAddControl}}
+              {{view App.AddControlView componentNameBinding="component_name"}}
+            {{/if}}
+            {{#if showRemoveControl}}
+              {{view App.RemoveControlView componentNameBinding="component_name" serviceComponentIddBinding="serviceComponentId"}}
+            {{/if}}
+          </div>
         </div>
-      </div>
       {{/each}}
     </form>
   </div>
 
   <div class="host-assignments span5">
     {{#each masterHostMapping}}
-    <div class="mapping-box round-corners well">
-      <div class="hostString"><span>{{hostInfo}}</span></div>
-      {{#each masterServices}}
-      <span {{bindAttr class="isInstalled:assignedService:newService :round-corners"}}>{{display_name}}</span>
-      {{/each}}
-    </div>
+      <div class="mapping-box round-corners well">
+        <div class="hostString"><span>{{hostInfo}}</span></div>
+        {{#each masterServices}}
+          <span {{bindAttr class="isInstalled:assignedService:newService :round-corners"}}>{{display_name}}</span>
+        {{/each}}
+      </div>
     {{/each}}
 
     {{#if remainingHosts}}
-    <div class="remaining-hosts round-corners well">
-      <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
+      <div class="remaining-hosts round-corners well">
+        <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
     {{/if}}
   </div>
   <div style="clear: both;"></div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/templates/main/service/item.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/item.hbs b/ambari-web/app/templates/main/service/item.hbs
index 1fd017a..7b904f0 100644
--- a/ambari-web/app/templates/main/service/item.hbs
+++ b/ambari-web/app/templates/main/service/item.hbs
@@ -64,7 +64,7 @@
         <!-- dropdown menu links -->
 
         <!-- Start/Stop service actions -->
-        {{#unless controller.content.isClientsOnly}}
+        {{#unless controller.isClientsOnlyService}}
           <li {{bindAttr class="controller.isStartDisabled:disabled"}}>
             <a href="javascript:void(null)" {{bindAttr class="controller.isStartDisabled:disabled" }}
               {{action "startService" target="controller"}}>

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/templates/wizard/step4.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step4.hbs b/ambari-web/app/templates/wizard/step4.hbs
index cda6d39..b21d360 100644
--- a/ambari-web/app/templates/wizard/step4.hbs
+++ b/ambari-web/app/templates/wizard/step4.hbs
@@ -37,16 +37,16 @@
     </tr>
     </thead>
     <tbody>
-      {{#each controller}}
-        {{#unless isHidden}}
+    {{#each controller}}
+      {{#unless isHiddenOnSelectServicePage}}
         <tr {{bindAttr class="isSelected:success:"}}>
-          <td><label class="checkbox">{{view Ember.Checkbox disabledBinding="isDisabled" checkedBinding="isSelected"}}{{displayName}}</label>
+          <td><label class="checkbox">{{view Ember.Checkbox disabledBinding="isInstalled" checkedBinding="isSelected"}}{{displayNameOnSelectServicePage}}</label>
           </td>
-          <td>{{version}}</td>
-          <td>{{{description}}}</td>
+          <td>{{serviceVersion}}</td>
+          <td>{{{comments}}}</td>
         </tr>
-        {{/unless}}
-      {{/each}}
+      {{/unless}}
+    {{/each}}
     </tbody>
   </table>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/templates/wizard/step5.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step5.hbs b/ambari-web/app/templates/wizard/step5.hbs
index 4994557..137e181 100644
--- a/ambari-web/app/templates/wizard/step5.hbs
+++ b/ambari-web/app/templates/wizard/step5.hbs
@@ -19,9 +19,8 @@
 <h2>{{title}}</h2>
 <div class="alert alert-info">
   {{t installer.step5.body}}
-  {{#if hasHiveServer}}
-    <br>
-    {{t installer.step5.body.hive}}
+  {{#if view.coHostedComponentText}}
+    {{{view.coHostedComponentText}}}
   {{/if}}
 </div>
 {{#if controller.isLoaded}}
@@ -47,38 +46,34 @@
                   <div class="span4">
                     <div class="control-group">
                       <label class="pts pull-right">
-                        {{#if controller.isReassignHive}}
-                          {{t installer.step5.hiveGroup}}
-                        {{else}}
-                          {{display_name}}:
-                        {{/if}}
+                        {{display_name}}:
                       </label>
                     </div>
                   </div>
                   <div class="span8">
-                    {{#if isHiveCoHost}}
+                    {{#if isServiceCoHost}}
                       <div class="hostName">
                         {{selectedHost}}<i class="icon-asterisks">&#10037;</i>
                       </div>
                     {{else}}
-                    <div class="control-group">
-                      {{#if view.shouldUseInputs}}
-                        {{view App.InputHostView
-                        componentBinding="this"
-                        disabledBinding="isInstalled" }}
-                      {{else}}
-                        {{view App.SelectHostView
-                        componentBinding="this"
-                        disabledBinding="isInstalled"
-                        optionValuePath="content.host_name"
-                        optionLabelPath="content.host_info" }}
-                      {{/if}}
-                      {{#if showAddControl}}
-                        {{view App.AddControlView componentNameBinding="component_name"}}
-                      {{/if}}
-                      {{#if showRemoveControl}}
-                        {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
-                      {{/if}}
+                      <div class="control-group">
+                        {{#if view.shouldUseInputs}}
+                          {{view App.InputHostView
+                          componentBinding="this"
+                          disabledBinding="isInstalled" }}
+                        {{else}}
+                          {{view App.SelectHostView
+                          componentBinding="this"
+                          disabledBinding="isInstalled"
+                          optionValuePath="content.host_name"
+                          optionLabelPath="content.host_info" }}
+                        {{/if}}
+                        {{#if showAddControl}}
+                          {{view App.AddControlView componentNameBinding="component_name"}}
+                        {{/if}}
+                        {{#if showRemoveControl}}
+                          {{view App.RemoveControlView componentNameBinding="component_name" serviceComponentIdBinding="serviceComponentId"}}
+                        {{/if}}
                       </div>
                     {{/if}}
                   </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/templates/wizard/step6.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step6.hbs b/ambari-web/app/templates/wizard/step6.hbs
index 33911cd..b27f721 100644
--- a/ambari-web/app/templates/wizard/step6.hbs
+++ b/ambari-web/app/templates/wizard/step6.hbs
@@ -18,6 +18,7 @@
 
 <div id="step6">
   <h2>{{view.title}}</h2>
+
   <div class="alert alert-info">{{{view.label}}}</div>
   {{#if errorMessage}}
     <div class="alert alert-error">{{errorMessage}}</div>
@@ -26,39 +27,41 @@
   <div class="pre-scrollable">
     <table class="table table-striped" id="component_assign_table">
       <thead>
-        <tr>
-          <th>{{t common.host}}</th>
-          {{#each header in controller.headers}}
+      <tr>
+        <th>{{t common.host}}</th>
+        {{#each header in controller.headers}}
 
-            <th>
-              <a href="#" {{bindAttr class="header.allChecked:selected:deselected"}}
-                {{action "selectAllNodes" header target="controller"}}>{{t all}}</a>&nbsp;|&nbsp;<a href="#" {{bindAttr class="header.noChecked:selected:deselected"}}
-                {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
-            </th>
+          <th>
+            <a href="#" {{bindAttr class="header.allChecked:selected:deselected header.isDisabled:remove-link"}}
+              {{action "selectAllNodes" header target="controller"}}>{{t all}}</a> &nbsp;|&nbsp; <a
+                  href="#" {{bindAttr class="header.noChecked:selected:deselected header.isDisabled:remove-link"}}
+            {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
+          </th>
 
-          {{/each}}
-        </tr>
+        {{/each}}
+      </tr>
       </thead>
       <tbody>
-        {{#if view.pageContent}}
-          {{#each host in view.pageContent}}
-            <tr>
-              {{#view App.WizardStep6HostView hostBinding="host" }}
-                <span class="trim_hostname">{{host.hostName}}</span>
-                {{#if host.hasMaster}}
-                  <i class="icon-asterisks">&#10037;</i>
-                {{/if}}
-              {{/view}}
-              {{#each checkbox in host.checkboxes}}
-                <td>
-                  <label class="checkbox">
-                      <input {{bindAttr checked = "checkbox.checked" disabled="checkbox.isInstalled"}} {{action "checkboxClick" checkbox target="view" }} type="checkbox"/>{{checkbox.title}}
-                  </label>
-                </td>
-              {{/each}}
-            </tr>
-          {{/each}}
-        {{/if}}
+      {{#if view.pageContent}}
+        {{#each host in view.pageContent}}
+          <tr>
+            {{#view App.WizardStep6HostView hostBinding="host" }}
+              <span class="trim_hostname">{{host.hostName}}</span>
+              {{#if host.hasMaster}}
+                <i class=icon-asterisks>&#10037;</i>
+              {{/if}}
+            {{/view}}
+            {{#each checkbox in host.checkboxes}}
+              <td>
+                <label class="checkbox">
+                  <input {{bindAttr checked = "checkbox.checked" disabled="checkbox.isInstalled"}} {{action "checkboxClick" checkbox target="view" }}
+                          type="checkbox"/>{{checkbox.title}}
+                </label>
+              </td>
+            {{/each}}
+          </tr>
+        {{/each}}
+      {{/if}}
       </tbody>
     </table>
   </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/templates/wizard/step8.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step8.hbs b/ambari-web/app/templates/wizard/step8.hbs
index 2352736..71915f8 100644
--- a/ambari-web/app/templates/wizard/step8.hbs
+++ b/ambari-web/app/templates/wizard/step8.hbs
@@ -53,7 +53,7 @@
 
     <div>
       {{#if controller.services.length}}
-        <p><b>{{t menu.item.services}}</b></p>
+        <p><b>{{t menu.item.services}}:</b></p>
         <ul>
           {{#each controller.services}}
             <li>

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 3396ac0..9581283 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -954,7 +954,7 @@ var urls = {
     }
   },
   'wizard.service_components': {
-    'real': '{stackUrl}/services?fields=StackServices/comments,StackServices/service_version,serviceComponents/*',
+    'real': '{stackUrl}/services?fields=StackServices/*,serviceComponents/*',
     'mock': '/data/stacks/HDP-2.1/service_components.json',
     'format': function(data) {
       return {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/utils/component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/component.js b/ambari-web/app/utils/component.js
deleted file mode 100644
index fd2ef1b..0000000
--- a/ambari-web/app/utils/component.js
+++ /dev/null
@@ -1,68 +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.
- */
-
-/**
- * Here will be stored slave functions related to components
- * @type {Object}
- */
-
-var App = require('app');
-module.exports = {
-
-  /**
-   * This needs to be done because mapper functions like App.stackServiceComponentMapper.map(data) does not override
-   * but unions the instances. So on re-navigation if the stack is switched and this function is not called then union of
-   * StackServiceComponent of both the stacks will be mapped to the model.
-   */
-  clearStackModel: function() {
-    if (App.StackServiceComponent.find().get('content').length) {
-      App.StackServiceComponent.find().set('content', []);
-    }
-  },
-
-  /**
-   * Format and load info about components to StackServiceComponent model.
-   *
-   * @method loadStackServiceComponentModel
-   * @param data {object} response from server
-   * @return {object} formatted info about components
-   */
-  loadStackServiceComponentModel: function(data) {
-    this.clearStackModel();
-    var serviceComponents = {items: []};
-    data.items.forEach(function(item){
-      item.serviceComponents.forEach(function(_serviceComponent, indx){
-        var stackServiceComponents =  _serviceComponent.StackServiceComponents;
-        var serviceComponent = {
-          component_name: stackServiceComponents.component_name,
-          service_name: stackServiceComponents.service_name,
-          component_category: stackServiceComponents.component_category,
-          is_master: stackServiceComponents.is_master,
-          is_client: stackServiceComponents.is_client,
-          stack_name: stackServiceComponents.stack_name,
-          stack_version: stackServiceComponents.stack_version,
-          id: indx
-        };
-        serviceComponents.items.pushObject(serviceComponent);
-      }, this);
-    }, this);
-    App.stackServiceComponentMapper.map(serviceComponents);
-    App.handleStackDependedComponents();
-    return serviceComponents;
-  }
-};

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 87dd0da..700da2f 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -40,7 +40,7 @@ App.config = Em.Object.create({
     "&quot;": '"',
     "&apos;": "'"
   },
-  
+
   CONFIG_GROUP_NAME_MAX_LENGTH: 18,
 
   /**
@@ -51,8 +51,8 @@ App.config = Em.Object.create({
   /**
    * Since values end up in XML files (core-sit.xml, etc.), certain
    * XML sensitive characters should be escaped. If not we will have
-   * an invalid XML document, and services will fail to start. 
-   * 
+   * an invalid XML document, and services will fail to start.
+   *
    * Special characters in XML are defined at
    * http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
    *
@@ -61,7 +61,7 @@ App.config = Em.Object.create({
    * @param toXml {Boolean}
    * @return {String}
    */
-  escapeXMLCharacters: function(value, toXML) {
+  escapeXMLCharacters: function (value, toXML) {
     var self = this;
     // To prevent double/triple replacing '&gt;' to '&amp;gt;' to '&amp;amp;gt;', we need
     // to first unescape all XML chars, and then escape them again.
@@ -77,42 +77,87 @@ App.config = Em.Object.create({
     }
   },
 
-  preDefinedServiceConfigs: function () {
+  preDefinedGlobalProperties: [],
+
+  setPreDefinedGlobalProperties: function () {
+    var globalProperties = [];
+    if (App.get('isHadoop2Stack')) {
+      globalProperties = require('data/HDP2/global_properties').configProperties;
+    } else {
+      globalProperties = require('data/global_properties').configProperties;
+    }
+    var preDefinedGlobalProperties = globalProperties;
+    var categories = [];
+    var nonServicePages = require('data/service_configs');
+    var services = App.StackService.find().filterProperty('id');
+
+    // Only services that have configTypes associated with it should display service config page
+    // Also Remove HCatalog from this list. HCatalog has global and hive-site related to it but none of them should be exposed under HCatalog Service
+    // HCatalog should be eventually made a part of Hive Service. See AMBARI-6302 description for further details
+    var servicesWithConfigTypes = services.filter(function (service) {
+      var configtypes = service.get('configTypes');
+      return configtypes && !!configtypes.length && service.get('serviceName') != 'HCATALOG';
+    }, this);
+    var serviceTabs = servicesWithConfigTypes.concat(nonServicePages);
+    serviceTabs.forEach(function (stackService) {
+      categories.pushObjects(stackService.get('configCategories'));
+    });
+    var categoryNames = categories.mapProperty('name').uniq();
+    if (!!categoryNames.length) {
+      preDefinedGlobalProperties = globalProperties.filter(function (_globalProperty) {
+        return !_globalProperty.category || (serviceTabs.someProperty('serviceName', _globalProperty.serviceName) &&
+          categoryNames.contains(_globalProperty.category));
+      });
+    }
+    this.set('preDefinedGlobalProperties', preDefinedGlobalProperties);
+  },
+
+  preDefinedServiceConfigs: [],
+
+  setPreDefinedServiceConfigs: function () {
     var configs = this.get('preDefinedGlobalProperties');
     var services = [];
-    $.extend(true, [], require('data/service_configs')).forEach(function (service) {
-      service.configs = configs.filterProperty('serviceName', service.serviceName);
+    var nonServiceTab = require('data/service_configs');
+    var stackServices = App.StackService.find().filterProperty('id');
+    // Only include services that has configTypes related to them for service configuration page
+    // Also Remove HCatalog from this list. HCatalog has global and hive-site related to it but none of them should be exposed under HCatalog Service
+    // HCatalog should be eventually made a part of Hive Service. See AMBARI-6302 description for further details
+    var servicesWithConfigTypes = stackServices.filter(function (service) {
+      var configtypes = service.get('configTypes');
+      return configtypes && !!configtypes.length && service.get('serviceName') != 'HCATALOG';
+    }, this);
+
+    var allTabs = servicesWithConfigTypes.concat(nonServiceTab);
+    allTabs.forEach(function (service) {
+      var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
+      serviceConfigs = serviceConfigs.filter(function (_globalProperty) {
+        !_globalProperty.category || service.get('configCategories').someProperty('name', _globalProperty.category);
+      });
+      service.set('configs', serviceConfigs);
       services.push(service);
     });
-    return services;
-  }.property('preDefinedGlobalProperties'),
+    this.set('preDefinedServiceConfigs', services);
+  },
 
   configMapping: function () {
     if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/config_mapping'));
-    }
-    return $.extend(true, [], require('data/config_mapping'));
-  }.property('App.isHadoop2Stack'),
-
-  preDefinedGlobalProperties: function () {
-    if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/global_properties').configProperties);
+      return require('data/HDP2/config_mapping');
     }
-    return $.extend(true, [], require('data/global_properties').configProperties);
+    return require('data/config_mapping');
   }.property('App.isHadoop2Stack'),
 
   preDefinedSiteProperties: function () {
     if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/site_properties').configProperties);
+      return require('data/HDP2/site_properties').configProperties;
     }
-    return $.extend(true, [], require('data/site_properties').configProperties);
+    return require('data/site_properties').configProperties;
   }.property('App.isHadoop2Stack'),
 
   preDefinedCustomConfigs: function () {
     if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/custom_configs'));
+      return require('data/HDP2/custom_configs');
     }
-    return $.extend(true, [], require('data/custom_configs'));
+    return require('data/custom_configs');
   }.property('App.isHadoop2Stack'),
 
   //categories which contain custom configs
@@ -165,7 +210,7 @@ App.config = Em.Object.create({
   /**
    * Array of global "service/desired_tag/actual_tag" strings which
    * indicate different configurations. We cache these so that
-   * we dont have to recalculate if two tags are difference.
+   * we don't have to recalculate if two tags are difference.
    */
   differentGlobalTagsCache: [],
 
@@ -173,12 +218,13 @@ App.config = Em.Object.create({
     var category = null;
     var serviceConfigMetaData = this.get('preDefinedServiceConfigs').findProperty('serviceName', config.serviceName);
     if (serviceConfigMetaData) {
-      serviceConfigMetaData.configCategories.forEach(function (_category) {
+      var configCategories = serviceConfigMetaData.get('configCategories');
+      configCategories.forEach(function (_category) {
         if (_category.siteFileNames && Array.isArray(_category.siteFileNames) && _category.siteFileNames.contains(config.filename)) {
           category = _category;
         }
       });
-      category = (category == null) ? serviceConfigMetaData.configCategories.findProperty('siteFileName', config.filename) : category;
+      category = (category == null) ? configCategories.findProperty('siteFileName', config.filename) : category;
     }
     return category;
   },
@@ -198,7 +244,7 @@ App.config = Em.Object.create({
   },
   /**
    * calculate config properties:
-   * category, filename, isUserProperty, description   
+   * category, filename, isUserProperty, description
    * @param config
    * @param isAdvanced
    * @param advancedConfigs
@@ -212,7 +258,7 @@ App.config = Em.Object.create({
       }
     } else {
       var advancedProperty = null;
-      if( isAdvanced ){
+      if (isAdvanced) {
         advancedProperty = advancedConfigs.findProperty('name', config.name);
       }
 
@@ -263,22 +309,22 @@ App.config = Em.Object.create({
 
       properties = (properties.length) ? properties.objectAt(0).properties : {};
       for (var index in properties) {
-        var configsPropertyDef =  null;
+        var configsPropertyDef = null;
         var preDefinedConfig = [];
         if (_tag.siteName === 'global') {
-        // Unlike other site where one site maps to ones service, global site contains configurations for multiple services
-        // So Global Configuration should not be filtered out with serviceName.
+          // Unlike other site where one site maps to ones service, global site contains configurations for multiple services
+          // So Global Configuration should not be filtered out with serviceName.
           preDefinedConfig = preDefinedConfigs.filterProperty('name', index);
-          preDefinedConfig.forEach(function(_preDefinedConfig){
+          preDefinedConfig.forEach(function (_preDefinedConfig) {
             var isServiceInstalled = selectedServiceNames.contains(_preDefinedConfig.serviceName);
-              if ( isServiceInstalled || _preDefinedConfig.serviceName === 'MISC') {
-                configsPropertyDef = _preDefinedConfig;
-              }
-          },this);
+            if (isServiceInstalled || _preDefinedConfig.serviceName === 'MISC') {
+              configsPropertyDef = _preDefinedConfig;
+            }
+          }, this);
         } else {
-          configsPropertyDef = preDefinedConfigs.filterProperty('name',index).findProperty('filename',filename);
+          configsPropertyDef = preDefinedConfigs.filterProperty('name', index).findProperty('filename', filename);
           if (!configsPropertyDef) {
-            configsPropertyDef = preDefinedConfigs.filterProperty('name',index).findProperty('serviceName', serviceName);
+            configsPropertyDef = preDefinedConfigs.filterProperty('name', index).findProperty('serviceName', serviceName);
           }
         }
 
@@ -298,7 +344,7 @@ App.config = Em.Object.create({
         if (configsPropertyDef) {
           this.setServiceConfigUiAttributes(serviceConfigObj, configsPropertyDef);
         }
-        
+
         if (_tag.siteName === 'global') {
           if (configsPropertyDef) {
             if (configsPropertyDef.isRequiredByAgent === false) {
@@ -321,22 +367,22 @@ App.config = Em.Object.create({
 
           serviceConfigObj.displayName = configsPropertyDef ? configsPropertyDef.displayName : index;
           this.calculateConfigProperties(serviceConfigObj, isAdvanced, advancedConfigs);
-          
-          if(serviceConfigObj.get('displayType') == 'directories'
+
+          if (serviceConfigObj.get('displayType') == 'directories'
             && (serviceConfigObj.get('category') == 'DataNode'
             || serviceConfigObj.get('category') == 'NameNode')) {
             var dirs = serviceConfigObj.get('value').split(',').sort();
             serviceConfigObj.set('value', dirs.join(','));
             serviceConfigObj.set('defaultValue', dirs.join(','));
           }
-          
-          if(serviceConfigObj.get('displayType') == 'directory'
+
+          if (serviceConfigObj.get('displayType') == 'directory'
             && serviceConfigObj.get('category') == 'SNameNode') {
             var dirs = serviceConfigObj.get('value').split(',').sort();
             serviceConfigObj.set('value', dirs[0]);
             serviceConfigObj.set('defaultValue', dirs[0]);
           }
-          
+
           if (serviceConfigObj.get('displayType') == 'masterHosts') {
             if (typeof(serviceConfigObj.get('value')) == 'string') {
               var value = serviceConfigObj.get('value').replace(/\[|]|'|&apos;/g, "").split(',');
@@ -403,8 +449,8 @@ App.config = Em.Object.create({
       if (_site.length == 1) {
         siteStart.push(_site[0]);
         siteConfigs = siteConfigs.without(_site[0]);
-      } else if (_site.length >1) {
-        _site.forEach(function(site){
+      } else if (_site.length > 1) {
+        _site.forEach(function (site) {
           siteStart.push(site);
           siteConfigs = siteConfigs.without(site);
         }, this);
@@ -427,7 +473,7 @@ App.config = Em.Object.create({
    */
   mergePreDefinedWithStored: function (storedConfigs, advancedConfigs, selectedServiceNames) {
     var mergedConfigs = [];
-    var preDefinedConfigs = $.extend(true, [], this.get('preDefinedGlobalProperties').concat(this.get('preDefinedSiteProperties')));
+    var preDefinedConfigs = this.get('preDefinedGlobalProperties').concat(this.get('preDefinedSiteProperties'));
 
     storedConfigs = (storedConfigs) ? storedConfigs : [];
 
@@ -449,7 +495,7 @@ App.config = Em.Object.create({
       if (storedCfgs.length <= 1 && preDefinedCfgs.length <= 1) {
         var stored = storedCfgs[0];
         var preDefined = preDefinedCfgs[0];
-        
+
         if (preDefined && stored) {
           configData = preDefined;
           configData.value = stored.value;
@@ -462,25 +508,23 @@ App.config = Em.Object.create({
           configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
           configData.showLabel = stored.showLabel !== false;
         }
-        else
-          if (!preDefined && stored) {
-            configData = this.addUserProperty(stored, isAdvanced, advancedConfigs);
+        else if (!preDefined && stored) {
+          configData = this.addUserProperty(stored, isAdvanced, advancedConfigs);
+        }
+        else if (preDefined && !stored) {
+          configData = preDefined;
+          configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
+          if (isAdvanced) {
+            var advanced = advancedConfigs.findProperty('name', configData.name);
+            this.setPropertyFromStack(configData, advanced);
           }
-          else
-            if (preDefined && !stored) {
-              configData = preDefined;
-              configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
-              if (isAdvanced) {
-                var advanced = advancedConfigs.findProperty('name', configData.name);
-                this.setPropertyFromStack(configData,advanced);
-              }
-            }
-        
+        }
+
         if (configData.displayType === 'checkbox') {
           configData.value = configData.value === 'true'; // convert {String} value to {Boolean}
           configData.defaultValue = configData.value;
         }
-      
+
         mergedConfigs.push(configData);
       } else {
         preDefinedCfgs.forEach(function (cfg) {
@@ -494,9 +538,9 @@ App.config = Em.Object.create({
             configData.filename = storedCfg.filename;
             configData.description = storedCfg.description;
             configData.description = storedCfg.showLabel !== false;
-          } else if (isAdvanced){
-              advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
-              this.setPropertyFromStack(configData,advanced);
+          } else if (isAdvanced) {
+            advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
+            this.setPropertyFromStack(configData, advanced);
           }
           mergedConfigs.push(configData);
         }, this);
@@ -510,7 +554,7 @@ App.config = Em.Object.create({
    * @param configData {Object} Configs that will be binded to the view on step-7 of installer wizard
    * @param advanced {Object} Config property loaded from Server side stack definition
    */
-  setPropertyFromStack: function(configData,advanced) {
+  setPropertyFromStack: function (configData, advanced) {
 
     // Password fields should be made blank by default in installer wizard
     // irrespective of whatever value is sent from stack definition.
@@ -601,17 +645,18 @@ App.config = Em.Object.create({
     var services = [];
 
     this.get('preDefinedServiceConfigs').forEach(function (serviceConfig) {
-      if (allSelectedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
-        console.log('pushing ' + serviceConfig.serviceName, serviceConfig);
-        if (!installedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
-          serviceConfig.showConfig = true;
+      var serviceName = serviceConfig.get('serviceName');
+      if (allSelectedServiceNames.contains(serviceName) || serviceName === 'MISC') {
+        console.log('pushing ' + serviceName, serviceConfig);
+        if (!installedServiceNames.contains(serviceName) || serviceName === 'MISC') {
+          serviceConfig.set('showConfig', true);
         }
         services.push(serviceConfig);
       }
     });
     services.forEach(function (service) {
       var configsByService = [];
-      var serviceConfigs = configs.filterProperty('serviceName', service.serviceName);
+      var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
       serviceConfigs.forEach(function (_config) {
         _config.isOverridable = (_config.isOverridable === undefined) ? true : _config.isOverridable;
         var serviceConfigProperty = App.ServiceConfigProperty.create(_config);
@@ -623,13 +668,13 @@ App.config = Em.Object.create({
         serviceConfigProperty.validate();
         configsByService.pushObject(serviceConfigProperty);
       }, this);
-      var serviceConfig = this.createServiceConfig(service.serviceName);
-      serviceConfig.set('showConfig', service.showConfig);
+      var serviceConfig = this.createServiceConfig(service.get('serviceName'));
+      serviceConfig.set('showConfig', service.get('showConfig'));
 
       // Use calculated default values for some configs
       var recommendedDefaults = {};
-      if (!storedConfigs && service.defaultsProviders) {
-        service.defaultsProviders.forEach(function (defaultsProvider) {
+      if (!storedConfigs && service.get('defaultsProviders')) {
+        service.get('defaultsProviders').forEach(function (defaultsProvider) {
           var defaults = defaultsProvider.getDefaults(localDB);
           for (var name in defaults) {
             var config = configsByService.findProperty('name', name);
@@ -646,13 +691,13 @@ App.config = Em.Object.create({
           }
         });
       }
-      if (service.configsValidator) {
-        service.configsValidator.set('recommendedDefaults', recommendedDefaults);
-        var validators = service.configsValidator.get('configValidators');
+      if (service.get('configsValidator')) {
+        service.get('configsValidator').set('recommendedDefaults', recommendedDefaults);
+        var validators = service.get('configsValidator').get('configValidators');
         for (var validatorName in validators) {
           var c = configsByService.findProperty('name', validatorName);
           if (c) {
-            c.set('serviceValidator', service.configsValidator);
+            c.set('serviceValidator', service.get('configsValidator'));
           }
         }
       }
@@ -713,10 +758,9 @@ App.config = Em.Object.create({
   createServiceConfig: function (serviceName) {
     var preDefinedServiceConfig = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName);
     var serviceConfig = App.ServiceConfig.create({
-      filename: preDefinedServiceConfig.filename,
-      serviceName: preDefinedServiceConfig.serviceName,
-      displayName: preDefinedServiceConfig.displayName,
-      configCategories: preDefinedServiceConfig.configCategories,
+      serviceName: preDefinedServiceConfig.get('serviceName'),
+      displayName: preDefinedServiceConfig.get('displayName'),
+      configCategories: preDefinedServiceConfig.get('configCategories'),
       configs: [],
       configGroups: []
     });
@@ -801,9 +845,9 @@ App.config = Em.Object.create({
          * Properties from mapred-queue-acls.xml are ignored unless App.supports.capacitySchedulerUi is true
          * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
          * HDP stack version is 1.x and App.supports.capacitySchedulerUi is true.
-          */
+         */
         if ((fileName !== 'mapred-queue-acls.xml' || App.supports.capacitySchedulerUi) &&
-            (fileName !== 'capacity-scheduler.xml' || isHDP2 || App.supports.capacitySchedulerUi)) {
+          (fileName !== 'capacity-scheduler.xml' || isHDP2 || App.supports.capacitySchedulerUi)) {
           properties.push({
             serviceName: serviceName,
             name: item.property_name,
@@ -890,7 +934,7 @@ App.config = Em.Object.create({
             serviceConfig.overrides = [];
           }
           if (!serviceConfig.overrides) {
-           serviceConfig.set('overrides', []);
+            serviceConfig.set('overrides', []);
           }
           console.log("loadServiceConfigGroupOverridesSuccess(): [" + group + "] OVERRODE(" + serviceConfig.name + "): " + serviceConfig.value + " -> " + hostOverrideValue);
           serviceConfig.overrides.push({value: hostOverrideValue, group: group});
@@ -1126,7 +1170,7 @@ App.config = Em.Object.create({
       configCategories.removeObject(snCategory);
     }
   },
-  
+
   /**
    * Launches a dialog where an existing config-group can be selected, or a new
    * one can be created. This is different than the config-group management
@@ -1140,7 +1184,7 @@ App.config = Em.Object.create({
    *  is closed, cancelled or OK is pressed.
    */
 
-  saveGroupConfirmationPopup: function(groupName) {
+  saveGroupConfirmationPopup: function (groupName) {
     App.ModalPopup.show({
       header: Em.I18n.t('config.group.save.confirmation.header'),
       secondary: Em.I18n.t('config.group.save.confirmation.manage.button'),
@@ -1148,7 +1192,7 @@ App.config = Em.Object.create({
       bodyClass: Ember.View.extend({
         templateName: require('templates/common/configs/saveConfigGroup')
       }),
-      onSecondary: function() {
+      onSecondary: function () {
         App.router.get('mainServiceInfoConfigsController').manageConfigurationGroups();
         this.hide();
       }
@@ -1177,7 +1221,7 @@ App.config = Em.Object.create({
     });
   },
 
-  launchConfigGroupSelectionCreationDialog : function(serviceId, configGroups, configProperty, callback, isInstaller) {
+  launchConfigGroupSelectionCreationDialog: function (serviceId, configGroups, configProperty, callback, isInstaller) {
     var self = this;
     var availableConfigGroups = configGroups.slice();
     // delete Config Groups, that already have selected property overridden
@@ -1193,7 +1237,7 @@ App.config = Em.Object.create({
     }, this);
     availableConfigGroups = result;
     var selectedConfigGroup = availableConfigGroups && availableConfigGroups.length > 0 ?
-        availableConfigGroups[0] : null;
+      availableConfigGroups[0] : null;
     var serviceName = App.Service.DisplayNames[serviceId];
     App.ModalPopup.show({
       classNames: [ 'sixty-percent-width-modal' ],
@@ -1206,10 +1250,10 @@ App.config = Em.Object.create({
       warningMessage: '&nbsp;',
       isWarning: false,
       optionSelectConfigGroup: true,
-      optionCreateConfigGroup: function(){
+      optionCreateConfigGroup: function () {
         return !this.get('optionSelectConfigGroup');
       }.property('optionSelectConfigGroup'),
-      hasExistedGroups: function() {
+      hasExistedGroups: function () {
         return !!this.get('availableConfigGroups').length;
       }.property('availableConfigGroups'),
       availableConfigGroups: availableConfigGroups,
@@ -1401,7 +1445,7 @@ App.config = Em.Object.create({
    * PUTs the new configuration-group on the server.
    * Changes possible here are the name, description and
    * host memberships of the configuration-group.
-   * 
+   *
    * @param {App.ConfigGroup} configGroup Configuration group to update
    * @param {Function} successCallback
    * @param {Function} errorCallback
@@ -1414,20 +1458,20 @@ App.config = Em.Object.create({
         tag: configGroup.get('service.id'),
         hosts: [],
         desired_configs: []
-      }  
+      }
     };
-    configGroup.get('hosts').forEach(function(h){
+    configGroup.get('hosts').forEach(function (h) {
       putConfigGroup.ConfigGroup.hosts.push({
         host_name: h
       });
     });
-    configGroup.get('configSiteTags').forEach(function(cst){
+    configGroup.get('configSiteTags').forEach(function (cst) {
       putConfigGroup.ConfigGroup.desired_configs.push({
         type: cst.get('site'),
         tag: cst.get('tag')
       });
     });
-    
+
     var sendData = {
       name: 'config_groups.update',
       data: {
@@ -1437,12 +1481,12 @@ App.config = Em.Object.create({
       success: 'successFunction',
       error: 'errorFunction',
       successFunction: function () {
-        if(successCallback) {
+        if (successCallback) {
           successCallback();
         }
       },
       errorFunction: function (xhr, text, errorThrown) {
-        if(errorCallback) {
+        if (errorCallback) {
           errorCallback(xhr, text, errorThrown);
         }
       }
@@ -1467,12 +1511,12 @@ App.config = Em.Object.create({
       success: 'successFunction',
       error: 'errorFunction',
       successFunction: function () {
-        if(successCallback) {
+        if (successCallback) {
           successCallback();
         }
       },
       errorFunction: function (xhr, text, errorThrown) {
-        if(errorCallback) {
+        if (errorCallback) {
           errorCallback(xhr, text, errorThrown);
         }
       }
@@ -1483,7 +1527,7 @@ App.config = Em.Object.create({
 
   /**
    * Gets all the configuration-groups for the given service.
-   * 
+   *
    * @param serviceId
    *          (string) ID of the service. Ex: HDFS
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index 1072f08..5bff313 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -316,79 +316,30 @@ App.format = {
    * @property components
    */
   components: {
-    'APP_TIMELINE_SERVER': 'App Timeline Server',
-    'DATANODE': 'DataNode',
+    'API': 'API',
     'DECOMMISSION_DATANODE': 'Update Exclude File',
-    'DRPC_SERVER': 'DRPC Server',
-    'FALCON': 'Falcon',
-    'FALCON_CLIENT': 'Falcon Client',
-    'FALCON_SERVER': 'Falcon Server',
-    'FALCON_SERVICE_CHECK': 'Falcon Service Check',
+    'DRPC': 'DRPC',
     'FLUME_HANDLER': 'Flume Agent',
-    'FLUME_SERVICE_CHECK': 'Flume Service Check',
-    'GANGLIA_MONITOR': 'Ganglia Monitor',
-    'GANGLIA_SERVER': 'Ganglia Server',
-    'GLUSTERFS_CLIENT': 'GLUSTERFS Client',
-    'GLUSTERFS_SERVICE_CHECK': 'GLUSTERFS Service Check',
-    'GMETAD_SERVICE_CHECK': 'Gmetad Service Check',
-    'GMOND_SERVICE_CHECK': 'Gmond Service Check',
-    'HADOOP_CLIENT': 'Hadoop Client',
-    'HBASE_CLIENT': 'HBase Client',
-    'HBASE_MASTER': 'HBase Master',
+    'GLUSTERFS': 'GLUSTERFS',
+    'HBASE': 'HBase',
     'HBASE_REGIONSERVER': 'RegionServer',
-    'HBASE_SERVICE_CHECK': 'HBase Service Check',
     'HCAT': 'HCat',
-    'HCAT_SERVICE_CHECK': 'HCat Service Check',
-    'HDFS_CLIENT': 'HDFS Client',
-    'HDFS_SERVICE_CHECK': 'HDFS Service Check',
+    'HDFS': 'HDFS',
     'HISTORYSERVER': 'History Server',
-    'HIVE_CLIENT': 'Hive Client',
-    'HIVE_METASTORE': 'Hive Metastore',
     'HIVE_SERVER': 'HiveServer2',
-    'HIVE_SERVICE_CHECK': 'Hive Service Check',
-    'HUE_SERVER': 'Hue Server',
-    'JAVA_JCE': 'Java JCE',
-    'JOBTRACKER': 'JobTracker',
-    'JOBTRACKER_SERVICE_CHECK': 'JobTracker Service Check',
-    'JOURNALNODE': 'JournalNode',
-    'KERBEROS_ADMIN_CLIENT': 'Kerberos Admin Client',
-    'KERBEROS_CLIENT': 'Kerberos Client',
-    'KERBEROS_SERVER': 'Kerberos Server',
-    'MAPREDUCE2_CLIENT': 'MapReduce2 Client',
-    'MAPREDUCE2_SERVICE_CHECK': 'MapReduce2 Service Check',
-    'MAPREDUCE_CLIENT': 'MapReduce Client',
-    'MAPREDUCE_SERVICE_CHECK': 'MapReduce Service Check',
-    'MYSQL_SERVER': 'MySQL Server',
-    'NAGIOS_SERVER': 'Nagios Server',
-    'NAMENODE': 'NameNode',
-    'NAMENODE_SERVICE_CHECK': 'NameNode Service Check',
-    'NIMBUS': 'Nimbus',
-    'NODEMANAGER': 'NodeManager',
-    'OOZIE_CLIENT': 'Oozie Client',
-    'OOZIE_SERVER': 'Oozie Server',
-    'OOZIE_SERVICE_CHECK': 'Oozie Service Check',
-    'PIG': 'Pig',
-    'PIG_SERVICE_CHECK': 'Pig Service Check',
-    'RESOURCEMANAGER': 'ResourceManager',
+    'JCE': 'JCE',
+    'MAPREDUCE': 'MapReduce',
+    'MAPREDUCE2': 'MapReduce2',
+    'MYSQL': 'MySQL',
+    'REST': 'REST',
     'SECONDARY_NAMENODE': 'SNameNode',
-    'SQOOP': 'Sqoop',
-    'SQOOP_SERVICE_CHECK': 'Sqoop Service Check',
     'STORM_REST_API': 'Storm REST API Server',
-    'STORM_SERVICE_CHECK': 'Storm Service Check',
-    'STORM_UI_SERVER': 'Storm UI Server',
-    'SUPERVISOR': 'Supervisor',
-    'TASKTRACKER': 'TaskTracker',
-    'TEZ_CLIENT': 'Tez Client',
-    'WEBHCAT_SERVER': 'WebHCat Server',
-    'WEBHCAT_SERVICE_CHECK': 'WebHCat Service Check',
-    'YARN_CLIENT': 'YARN Client',
-    'YARN_SERVICE_CHECK': 'YARN Service Check',
+    'WEBHCAT': 'WebHCat',
+    'YARN': 'YARN',
+    'UI': 'UI',
     'ZKFC': 'ZKFailoverController',
-    'ZOOKEEPER_CLIENT': 'ZooKeeper Client',
-    'ZOOKEEPER_QUORUM_SERVICE_CHECK': 'ZK Quorum Service Check',
-    'ZOOKEEPER_SERVER': 'ZooKeeper Server',
-    'ZOOKEEPER_SERVICE_CHECK': 'ZooKeeper Service Check',
-    'CLIENT': 'Client'
+    'ZOOKEEPER': 'ZooKeeper',
+    'ZOOKEEPER_QUORUM_SERVICE_CHECK': 'ZK Quorum Service Check'
   },
 
   /**
@@ -419,7 +370,32 @@ App.format = {
    * return {string}
    */
   role:function (role) {
-    return this.components[role] ? this.components[role] : '';
+    return this.normalizeName(role);
+  },
+
+  /**
+   * Try to format non predefined names to readable format.
+   *
+   * @method normalizeName
+   * @param name {String} - name to format
+   * @return {String}
+   */
+  normalizeName: function(name) {
+    if (!name || typeof name != 'string') return '';
+    if (this.components[name]) return this.components[name];
+    name = name.toLowerCase();
+    var suffixNoSpaces = ['node','tracker','manager'];
+    var suffixRegExp = new RegExp('(\\w+)(' + suffixNoSpaces.join('|') + ')', 'gi');
+    if (/_/g.test(name)) {
+      name = name.split('_').map(function(singleName) {
+        return this.normalizeName(singleName.toUpperCase());
+      }, this).join(' ');
+    } else if(suffixRegExp.test(name)) {
+      suffixRegExp.lastIndex = 0;
+      var matches = suffixRegExp.exec(name);
+      name = matches[1].capitalize() + matches[2].capitalize();
+    };
+    return name.capitalize();
   },
 
   /**
@@ -448,17 +424,17 @@ App.format = {
       } else if (self.command[item]) {
         result = result + ' ' + self.command[item];
       } else {
-        result = result + ' ' + item;
+        result = result + ' ' + self.role(item);
       }
     });
-    if (result === ' nagios_update_ignore ACTIONEXECUTE') {
+    if (result === ' Nagios Update Ignore Actionexecute') {
        result = Em.I18n.t('common.maintenance.task');
     }
     return result;
   },
 
   /**
-   * Convert uppercase status name to downcase.
+   * Convert uppercase status name to lowercase.
    * <br>
    * <br>PENDING - Not queued yet for a host
    * <br>QUEUED - Queued for a host

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/utils/string_utils.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/string_utils.js b/ambari-web/app/utils/string_utils.js
index 0ce8340..b16852e 100644
--- a/ambari-web/app/utils/string_utils.js
+++ b/ambari-web/app/utils/string_utils.js
@@ -159,5 +159,41 @@ module.exports = {
     }
     var last_slash = path.lastIndexOf('/');
     return (last_slash!=0)?path.substr(0,last_slash):'/';
+  },
+
+  /**
+   * @method getFormattedStringFromArray Get formatted string of elements to display on the UI
+   * Example:
+   * var arr = [ambari, bigdata, hadoop]
+   * getFormattedStringFromArray(arr);  // ambari, bigdata and hadoop
+   * @param array {Array}  Array of elements
+   * @returns {String}
+   */
+  getFormattedStringFromArray: function (array) {
+    var label = '';
+    array.forEach(function (_arrElement) {
+      if (array.length === 1) {
+        label = _arrElement;
+      }
+      else {
+        if (_arrElement !== array[array.length - 1]) {           // [clients.length - 1]
+          label = label + ' ' + _arrElement;
+          if (_arrElement !== array[array.length - 2]) {
+            label = label + ',';
+          }
+        }
+        else {
+          label = label + ' ' + Em.I18n.t('and') + ' ' + _arrElement;
+        }
+      }
+    }, this);
+    return label.trim();
+  },
+
+  pluralize: function(count, singular, plural) {
+    if (count > 1) {
+      return plural;
+    }
+    return singular;
   }
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/common/configs/services_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/services_config.js b/ambari-web/app/views/common/configs/services_config.js
index 1c66e7d..ca07473 100644
--- a/ambari-web/app/views/common/configs/services_config.js
+++ b/ambari-web/app/views/common/configs/services_config.js
@@ -488,14 +488,13 @@ App.ServiceConfigsByCategoryView = Ember.View.extend({
     var serviceName = this.get('service.serviceName');
     var serviceConfigsMetaData = App.config.get('preDefinedServiceConfigs');
     var serviceConfigMetaData = serviceConfigsMetaData.findProperty('serviceName', serviceName);
-    var categoryMetaData = serviceConfigMetaData == null ? null : serviceConfigMetaData.configCategories.findProperty('name', category.get('name'));
+    var categoryMetaData = serviceConfigMetaData == null ? null : serviceConfigMetaData.get('configCategories').findProperty('name', category.get('name'));
     if (categoryMetaData != null) {
       serviceConfigObj.filename = categoryMetaData.siteFileName;
     }
 
     var self = this;
     App.ModalPopup.show({
-      // classNames: ['big-modal'],
       classNames: [ 'sixty-percent-width-modal'],
       header: "Add Property",
       primary: 'Add',

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host.js b/ambari-web/app/views/main/host.js
index e9c90fd..d267a2b 100644
--- a/ambari-web/app/views/main/host.js
+++ b/ambari-web/app/views/main/host.js
@@ -85,6 +85,11 @@ App.MainHostView = App.TableView.extend(App.TableServerProvider, {
   }.property('filteredCount'),
 
   /**
+   * Stub function
+   */
+  updatePaging: function () {},
+
+  /**
    * flag to toggle displaying selected hosts counter
    */
   showSelectedFilter: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/host/addHost/step4_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/addHost/step4_view.js b/ambari-web/app/views/main/host/addHost/step4_view.js
index 68bce18..29f4901 100644
--- a/ambari-web/app/views/main/host/addHost/step4_view.js
+++ b/ambari-web/app/views/main/host/addHost/step4_view.js
@@ -20,12 +20,5 @@
 var App = require('app');
 
 App.AddHostStep4View = Em.View.extend({
-
-  templateName: require('templates/main/host/addHost/step4'),
-
-
-  didInsertElement: function() {
-
-  }
-
+  templateName: require('templates/main/host/addHost/step4')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/host/configs_service_menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/configs_service_menu.js b/ambari-web/app/views/main/host/configs_service_menu.js
index 53d6a19..0f20a7d 100644
--- a/ambari-web/app/views/main/host/configs_service_menu.js
+++ b/ambari-web/app/views/main/host/configs_service_menu.js
@@ -28,8 +28,8 @@ App.MainHostServiceMenuView = Em.CollectionView.extend({
       hostComponents.forEach(function (hc) {
         var service = hc.get('service');
         if (service) {
-        var serviceName = service.get('serviceName');
-          if(!['PIG', 'SQOOP', 'HCATALOG', 'GANGLIA'].contains(serviceName)){
+          var serviceName = service.get('serviceName');
+          if(!App.get('services.noConfigTypes').concat('HCATALOG').contains(serviceName)){
             if (!services.findProperty('serviceName', serviceName)) {
               services.push(service);
             }
@@ -39,7 +39,8 @@ App.MainHostServiceMenuView = Em.CollectionView.extend({
         }
       });
     }
-    return misc.sortByOrder(App.Service.servicesSortOrder, services);
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    return misc.sortByOrder(stackServices, services);
   }.property('host'),
   
   host: function(){

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/views/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js
index 2cdce53..8f66509 100644
--- a/ambari-web/app/views/main/service/info/summary.js
+++ b/ambari-web/app/views/main/service/info/summary.js
@@ -64,7 +64,9 @@ App.MainServiceInfoSummaryView = Em.View.extend({
    */
   collapsedSections: null,
 
-  servicesHaveClients: ["GLUSTERFS", "OOZIE", "ZOOKEEPER", "HIVE", "MAPREDUCE2", "TEZ", "SQOOP", "PIG","FALCON"],
+  servicesHaveClients: function() {
+    return App.get('services.hasClient');
+  }.property('App.services.hasClient'),
 
   sumMasterComponentView : Em.View.extend({
     didInsertElement: function() {
@@ -382,7 +384,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({
    * Alerts panel not display for PIG, SQOOP and TEZ Service
    */
   isNoAlertsService: function () {
-    return !!this.get('service.serviceName') && ['PIG', 'SQOOP', 'TEZ'].contains(this.get('service.serviceName'));
+    return !!this.get('service.serviceName') && App.get('services.clientOnly').contains(this.get('service.serviceName'));
   }.property(''),
 
   gangliaUrl:function () {


[6/6] git commit: AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Posted by yu...@apache.org.
AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)


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

Branch: refs/heads/trunk
Commit: 00f8d5c5c41fc3b2590aec3b2cbbd485c53142d7
Parents: ed65cfd
Author: Yusaku Sako <yu...@hortonworks.com>
Authored: Tue Jul 8 21:28:12 2014 -0700
Committer: Yusaku Sako <yu...@hortonworks.com>
Committed: Tue Jul 8 21:29:58 2014 -0700

----------------------------------------------------------------------
 ambari-web/app/app.js                           | 170 +----
 .../controllers/global/cluster_controller.js    |   9 +-
 ambari-web/app/controllers/installer.js         |  63 +-
 .../app/controllers/main/admin/cluster.js       |  78 +-
 .../admin/highAvailability/step2_controller.js  |  25 +-
 .../admin/highAvailability/wizard_controller.js |  33 +-
 .../controllers/main/admin/misc_controller.js   |   2 +-
 .../app/controllers/main/host/add_controller.js |  51 +-
 ambari-web/app/controllers/main/service.js      |  42 +-
 .../controllers/main/service/add_controller.js  |  71 +-
 .../controllers/main/service/info/configs.js    |  29 +-
 ambari-web/app/controllers/main/service/item.js |  12 +-
 .../main/service/reassign/step2_controller.js   |   2 +-
 .../main/service/reassign_controller.js         |  33 +-
 ambari-web/app/controllers/wizard.js            | 121 ++-
 .../app/controllers/wizard/step4_controller.js  | 280 +++----
 .../app/controllers/wizard/step5_controller.js  | 278 +++----
 .../app/controllers/wizard/step6_controller.js  | 164 ++--
 .../app/controllers/wizard/step7_controller.js  |  83 +-
 .../app/controllers/wizard/step8_controller.js  | 154 ++--
 .../app/controllers/wizard/step9_controller.js  |  36 +-
 ambari-web/app/data/HDP2/global_properties.js   | 118 ++-
 ambari-web/app/data/HDP2/site_properties.js     | 138 ++--
 ambari-web/app/data/global_properties.js        |  99 ++-
 ambari-web/app/data/review_configs.js           | 368 ---------
 ambari-web/app/data/service_configs.js          | 279 +------
 ambari-web/app/data/services.js                 | 189 -----
 ambari-web/app/data/site_properties.js          |  46 +-
 ambari-web/app/mappers.js                       |   2 +-
 .../app/mappers/service_metrics_mapper.js       |   5 +-
 .../mappers/stack_service_component_mapper.js   |  44 --
 ambari-web/app/mappers/stack_service_mapper.js  |  90 +++
 ambari-web/app/messages.js                      |  22 +-
 ambari-web/app/mixins.js                        |   3 +-
 ambari-web/app/mixins/models/service_mixin.js   |  30 +
 ambari-web/app/models.js                        |   1 +
 ambari-web/app/models/host_component.js         |   6 +-
 ambari-web/app/models/service.js                |  57 +-
 ambari-web/app/models/stack_service.js          | 382 ++++++++++
 .../app/models/stack_service_component.js       | 146 +++-
 ambari-web/app/routes/add_host_routes.js        |   2 -
 ambari-web/app/routes/add_service_routes.js     |   3 +-
 ambari-web/app/routes/installer.js              |   5 +-
 ambari-web/app/routes/main.js                   |   2 +-
 .../main/admin/highAvailability/step2.hbs       |  75 +-
 ambari-web/app/templates/main/service/item.hbs  |   2 +-
 ambari-web/app/templates/wizard/step4.hbs       |  14 +-
 ambari-web/app/templates/wizard/step5.hbs       |  49 +-
 ambari-web/app/templates/wizard/step6.hbs       |  61 +-
 ambari-web/app/templates/wizard/step8.hbs       |   2 +-
 ambari-web/app/utils/ajax/ajax.js               |   2 +-
 ambari-web/app/utils/component.js               |  68 --
 ambari-web/app/utils/config.js                  | 248 +++---
 ambari-web/app/utils/helper.js                  | 112 ++-
 ambari-web/app/utils/string_utils.js            |  36 +
 .../app/views/common/configs/services_config.js |   3 +-
 ambari-web/app/views/main/host.js               |   5 +
 .../app/views/main/host/addHost/step4_view.js   |   9 +-
 .../app/views/main/host/configs_service_menu.js |   7 +-
 .../app/views/main/service/info/summary.js      |   6 +-
 ambari-web/app/views/main/service/item.js       |  10 +-
 ambari-web/app/views/main/service/menu.js       |  22 +-
 ambari-web/app/views/main/service/service.js    |   5 +-
 ambari-web/app/views/wizard/step5_view.js       |  27 +-
 ambari-web/app/views/wizard/step6_view.js       |  13 +-
 ambari-web/test/app_test.js                     |  16 +-
 .../main/host/add_controller_test.js            |  20 +-
 .../test/controllers/main/host/details_test.js  |   1 +
 .../test/controllers/wizard/step4_test.js       | 175 +----
 .../test/controllers/wizard/step5_test.js       | 759 +++++++------------
 .../test/controllers/wizard/step6_test.js       |   6 -
 .../test/controllers/wizard/step8_test.js       | 153 ++++
 .../test/controllers/wizard/step9_test.js       |   2 +
 ambari-web/test/init_model_test.js              |  12 +-
 ambari-web/test/service_components.js           | 679 +++++++++++++++--
 ambari-web/test/utils/component_test.js         |  71 --
 ambari-web/test/utils/helper_test.js            |  86 +++
 ambari-web/test/views/wizard/step5_view_test.js |   4 +-
 78 files changed, 3155 insertions(+), 3378 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index 81ee5d5..5e31627 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -88,154 +88,28 @@ module.exports = Em.Application.create({
   }.property('router.clusterController.isLoaded', 'isHadoop2Stack'),
 
   /**
-   * List of disabled components for the current stack with related info.
-   * Each element has followed structure:
-   * @type {Em.Enumerable.<Em.Object>}
-   *   @property componentName {String} - name of the component
-   *   @property properties {Object} - mapped properties by site files,
-   *    for example:
-   *      properties: { global_properties: [], site_properties: [], etc. }
-   *   @property reviewConfigs {Ember.Object} - reference review_configs.js
+   * Object with utility functions for list of service names with similar behavior
    */
-  stackDependedComponents: [],
+  services: Em.Object.create({
+    all: function () {
+      return App.StackService.find().mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
 
-  /**
-   * Restore component data that was excluded from stack.
-   *
-   * @param component {Ember.Object} - #stackDependedComponents item
-   */
-  enableComponent: function (component) {
-    var propertyFileNames = ['global_properties', 'site_properties'];
-    var requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
-    // add properties
-    propertyFileNames.forEach(function (fileName) {
-      require(requirePrefix + fileName).configProperties = require(requirePrefix + fileName).configProperties.concat(component.get('properties.' + fileName));
-    });
-    var reviewConfigsService = require('data/review_configs')
-      .findProperty('config_name', 'services').config_value
-      .findProperty('service_name', component.get('serviceName'));
-    reviewConfigsService.get('service_components').pushObject(component.get('reviewConfigs'));
-  },
-  /**
-   * Disabling component. Remove related data from lists such as
-   * properties, review configs, service components.
-   *
-   * @param component {Object} - stack service component
-   *
-   * @return {Ember.Object} - item of <code>stackDependedComponents</code> property
-   */
-  disableComponent: function (component) {
-    var componentCopy, propertyFileNames;
-    var service_configs = require('data/service_configs');
-    propertyFileNames = ['global_properties', 'site_properties'];
-    componentCopy = Em.Object.create({
-      componentName: component.get('componentName'),
-      serviceName: component.get('serviceName'),
-      properties: {},
-      reviewConfigs: {},
-      configCategory: {}
-    });
+    clientOnly: function () {
+      return App.StackService.find().filterProperty('isClientOnlyService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
 
-    var serviceConfigsCategoryName, requirePrefix, serviceConfig;
-    // get service category name related to component
-    serviceConfig = service_configs.findProperty('serviceName', component.get('serviceName'));
-    serviceConfig.configCategories = serviceConfig.configCategories.filter(function (configCategory) {
-      if (configCategory.get('hostComponentNames')) {
-        serviceConfigsCategoryName = configCategory.get('name');
-        if (configCategory.get('hostComponentNames').contains(component.get('componentName'))) {
-          componentCopy.set('configCategory', configCategory);
-        }
-      }
-      return true;
-    });
-    requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
-    var propertyObj = {};
-    propertyFileNames.forEach(function (propertyFileName) {
-      propertyObj[propertyFileName] = [];
-    });
-    // remove config properties related to this component
-    propertyFileNames.forEach(function (propertyFileName) {
-      var properties = require(requirePrefix + propertyFileName);
-      properties.configProperties = properties.configProperties.filter(function (property) {
-        if (property.category == serviceConfigsCategoryName) {
-          propertyObj[propertyFileName].push(property);
-          return false;
-        } else {
-          return true;
-        }
-      });
-    });
-    componentCopy.set('properties', propertyObj);
-    // remove component from review configs
-    var reviewConfigsService = require('data/review_configs')
-      .findProperty('config_name', 'services').config_value
-      .findProperty('service_name', component.get('serviceName'));
-    //review_configs might not contain particular service
-    if (reviewConfigsService) {
-      reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) {
-        if (serviceComponent.get('component_name') != component.get('componentName')) {
-          return true;
-        } else {
-          componentCopy.set('reviewConfigs', serviceComponent);
-          return false;
-        }
-      }));
-    }
-    return componentCopy;
-  },
-  /**
-   * Resolve dependency in components.
-   * if component with config category from "data/service_configs" doesn't match components from stack
-   * then disable it and push to stackDependedComponents
-   * otherwise enable component and remove it from stackDependedComponents
-   * Check forbidden/allowed components and
-   * remove/restore related data.
-   *
-   * @method handleStackDependedComponents
-   */
-  handleStackDependedComponents: function () {
-    // need for unit testing and test mode
-    if (this.get('handleStackDependencyTest') || this.testMode) return;
-    var stackDependedComponents = this.get('stackDependedComponents');
-    var service_configs = require('data/service_configs');
-    var stackServiceComponents = this.StackServiceComponent.find();
-    var stackServices = stackServiceComponents.mapProperty('serviceName').uniq();
-    if (!stackServiceComponents.mapProperty('componentName').length) {
-      return;
-    }
-    // disable components
-    service_configs.forEach(function (service) {
-      service.configCategories.forEach(function (serviceConfigCategory) {
-        var categoryComponents = serviceConfigCategory.get('hostComponentNames');
-        if (categoryComponents && categoryComponents.length) {
-          categoryComponents.forEach(function (categoryComponent) {
-            var stackServiceComponent = stackServiceComponents.findProperty('componentName', categoryComponent);
-            // populate App.stackDependedComponents if the service config category for the serviceComponent
-            // exists in the 'data/service_configs.js' and the service to which the component belongs also exists in the
-            // stack but the serviceComponent does not exists in the stack. Also check App.stackDependedComponents doesn't already have the componentName
-            if (!stackServiceComponent && stackServices.contains(service.serviceName) && !stackDependedComponents.mapProperty('componentName').contains['categoryComponent']) {
-              var _stackServiceComponent = Ember.Object.create({
-                componentName: categoryComponent,
-                serviceName: service.serviceName
-              });
-              stackDependedComponents.push(this.disableComponent(_stackServiceComponent));
-            }
-          }, this);
-        }
-      }, this);
-    }, this);
+    hasClient: function () {
+      return App.StackService.find().filterProperty('hasClient').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
 
-    // enable components
-    if (stackDependedComponents.length > 0) {
-      stackDependedComponents.forEach(function (component) {
-        if (stackServiceComponents.someProperty('componentName', component.get('componentName'))) {
-          this.enableComponent(component);
-          stackDependedComponents.removeObject(component);
-        }
-      }, this);
-    }
-    this.set('stackDependedComponents', stackDependedComponents);
-  },
+    noConfigTypes: function () {
+      return App.StackService.find().filterProperty('isNoConfigTypes').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+    monitoring: function () {
+      return App.StackService.find().filterProperty('isMonitoringService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded')
+  }),
 
   /**
    * List of components with allowed action for them
@@ -274,6 +148,14 @@ module.exports = Em.Application.create({
       return App.StackServiceComponent.find().filterProperty('isAddableToHost', true).mapProperty('componentName')
     }.property('App.router.clusterController.isLoaded'),
 
+    addableMasterInstallerWizard: function () {
+      return App.StackServiceComponent.find().filterProperty('isMasterWithMultipleInstances', true).mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    addableMasterHaWizard: function () {
+      return App.StackServiceComponent.find().filterProperty('isMasterWithMultipleInstancesHaWizard', true).mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
     slaves: function () {
       return App.StackServiceComponent.find().filterProperty('isMaster', false).filterProperty('isClient', false).mapProperty('componentName')
     }.property('App.router.clusterController.isLoaded'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index df70820..b68ddab 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -305,9 +305,14 @@ App.ClusterController = Em.Controller.extend({
      * 10. update stale_configs of host-components (depends on App.supports.hostOverrides)
      */
     this.loadStackServiceComponents(function (data) {
+      data.items.forEach(function(service) {
+        service.StackServices.is_selected = true;
+        service.StackServices.is_installed = false;
+      },this);
+      App.stackServiceMapper.map(data);
+      App.config.setPreDefinedGlobalProperties();
+      App.config.setPreDefinedServiceConfigs();
       var updater = App.router.get('updateController');
-
-      require('utils/component').loadStackServiceComponentModel(data);
       self.updateLoadStatus('stackComponents');
       updater.updateServices(function () {
         self.updateLoadStatus('services');

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index d339433..940cf77 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -122,18 +122,11 @@ App.InstallerController = App.WizardController.extend({
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
   loadServices: function () {
-    var servicesInfo = this.getDBProperty('service');
-    if(servicesInfo && servicesInfo.length) {
-      servicesInfo.forEach(function (item, index) {
-        servicesInfo[index] = Em.Object.create(item);
-        servicesInfo[index].isInstalled = false;
-      });
-      this.set('content.services', servicesInfo);
-      console.log('installerController.loadServices: loaded data ', JSON.stringify(servicesInfo));
-      console.log('selected services ', servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName'));
-    } else {
-      console.log("Failed to load Services");
-   }
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    if (!(stackServices && !!stackServices.length && App.StackService.find().objectAt(0).get('stackVersion') == App.get('currentStackVersionNumber'))) {
+      this.loadServiceComponents();
+      this.set('content.services', App.StackService.find());
+    }
   },
 
   /**
@@ -207,18 +200,6 @@ App.InstallerController = App.WizardController.extend({
     return hosts;
   }.property('content.hosts'),
 
-  /**
-   * Load service components.
-   */
-  loadServiceComponentsDb: function () {
-    var serviceComponents = this.getDBProperty('serviceComponents');
-    if(serviceComponents && serviceComponents.items && serviceComponents.items.length) {
-      App.stackServiceComponentMapper.map(serviceComponents);
-    } else {
-      console.log("Failed to load Service components");
-    }
-  },
-
   stacks: [],
 
   /**
@@ -391,11 +372,19 @@ App.InstallerController = App.WizardController.extend({
    * @param stepController App.WizardStep4Controller
    */
   saveServices: function (stepController) {
-    this.setDBProperty('service', stepController.get('content'));
-    var serviceNames = stepController.filterProperty('isSelected', true).mapProperty('serviceName');
-    this.set('content.selectedServiceNames', serviceNames);
-    this.setDBProperty('selectedServiceNames', serviceNames);
-    console.log('installerController.saveServices: saved data ', serviceNames);
+    var selectedServiceNames = [];
+    var installedServiceNames = [];
+    stepController.filterProperty('isSelected').forEach(function (item) {
+      selectedServiceNames.push(item.get('serviceName'));
+    });
+    stepController.filterProperty('isInstalled').forEach(function (item) {
+      installedServiceNames.push(item.get('serviceName'));
+    });
+    this.set('content.services', App.StackService.find());
+    this.set('content.selectedServiceNames', selectedServiceNames);
+    this.setDBProperty('selectedServiceNames', selectedServiceNames);
+    this.set('content.installedServiceNames', installedServiceNames);
+    this.setDBProperty('installedServiceNames', installedServiceNames);
   },
 
   /**
@@ -486,21 +475,19 @@ App.InstallerController = App.WizardController.extend({
   saveClients: function (stepController) {
     var clients = [];
     var serviceComponents = App.StackServiceComponent.find();
-
+    var services =
     stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) {
-      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient', true);
-      if (client) {
+      var client = _service.get('serviceComponents').filterProperty('isClient', true);
+      client.forEach(function(clientComponent){
         clients.pushObject({
-          component_name: client.get('componentName'),
-          display_name: client.get('displayName'),
+          component_name: clientComponent.get('componentName'),
+          display_name: clientComponent.get('displayName'),
           isInstalled: false
         });
-      }
+      },this);
     }, this);
-
     this.setDBProperty('clientInfo', clients);
     this.set('content.clients', clients);
-    console.log("InstallerController.saveClients: saved list ", clients);
   },
 
   /**
@@ -614,8 +601,8 @@ App.InstallerController = App.WizardController.extend({
         this.loadMasterComponentHosts();
         this.loadConfirmedHosts();
       case '4':
+        this.loadStacks();
         this.loadServices();
-        this.loadServiceComponentsDb();
       case '3':
         this.loadConfirmedHosts();
       case '2':

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/cluster.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/cluster.js b/ambari-web/app/controllers/main/admin/cluster.js
index 6e105da..264b4e9 100644
--- a/ambari-web/app/controllers/main/admin/cluster.js
+++ b/ambari-web/app/controllers/main/admin/cluster.js
@@ -20,15 +20,15 @@ var App = require('app');
 var stringUtils = require('utils/string_utils');
 
 App.MainAdminClusterController = Em.Controller.extend({
-  name:'mainAdminClusterController',
+  name: 'mainAdminClusterController',
   services: [],
   allRepos: [],
   upgradeVersion: '',
   /**
    * get the newest version of HDP from server
    */
-  updateUpgradeVersion: function(){
-    if(App.router.get('clusterController.isLoaded')){
+  updateUpgradeVersion: function () {
+    if (App.router.get('clusterController.isLoaded')) {
       App.ajax.send({
         name: 'cluster.update_upgrade_version',
         sender: this,
@@ -36,25 +36,25 @@ App.MainAdminClusterController = Em.Controller.extend({
         error: 'updateUpgradeVersionErrorCallback'
       });
     }
-  }.observes('App.router.clusterController.isLoaded', 'App.currentStackVersion','App.router.mainServiceController.content.length'),
+  }.observes('App.router.clusterController.isLoaded', 'App.currentStackVersion', 'App.router.mainServiceController.content.length'),
 
-  updateUpgradeVersionSuccessCallback: function(data) {
+  updateUpgradeVersionSuccessCallback: function (data) {
     var upgradeVersion = this.get('upgradeVersion') || App.defaultStackVersion;
     var currentVersion = App.get('currentStackVersionNumber');
     upgradeVersion = upgradeVersion.replace(/HDP-/, '');
-    data.items.mapProperty('Versions.stack_version').forEach(function(version){
+    data.items.mapProperty('Versions.stack_version').forEach(function (version) {
       upgradeVersion = (stringUtils.compareVersions(upgradeVersion, version) === -1) ? version : upgradeVersion;
     });
     var currentStack = data.items.findProperty('Versions.stack_version', currentVersion);
     var upgradeStack = data.items.findProperty('Versions.stack_version', upgradeVersion);
     var minUpgradeVersion = upgradeStack.Versions.min_upgrade_version;
-    if(minUpgradeVersion && (stringUtils.compareVersions(minUpgradeVersion, currentVersion) === 1)){
+    if (minUpgradeVersion && (stringUtils.compareVersions(minUpgradeVersion, currentVersion) === 1)) {
       upgradeVersion = currentVersion;
       upgradeStack = currentStack;
     }
     upgradeVersion = 'HDP-' + upgradeVersion;
     this.set('upgradeVersion', upgradeVersion);
-    if(currentStack && upgradeStack) {
+    if (currentStack && upgradeStack) {
       this.parseServicesInfo(currentStack, upgradeStack);
     }
     else {
@@ -62,7 +62,7 @@ App.MainAdminClusterController = Em.Controller.extend({
     }
   },
 
-  updateUpgradeVersionErrorCallback: function(request, ajaxOptions, error) {
+  updateUpgradeVersionErrorCallback: function (request, ajaxOptions, error) {
     console.log('Error message is: ' + request.responseText);
     console.log('HDP stack doesn\'t have services with defaultStackVersion');
   },
@@ -70,8 +70,8 @@ App.MainAdminClusterController = Em.Controller.extend({
   /**
    * get the installed repositories of HDP from server
    */
-  loadRepositories: function(){
-    if(App.router.get('clusterController.isLoaded')){
+  loadRepositories: function () {
+    if (App.router.get('clusterController.isLoaded')) {
       var nameVersionCombo = App.get('currentStackVersion');
       var stackName = nameVersionCombo.split('-')[0];
       var stackVersion = nameVersionCombo.split('-')[1];
@@ -119,7 +119,7 @@ App.MainAdminClusterController = Em.Controller.extend({
     this.set('allRepos', allRepos);
   },
 
-  loadRepositoriesErrorCallback: function(request, ajaxOptions, error) {
+  loadRepositoriesErrorCallback: function (request, ajaxOptions, error) {
     console.log('Error message is: ' + request.responseText);
   },
 
@@ -129,42 +129,32 @@ App.MainAdminClusterController = Em.Controller.extend({
   parseServicesInfo: function (currentStack, upgradeStack) {
     var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
-    var displayOrderConfig = require('data/services');
-    if(currentStack.stackServices.length && upgradeStack.stackServices.length){
+    var displayOrder = App.StackService.displayOrder;
+    if (currentStack.stackServices.length && upgradeStack.stackServices.length) {
       // loop through all the service components
-      for (var i = 0; i < displayOrderConfig.length; i++) {
+      displayOrder.forEach(function (_stackServiceName) {
         var entry = currentStack.stackServices.
-          findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-        if (entry) {
-          entry = entry.StackServices;
-          if (installedServices.contains(entry.service_name)) {
-            var myService = Em.Object.create({
-              serviceName: entry.service_name,
-              displayName: displayOrderConfig[i].displayName,
-              isDisabled: displayOrderConfig[i].isDisabled,
-              isSelected: true,
-              isInstalled: false,
-              isHidden: displayOrderConfig[i].isHidden,
-              description: entry.comments,
-              version: entry.service_version,
-              newVersion: ''
-            });
-            // it's possible that there is no corresponding service in the new stack
-            var matchedService = upgradeStack.stackServices.findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-            if (matchedService) {
-              myService.newVersion = matchedService.StackServices.service_version;
-            }
-            //From 1.3.0 for Hive we display only "Hive" (but it install HCat and WebHCat as well)
-            if (this.get('upgradeVersion').replace(/HDP-/, '') >= '1.3.0' && displayOrderConfig[i].serviceName == 'HIVE') {
-              myService.set('displayName', 'Hive');
-            }
-            result.push(myService);
+          findProperty("StackServices.service_name", _stackServiceName);
+        var stackService = App.StackService.find().findProperty('serviceName', _stackServiceName);
+        if (!!stackService) {
+          var myService = Em.Object.create({
+            serviceName: stackService.get('serviceName'),
+            displayName: stackService.get('displayNameOnSelectServicePage'),
+            isSelected: true,
+            isInstalled: false,
+            isHidden:  stackService.get('isHiddenOnSelectServicePage'),
+            description: stackService.get('comments'),
+            version: stackService.get('serviceVersion'),
+            newVersion: ''
+          });
+          // it's possible that there is no corresponding service in the new stack
+          var matchedService = upgradeStack.stackServices.findProperty("StackServices.service_name", stackService.get('serviceName'));
+          if (matchedService) {
+            myService.newVersion = matchedService.StackServices.service_version;
           }
+          result.push(myService);
         }
-        else {
-          console.warn('Service not found - ', displayOrderConfig[i].serviceName);
-        }
-      }
+      }, this);
     }
     this.set('services', result);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
index d58d7dd..e7e77bb 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
@@ -25,9 +25,15 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
   name:"highAvailabilityWizardStep2Controller",
 
   /**
-   * master components which could be assigned to multiple hosts
+   * master components which could be assigned to multiple hosts in HA wizard
    */
-  multipleComponents: ['NAMENODE', 'JOURNALNODE'],
+  multipleComponentsHaWizard: ['NAMENODE', 'JOURNALNODE'],
+
+  /**
+   * master components supported by Ambari
+   */
+
+  multipleComponents: ['NAMENODE', 'JOURNALNODE','ZOOKEEPER_SERVER','HBASE_MASTER'],
 
   /**
    * overrides method in wizardStep5Controller
@@ -53,7 +59,7 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
 
       var masterServices = self.get("selectedServicesMasters").filterProperty("selectedHost", item);
       masterServices.forEach(function(item){
-        if(this.get('multipleComponents').contains(item.component_name)){
+        if(this.get('multipleComponentsHaWizard').contains(item.component_name)){
           item.set('color','green');
         }else{
           item.set('color','grey');
@@ -77,14 +83,13 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
    * @param masterComponents
    */
   renderComponents:function (masterComponents) {
-    var services = this.get('content.services')
-      .filterProperty('isInstalled', true).filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
+    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
 
     var result = [];
 
     var curNameNode = masterComponents.findProperty('component_name',"NAMENODE");
     curNameNode.isCurNameNode = true;
-    curNameNode.zId = 0;
+    curNameNode.serviceComponentId = 0;
 
     //Create JOURNALNODE
     for (var index = 0; index < 3; index++) {
@@ -92,11 +97,11 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
         {
           component_name: "JOURNALNODE",
           display_name: "JournalNode",
-          isHiveCoHost: false,
+          isServiceCoHost: false,
           isInstalled: false,
           selectedHost: this.get("hosts")[index].get("host_name"),
           serviceId: "HDFS",
-          zId: index
+          serviceComponentId: index
         }
       )
     }
@@ -105,12 +110,12 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
       {
         component_name: "NAMENODE",
         display_name: "NameNode",
-        isHiveCoHost: false,
+        isServiceCoHost: false,
         isInstalled: false,
         selectedHost: this.get("hosts").mapProperty('host_name').without(curNameNode.selectedHost)[0],
         serviceId: "HDFS",
         isAddNameNode: true,
-        zId: 1
+        serviceComponentId: 1
       }
     );
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
index a6e35b1..22791bf 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
@@ -66,14 +66,31 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
    * Load services data from server.
    */
   loadServicesFromServer: function() {
-    var apiService = this.loadServiceComponents();
-    apiService.forEach(function(item, index){
-      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
-      apiService[index].isDisabled = apiService[index].isSelected;
-      apiService[index].isInstalled = apiService[index].isSelected;
-    });
-    this.set('content.services', apiService);
-    App.db.setService(apiService);
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+    }
+    this.set('content.services', App.StackService.find());
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/misc_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/misc_controller.js b/ambari-web/app/controllers/main/admin/misc_controller.js
index 6ebdd7c..628d813 100644
--- a/ambari-web/app/controllers/main/admin/misc_controller.js
+++ b/ambari-web/app/controllers/main/admin/misc_controller.js
@@ -49,7 +49,7 @@ App.MainAdminMiscController = App.MainServiceInfoConfigsController.extend({
     var loadedClusterSiteToTagMap = {};
 
     for (var site in data.Clusters.desired_configs) {
-      if (serviceConfigsDef.sites.indexOf(site) > -1) {
+      if (serviceConfigsDef.configTypes.contains(site)) {
         loadedClusterSiteToTagMap[site] = data.Clusters.desired_configs[site]['tag'];
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/host/add_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/add_controller.js b/ambari-web/app/controllers/main/host/add_controller.js
index 8af72a1..a0f08bd 100644
--- a/ambari-web/app/controllers/main/host/add_controller.js
+++ b/ambari-web/app/controllers/main/host/add_controller.js
@@ -100,32 +100,34 @@ App.AddHostController = App.WizardController.extend({
   },
 
   /**
-   * Load services data from server.
-   * TODO move to mixin
-   */
-  loadServicesFromServer: function () {
-    var apiService = this.loadServiceComponents();
-    apiService.forEach(function (item, index) {
-      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
-      apiService[index].isDisabled = apiService[index].isSelected;
-      apiService[index].isInstalled = apiService[index].isSelected;
-    });
-    this.set('content.services', apiService);
-    this.setDBProperty('service', apiService);
-  },
-
-  /**
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
   loadServices: function () {
-    var servicesInfo = this.getDBProperty('service');
-    console.log('AddHostController.loadServices: loaded data ', servicesInfo);
-    servicesInfo.forEach(function (item, index) {
-      servicesInfo[index] = Em.Object.create(item);
-    });
-    this.set('content.services', servicesInfo);
-    var serviceNames = servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName');
-    console.log('selected services ', serviceNames);
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+    }
+    this.set('content.services', App.StackService.find());
   },
 
   /**
@@ -171,7 +173,7 @@ App.AddHostController = App.WizardController.extend({
     }
 
     this.get('content.services').filterProperty('isSelected').forEach(function (_service) {
-      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient');
+      var client = serviceComponents.filterProperty('serviceName', _service.get('serviceName')).findProperty('isClient');
       if (client) {
         clients.push({
           component_name: client.get('componentName'),
@@ -180,7 +182,6 @@ App.AddHostController = App.WizardController.extend({
         });
       }
     }, this);
-
     this.setDBProperty('clientInfo', clients);
     this.set('content.clients', clients);
     console.log("AddHostController.saveClients: saved list ", clients);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service.js b/ambari-web/app/controllers/main/service.js
index fba94b1..1c9d774 100644
--- a/ambari-web/app/controllers/main/service.js
+++ b/ambari-web/app/controllers/main/service.js
@@ -20,7 +20,6 @@ var App = require('app');
 
 App.MainServiceController = Em.ArrayController.extend({
   name:'mainServiceController',
-  stackServices: [],
   content: function(){
     if(!App.router.get('clusterController.isLoaded')){
       return [];
@@ -37,46 +36,22 @@ App.MainServiceController = Em.ArrayController.extend({
 
   isAllServicesInstalled: function() {
     if (!this.get('content.content')) return false;
-    if (!this.get('stackServices').length) {
-      this.loadAvailableServices();
-    }
+
+    var availableServices = App.StackService.find().mapProperty('serviceName');
     if (!App.supports.hue) {
-      var stackServices = this.get('stackServices').without('HUE');
-      this.set('stackServices',stackServices);
+      availableServices = availableServices.without('HUE');
     }
-    return this.get('content.content').length == this.get('stackServices').length;
+    return this.get('content.content').length == availableServices.length;
   }.property('content.content.@each', 'content.content.length'),
 
-  loadAvailableServices: function() {
-    App.ajax.send({
-      name: 'wizard.service_components',
-      sender: this,
-      data: {
-        stackUrl: App.get('stackVersionURL'),
-        stackVersion: App.get('currentStackVersionNumber')
-      },
-      success: 'loadAvailableServicesSuccessCallback'
-    });
-  },
-
-  loadAvailableServicesSuccessCallback: function(jsonData) {
-    var data = [];
-    var displayOrderConfig = require('data/services');
-    for (var i = 0; i < displayOrderConfig.length; i++) {
-      var entry = jsonData.items.findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-      if (entry) {
-        data.push(entry.StackServices.service_name);
-      }
-    }
-    this.set('stackServices',data);
-  },
-
   isStartAllDisabled: function(){
     if(this.get('isStartStopAllClicked') == true) {
       return true;
     }
-    var stoppedServiceLength = this.get('content').filterProperty('healthStatus','red').filterProperty('isClientsOnly', false).length;
-    return (stoppedServiceLength === 0); // all green status
+    var stoppedServices =  this.get('content').filter(function(_service){
+      return (_service.get('healthStatus') === 'red' && !App.get('services.clientOnly').contains(_service.get('serviceName')));
+    });
+    return (stoppedServices.length === 0); // all green status
   }.property('isStartStopAllClicked', 'content.@each.healthStatus'),
   isStopAllDisabled: function(){
     if(this.get('isStartStopAllClicked') == true) {
@@ -158,5 +133,4 @@ App.MainServiceController = Em.ArrayController.extend({
     }
     App.router.transitionTo('main.serviceAdd');
   }
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/add_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/add_controller.js b/ambari-web/app/controllers/main/service/add_controller.js
index 2f353c8..89669ff 100644
--- a/ambari-web/app/controllers/main/service/add_controller.js
+++ b/ambari-web/app/controllers/main/service/add_controller.js
@@ -22,8 +22,6 @@ App.AddServiceController = App.WizardController.extend({
 
   name: 'addServiceController',
 
-  serviceConfigs:require('data/service_configs'),
-
   totalSteps: 7,
 
   /**
@@ -80,7 +78,6 @@ App.AddServiceController = App.WizardController.extend({
       return;
     }
     var apiService = this.loadServiceComponents();
-    //
     apiService.forEach(function(item, index){
       apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
       apiService[index].isDisabled = apiService[index].isSelected;
@@ -94,20 +91,38 @@ App.AddServiceController = App.WizardController.extend({
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
   loadServices: function () {
-    var servicesInfo = this.getDBProperty('service');
-    servicesInfo.forEach(function (item, index) {
-      servicesInfo[index] = Em.Object.create(item);
-    });
-    this.set('content.services', servicesInfo);
-    console.log('AddServiceController.loadServices: loaded data ', servicesInfo);
-
-    var serviceNames = servicesInfo.filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName');
-    console.log('selected services ', serviceNames);
-
-    this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE')  && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
-    if (this.get('content.skipSlavesStep')) {
-      this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+      var serviceNames = App.StackService.find().filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
+      console.log('selected services ', serviceNames);
+
+      this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE')  && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
+      if (this.get('content.skipSlavesStep')) {
+        this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
+      }
     }
+    this.set('content.services', App.StackService.find());
   },
 
   /**
@@ -116,14 +131,18 @@ App.AddServiceController = App.WizardController.extend({
    */
   saveServices: function (stepController) {
     var serviceNames = [];
-    this.setDBProperty('service', stepController.get('content'));
+    var services = {
+      selectedServices: [],
+      installedServices: []
+    };
+    var selectedServices = stepController.get('content').filterProperty('isSelected',true).filterProperty('isInstalled', false).mapProperty('serviceName');
+    services.selectedServices.pushObjects(selectedServices);
+    services.installedServices.pushObjects(stepController.get('content').filterProperty('isInstalled',true).mapProperty('serviceName'));
+    this.setDBProperty('services',services);
     console.log('AddServiceController.saveServices: saved data', stepController.get('content'));
-    stepController.filterProperty('isSelected', true).filterProperty('isInstalled', false).forEach(function (item) {
-      serviceNames.push(item.serviceName);
-    });
-    this.set('content.selectedServiceNames', serviceNames);
-    this.setDBProperty('selectedServiceNames',serviceNames);
-    console.log('AddServiceController.selectedServiceNames:', serviceNames);
+
+    this.set('content.selectedServiceNames', selectedServices);
+    this.setDBProperty('selectedServiceNames',selectedServices);
 
     this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE') && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
     if (this.get('content.skipSlavesStep')) {
@@ -172,8 +191,8 @@ App.AddServiceController = App.WizardController.extend({
    * @param {string} serviceName
    * @returns {boolean}
    */
-  isServiceConfigurable: function(serviceName) {
-    return this.get('serviceConfigs').mapProperty('serviceName').contains(serviceName);
+  isServiceNotConfigurable: function(serviceName) {
+    return App.get('services.noConfigTypes').contains(serviceName);
   },
 
   /**
@@ -184,7 +203,7 @@ App.AddServiceController = App.WizardController.extend({
     var skipConfigStep = true;
     var selectedServices = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
     selectedServices.map(function(serviceName) {
-      skipConfigStep = skipConfigStep && !this.isServiceConfigurable(serviceName);
+      skipConfigStep = skipConfigStep && this.isServiceNotConfigurable(serviceName);
     }, this);
     return skipConfigStep;
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/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 ee1336f..0db4b50 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -34,7 +34,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   globalConfigs: [],
   uiConfigs: [],
   customConfig: [],
-  serviceConfigsData: require('data/service_configs'),
   isApplyingChanges: false,
   saveConfigsFlag: true,
   putClusterConfigsCallsNumber: null,
@@ -228,7 +227,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     var selectedConfigGroup;
     var siteToTagMap = {};
     var hostsLength = App.router.get('mainHostController.hostsCountMap.TOTAL');
-    serviceConfigsDef.sites.forEach(function(siteName){
+    serviceConfigsDef.get('configTypes').forEach(function(siteName){
       if(data.Clusters.desired_configs[siteName]){
         siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
       } else {
@@ -537,7 +536,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @method loadConfigs
    */
   loadConfigs: function(configs, componentConfig) {
-    var serviceConfigsData = this.get('serviceConfigsData').findProperty('serviceName', this.get('content.serviceName'));
+    var serviceConfigsData = App.StackService.find().findProperty('serviceName', this.get('content.serviceName'));
     var defaultGroupSelected = this.get('selectedConfigGroup.isDefault');
     configs.forEach(function (_serviceConfigProperty) {
       var serviceConfigProperty = this.createConfigProperty(_serviceConfigProperty, defaultGroupSelected, serviceConfigsData);
@@ -594,18 +593,20 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @mrethod setRecommendedDefaults
    */
   setRecommendedDefaults: function (advancedConfigs) {
-    var s = this.get('serviceConfigsData').findProperty('serviceName', this.get('content.serviceName'));
+    var s = App.StackService.find().findProperty('serviceName', this.get('content.serviceName'));
     var dfd = $.Deferred();
-    if (!s.defaultsProviders) {
+    var defaultsProvider = s.get('defaultsProviders');
+    var configsValidator = s.get('configsValidator');
+    if (!defaultsProvider) {
       dfd.resolve();
       return dfd.promise();
     }
-    this.getInfoForDefaults(s.defaultsProviders);
+    this.getInfoForDefaults(defaultsProvider);
     this.addObserver('defaultsInfo.hosts.length', this, function() {
       var localDB = this.get('defaultsInfo');
       var recommendedDefaults = {};
-      if (s.defaultsProviders) {
-        s.defaultsProviders.forEach(function (defaultsProvider) {
+      if (defaultsProvider) {
+        defaultsProvider.forEach(function (defaultsProvider) {
           var d = defaultsProvider.getDefaults(localDB);
           for (var name in d) {
             if (!!d[name]) {
@@ -619,8 +620,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
           }
         });
       }
-      if (s.configsValidator) {
-        s.configsValidator.set('recommendedDefaults', recommendedDefaults);
+      if (configsValidator) {
+        configsValidator.set('recommendedDefaults', recommendedDefaults);
       }
       dfd.resolve();
     });
@@ -650,10 +651,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    */
   setValidator: function(serviceConfigProperty, serviceConfigsData) {
     if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
-      if (serviceConfigsData.configsValidator) {
-        for (var validatorName in serviceConfigsData.configsValidator.get('configValidators')) {
+      if (serviceConfigsData.get('configsValidator')) {
+        for (var validatorName in serviceConfigsData.get('configsValidator.configValidators')) {
           if (serviceConfigProperty.get("name") == validatorName) {
-            serviceConfigProperty.set('serviceValidator', serviceConfigsData.configsValidator);
+            serviceConfigProperty.set('serviceValidator', serviceConfigsData.get('configsValidator'));
           }
         }
       }
@@ -1798,7 +1799,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    */
   setHostForService: function(serviceName, componentName, hostProperty, multiple) {
     var globalConfigs = this.get('globalConfigs');
-    var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).configs;
+    var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).get('configs');
     var hostConfig = serviceConfigs.findProperty('name', hostProperty);
     if (hostConfig) {
       hostConfig.defaultValue = this.getMasterComponentHostValue(componentName, multiple);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index c93259e..89e6c60 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -43,6 +43,15 @@ App.MainServiceItemController = Em.Controller.extend({
       's': 'stop'
     }
   },
+
+  isClientsOnlyService: function() {
+    return App.get('services.clientOnly').contains(this.get('content.serviceName'));
+  }.property('content.serviceName'),
+
+  isConfigurable: function () {
+    return !App.get('services.noConfigTypes').concat('HCATALOG').contains('content.serviceName');
+  }.property('App.services.noConfigTypes','content.serviceName'),
+
   /**
    * Common method for ajax (start/stop service) responses
    * @param data
@@ -301,8 +310,7 @@ App.MainServiceItemController = Em.Controller.extend({
    */
   refreshConfigs: function () {
     var self = this;
-
-    if (this.get('content.isClientsOnly')) {
+    if (this.get('isClientsOnlyService')) {
       return App.showConfirmationFeedBackPopup(function (query) {
         batchUtils.getComponentsFromServer({
           services: [self.get('content.serviceName')]

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/reassign/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step2_controller.js b/ambari-web/app/controllers/main/service/reassign/step2_controller.js
index 8964c1b..977cb4e 100644
--- a/ambari-web/app/controllers/main/service/reassign/step2_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step2_controller.js
@@ -55,7 +55,7 @@ App.ReassignMasterWizardStep2Controller = App.WizardStep5Controller.extend({
         selectedHost: master.hostName,
         isInstalled: true,
         serviceId: App.HostComponent.find().findProperty('componentName', master.component).get('serviceName'),
-        isHiveCoHost: ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(master.component),
+        isServiceCoHost: ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(master.component),
         color: color
       });
     }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/reassign_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign_controller.js b/ambari-web/app/controllers/main/service/reassign_controller.js
index 167e179..febe092 100644
--- a/ambari-web/app/controllers/main/service/reassign_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign_controller.js
@@ -141,14 +141,31 @@ App.ReassignMasterController = App.WizardController.extend({
    * Load services data from server.
    */
   loadServicesFromServer: function () {
-    var apiService = this.loadServiceComponents();
-    apiService.forEach(function (item, index) {
-      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
-      apiService[index].isDisabled = apiService[index].isSelected;
-      apiService[index].isInstalled = apiService[index].isSelected;
-    });
-    this.set('content.services', apiService);
-    App.db.setService(apiService);
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+    }
+    this.set('content.services', App.StackService.find());
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index b48b6d9..c21ee96 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -55,7 +55,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
 
   slaveComponents: function () {
-    return App.StackServiceComponent.find().filterProperty('isSlave',true);
+    return App.StackServiceComponent.find().filterProperty('isSlave', true);
   }.property('App.router.clusterController.isLoaded'),
 
   allHosts: function () {
@@ -511,10 +511,20 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   loadedServiceComponents: null,
 
   /**
+   * Clean store from already loaded data.
+   **/
+  clearStackModels: function () {
+    if (App.StackService.find().get('content').length) {
+      App.StackServiceComponent.find().set('content', []);
+      App.StackService.find().set('content', []);
+    }
+  },
+  /**
    * Generate serviceComponents as pr the stack definition  and save it to localdata
    * called form stepController step4WizardController
    */
   loadServiceComponents: function () {
+    this.clearStackModels();
     App.ajax.send({
       name: 'wizard.service_components',
       sender: this,
@@ -526,14 +536,40 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       success: 'loadServiceComponentsSuccessCallback',
       error: 'loadServiceComponentsErrorCallback'
     });
-    return this.get('loadedServiceComponents');
   },
 
   loadServiceComponentsSuccessCallback: function (jsonData) {
-    this.setServices(jsonData);
-    this.setServiceComponents(jsonData);
-    console.log("TRACE: getService ajax call  -> In success function for the getServiceComponents call");
-    console.log("TRACE: jsonData.services : " + jsonData.items);
+    var savedSelectedServices = this.getDBProperty('selectedServiceNames');
+    var savedInstalledServices = this.getDBProperty('installedServiceNames');
+    this.set('content.selectedServiceNames', savedSelectedServices);
+    this.set('content.installedServiceNames', savedInstalledServices);
+    if (!savedSelectedServices) {
+      jsonData.items.forEach(function (service) {
+        service.StackServices.is_selected = true;
+      }, this);
+    } else {
+      jsonData.items.forEach(function (service) {
+        if (savedSelectedServices.contains(service.StackServices.service_name))
+          service.StackServices.is_selected = true;
+        else
+          service.StackServices.is_selected = false;
+      }, this);
+    }
+
+    if (!savedInstalledServices) {
+      jsonData.items.forEach(function (service) {
+        service.StackServices.is_installed = false;
+      }, this);
+    } else {
+      jsonData.items.forEach(function (service) {
+        if (savedInstalledServices.contains(service.StackServices.service_name))
+          service.StackServices.is_installed = true;
+        else
+          service.StackServices.is_installed = false;
+      }, this);
+    }
+
+    App.stackServiceMapper.map(jsonData);
   },
 
   loadServiceComponentsErrorCallback: function (request, ajaxOptions, error) {
@@ -543,64 +579,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
 
   /**
-   *
-   * @param jsonData
-   */
-  setServices: function(jsonData) {
-    var displayOrderConfig = require('data/services');
-    // Creating Model
-    var Service = Ember.Object.extend({
-      serviceName: null,
-      displayName: null,
-      isDisabled: true,
-      isSelected: true,
-      isInstalled: false,
-      description: null,
-      version: null
-    });
-
-    var data = [];
-    // loop through all the service components
-    for (var i = 0; i < displayOrderConfig.length; i++) {
-      var entry = jsonData.items.findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-      if (entry) {
-        var myService = Service.create({
-          serviceName: entry.StackServices.service_name,
-          displayName: displayOrderConfig[i].displayName,
-          isDisabled: displayOrderConfig[i].isDisabled,
-          isSelected: displayOrderConfig[i].isSelected,
-          canBeSelected: displayOrderConfig[i].canBeSelected,
-          isInstalled: false,
-          isHidden: displayOrderConfig[i].isHidden,
-          description: entry.StackServices.comments,
-          version: entry.StackServices.service_version
-        });
-
-        data.push(myService);
-      }
-      else {
-        console.warn('Service not found - ', displayOrderConfig[i].serviceName);
-      }
-    }
-
-    this.set('loadedServiceComponents', data);
-  },
-
-  /**
-   *
-   * @param jsonData
-   */
-  setServiceComponents: function(jsonData) {
-    var serviceComponents = require('utils/component').loadStackServiceComponentModel(jsonData);
-    this.setDBProperty('serviceComponents', serviceComponents);
-  },
-
-  loadServicesFromServer: function () {
-    var apiService = this.loadServiceComponents();
-    this.set('content.services', apiService);
-    this.setDBProperty('service', apiService);
-  },
-  /**
    * Load config groups from local DB
    */
   loadServiceConfigGroups: function () {
@@ -800,10 +778,13 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
    */
   loadAdvancedConfigs: function (dependentController) {
     var self = this;
-    var counter = this.get('content.services').filterProperty('isSelected').length;
+    var stackServices = this.get('content.services').filter(function(service){
+      return service.get('isInstalled') || service.get('isSelected');
+    }).mapProperty('serviceName');
+    var counter = stackServices.length;
     var loadAdvancedConfigResult = [];
     dependentController.set('isAdvancedConfigLoaded', false);
-    this.get('content.services').filterProperty('isSelected').mapProperty('serviceName').forEach(function (_serviceName) {
+    stackServices.forEach(function (_serviceName) {
       App.config.loadAdvancedConfig(_serviceName, function (properties) {
         loadAdvancedConfigResult.pushObjects(properties);
         counter--;
@@ -857,18 +838,18 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       // check for configs that need to update for installed services
       if (stepController.get('installedServiceNames') && stepController.get('installedServiceNames').contains(_content.get('serviceName'))) {
         // get only modified configs
-        var configs = _content.get('configs').filterProperty('isNotDefaultValue').filter(function(config) {
+        var configs = _content.get('configs').filterProperty('isNotDefaultValue').filter(function (config) {
           var notAllowed = ['masterHost', 'masterHosts', 'slaveHosts', 'slaveHost'];
           return !notAllowed.contains(config.get('displayType'));
         });
         // if modified configs detected push all service's configs for update
         if (configs.length)
-          updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')));
+          updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName', _content.get('serviceName')));
         // watch for properties that are not modified but have to be updated
         if (_content.get('configs').someProperty('forceUpdate')) {
           // check for already added modified properties
           if (!updateServiceConfigProperties.findProperty('serviceName', _content.get('serviceName'))) {
-            updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')));
+            updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName', _content.get('serviceName')));
           }
         }
       }
@@ -923,7 +904,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     var components = this.get('slaveComponents');
     var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
-    var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName');
+    var selectedServices = App.StackService.find().filterProperty('isSelected', true).mapProperty('serviceName');
     var installedComponentsMap = {};
     var uninstalledComponents = [];
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step4_controller.js b/ambari-web/app/controllers/wizard/step4_controller.js
index 9b8acac..65213ff 100644
--- a/ambari-web/app/controllers/wizard/step4_controller.js
+++ b/ambari-web/app/controllers/wizard/step4_controller.js
@@ -42,7 +42,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @type {bool}
    */
   isAll: function () {
-    return this.filterProperty('canBeSelected', true).everyProperty('isSelected', true);
+    return this.everyProperty('isSelected', true);
   }.property('@each.isSelected'),
 
   /**
@@ -50,96 +50,15 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @type {bool}
    */
   isMinimum: function () {
-    return this.filterProperty('isDisabled', false).everyProperty('isSelected', false);
+    return this.everyProperty('isSelected', false);
   }.property('@each.isSelected'),
 
   /**
-   * submit checks describe dependency rules between services
-   * checkCallback - callback, which check for dependency
-   * popupParams - parameters for popup
-   * @type {{checkCallback: string, popupParams: Ember.Enumerable}[]}
-   */
-  submitChecks: [
-    {
-      checkCallback: 'needToAddMapReduce',
-      popupParams: [
-        {serviceName: 'MAPREDUCE', selected: true},
-        'mapreduceCheck'
-      ]
-    },
-    {
-      checkCallback: 'noDFSs',
-      popupParams: [
-        {serviceName: 'HDFS', selected: true},
-        'hdfsCheck'
-      ]
-    },
-    {
-      checkCallback: 'needToAddYarnMapReduce2',
-      popupParams: [
-        {serviceName: 'YARN', selected: true},
-        'yarnCheck'
-      ]
-    },
-    {
-      checkCallback: 'needToAddZooKeeper',
-      popupParams: [
-        {serviceName: 'ZOOKEEPER', selected: true},
-        'zooKeeperCheck'
-      ]
-    },
-    {
-      checkCallback: 'multipleDFSs',
-      popupParams: [
-        [
-          {serviceName: 'HDFS', selected: true},
-          {serviceName: 'GLUSTERFS', selected: false}
-        ],
-        'multipleDFS'
-      ]
-    },
-    {
-      checkCallback: 'needToAddOozie',
-      popupParams: [
-        {serviceName: 'OOZIE', selected: true},
-        'oozieCheck'
-      ]
-    },
-    {
-      checkCallback: 'needToAddTez',
-      popupParams: [
-        {serviceName: 'TEZ', selected: true},
-        'tezCheck'
-      ]
-    }
-  ],
-
-  /**
-   * Update hidden services. Make them to have the same status as master ones.
-   * @method checkDependencies
-   */
-  checkDependencies: function () {
-    var services = {};
-    this.forEach(function (service) {
-      services[service.get('serviceName')] = service;
-    });
-
-    // prevent against getting error when not all elements have been loaded yet
-    if (services['HBASE'] && services['ZOOKEEPER'] && services['HIVE'] && services['HCATALOG'] && services['WEBHCAT']) {
-      if (services['YARN'] && services['MAPREDUCE2']) {
-        services['MAPREDUCE2'].set('isSelected', services['YARN'].get('isSelected'));
-      }
-      services['HCATALOG'].set('isSelected', services['HIVE'].get('isSelected'));
-      services['WEBHCAT'].set('isSelected', services['HIVE'].get('isSelected'));
-    }
-  }.observes('@each.isSelected'),
-
-  /**
    * Onclick handler for <code>select all</code> link
    * @method selectAll
    */
   selectAll: function () {
-    this.filterProperty('canBeSelected', true).setEach('isSelected', true);
+    this.setEach('isSelected', true);
   },
 
   /**
@@ -147,76 +66,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method selectMinimum
    */
   selectMinimum: function () {
-    this.filterProperty('isDisabled', false).setEach('isSelected', false);
-  },
-
-  /**
-   * Check whether we should turn on <code>serviceName</code> service according to selected <code>dependentServices</code>
-   * @param serviceName checked service
-   * @param dependentServices list of dependent services
-   * @returns {bool}
-   * @method needAddService
-   */
-  needAddService: function (serviceName, dependentServices) {
-    if (!(dependentServices instanceof Array)) {
-      dependentServices = [dependentServices];
-    }
-    if (this.findProperty('serviceName', serviceName) && this.findProperty('serviceName', serviceName).get('isSelected') === false) {
-      var ds = this.filter(function (item) {
-        return dependentServices.contains(item.get('serviceName')) && item.get('isSelected');
-      });
-      return (ds.get('length') > 0);
-    }
-    return false;
-  },
-
-  /**
-   * Check whether we should turn on <code>Oozie</code> service
-   * @return {bool}
-   * @method needToAddOozie
-   */
-  needToAddOozie: function () {
-    return this.needAddService('OOZIE', ['FALCON']);
-  },
-
-  /**
-   * Check whether we should turn on <code>MapReduce</code> service
-   * @return {bool}
-   * @method needToAddMapReduce
-   */
-  needToAddMapReduce: function () {
-    return this.needAddService('MAPREDUCE', ['PIG', 'OOZIE', 'HIVE']);
-  },
-
-  /**
-   * Check whether we should turn on <code>MapReduce2</code> service
-   * @return {bool}
-   * @method needToAddYarnMapReduce2
-   */
-  needToAddYarnMapReduce2: function () {
-    return this.needAddService('YARN', ['PIG', 'OOZIE', 'HIVE', 'TEZ']);
-  },
-
-  /**
-   * Check whether we should turn on <code>Tez</code> service
-   * @return {bool}
-   * @method needToAddTez
-   */
-  needToAddTez: function () {
-    return this.needAddService('TEZ', ['YARN']);
-  },
-
-  /**
-   * Check whether we should turn on <code>ZooKeeper</code> service
-   * @return {bool}
-   * @method needToAddZooKeeper
-   */
-  needToAddZooKeeper: function () {
-    if (App.get('isHadoop2Stack')) {
-      return this.findProperty('serviceName', 'ZOOKEEPER') && this.findProperty('serviceName', 'ZOOKEEPER').get('isSelected') === false;
-    } else {
-      return this.needAddService('ZOOKEEPER', ['HBASE', 'HIVE', 'WEBHCAT', 'STORM']);
-    }
+    this.setEach('isSelected', false);
   },
 
   /**
@@ -225,8 +75,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method noDFSs
    */
   noDFSs: function () {
-    return (this.findProperty('serviceName', 'HDFS').get('isSelected') === false &&
-      (!this.findProperty('serviceName', 'GLUSTERFS') || this.findProperty('serviceName', 'GLUSTERFS').get('isSelected') === false));
+    return  !this.filterProperty('isDFS',true).someProperty('isSelected',true);
   },
 
   /**
@@ -235,8 +84,8 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method multipleDFSs
    */
   multipleDFSs: function () {
-    return (this.findProperty('serviceName', 'HDFS').get('isSelected') === true &&
-      (this.findProperty('serviceName', 'GLUSTERFS') && this.findProperty('serviceName', 'GLUSTERFS').get('isSelected') === true));
+    var dfsServices = this.filterProperty('isDFS',true).filterProperty('isSelected',true);
+	  return  dfsServices.length > 1;
   },
 
   /**
@@ -244,8 +93,9 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @return {bool}
    * @method gangliaOrNagiosNotSelected
    */
-  gangliaOrNagiosNotSelected: function () {
-    return (this.findProperty('serviceName', 'GANGLIA').get('isSelected') === false || this.findProperty('serviceName', 'NAGIOS').get('isSelected') === false);
+  isMonitoringServiceNotSelected: function () {
+    var stackMonitoringServices = this.filterProperty('isMonitoringService',true);
+    return stackMonitoringServices.someProperty('isSelected',false);
   },
 
   /**
@@ -253,8 +103,12 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method validateMonitoring
    */
   validateMonitoring: function () {
-    if (this.gangliaOrNagiosNotSelected()) {
-      this.monitoringCheckPopup();
+    var monitoringServices =  this.filterProperty('isMonitoringService',true);
+    var notSelectedService = monitoringServices.filterProperty('isSelected',false);
+    if (!!notSelectedService.length) {
+      notSelectedService = stringUtils.getFormattedStringFromArray(notSelectedService.mapProperty('displayNameOnSelectServicePage'));
+      monitoringServices = stringUtils.getFormattedStringFromArray(monitoringServices.mapProperty('displayNameOnSelectServicePage'));
+      this.monitoringCheckPopup(notSelectedService,monitoringServices);
     } else {
       App.router.send('next');
     }
@@ -265,22 +119,88 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method submit
    */
   submit: function () {
-    var submitChecks = this.get('submitChecks');
-    var doValidateMonitoring = true;
-    if (!this.get("isSubmitDisabled")) {
-      for (var i = 0; i < submitChecks.length; i++) {
-        if (this[submitChecks[i].checkCallback].call(this)) {
-          doValidateMonitoring = false;
-          this.needToAddServicePopup.apply(this, submitChecks[i].popupParams);
-          break;
+    this.setGroupedServices();
+    if (!this.get("isSubmitDisabled") && !this.isSubmitChecksFailed()) {
+      this.validateMonitoring();
+    }
+  },
+
+  /**
+   * @method  {isSubmitChecksFailed} Do the required checks on Next button click event
+   * @returns {boolean}
+   */
+  isSubmitChecksFailed: function() {
+    return this.isFileSystemCheckFailed() || this.isServiceDependencyCheckFailed();
+  },
+
+  /**
+   * @method: isFileSystemCheckFailed - Checks if a filesystem is selected and only one filesystem is selected
+   * @return: {boolean}
+   */
+  isFileSystemCheckFailed: function() {
+    var isCheckFailed = false;
+    var primaryDFS = this.findProperty('isPrimaryDFS',true);
+    var primaryDfsDisplayName = primaryDFS.get('displayNameOnSelectServicePage');
+    var primaryDfsServiceName = primaryDFS.get('serviceName');
+     if (this.noDFSs()) {
+       isCheckFailed = true;
+       this.needToAddServicePopup.apply(this, [{serviceName: primaryDfsServiceName, selected: true},'fsCheck',primaryDfsDisplayName]);
+     } else if (this.multipleDFSs()) {
+       var dfsServices = this.filterProperty('isDFS',true).filterProperty('isSelected',true).mapProperty('serviceName');
+       var services = dfsServices.map(function (item){
+         var mappedObj = {
+           serviceName: item,
+           selected: false
+         };
+         if (item ===  primaryDfsServiceName) {
+           mappedObj.selected = true;
+         }
+         return mappedObj;
+       });
+       isCheckFailed = true;
+       this.needToAddServicePopup.apply(this, [services,'multipleDFS',primaryDfsDisplayName]);
+     }
+    return isCheckFailed;
+  },
+
+  /**
+   * @method: isServiceDependencyCheckFailed - Checks if a dependent service is selected without selecting the main service
+   * @return {boolean}
+   */
+  isServiceDependencyCheckFailed: function() {
+    var isCheckFailed = false;
+    var notSelectedServices = this.filterProperty('isSelected',false);
+    notSelectedServices.forEach(function(service){
+      var showWarningPopup;
+      var dependentServices =  service.get('dependentServices');
+      if (!!dependentServices) {
+        showWarningPopup = false;
+        dependentServices.forEach(function(_dependentService){
+          var dependentService = this.findProperty('serviceName', _dependentService);
+          if (dependentService.get('isSelected') === true) {
+            showWarningPopup = true;
+            isCheckFailed = true;
+          }
+        },this);
+        if (showWarningPopup) {
+          this.needToAddServicePopup.apply(this, [{serviceName: service.get('serviceName'), selected: true},'serviceCheck',service.get('displayNameOnSelectServicePage')]);
         }
       }
-      if (doValidateMonitoring) {
-        this.validateMonitoring();
-      }
-    }
+    },this);
+    return isCheckFailed;
   },
 
+  setGroupedServices: function() {
+    this.forEach(function(service){
+      var coSelectedServices = service.get('coSelectedServices');
+      coSelectedServices.forEach(function(groupedServiceName) {
+        var groupedService = this.findProperty('serviceName', groupedServiceName);
+        groupedService.set('isSelected',service.get('isSelected'));
+      },this);
+    },this);
+  },
+
+
   /**
    * Select/deselect services
    * @param services array of objects
@@ -294,17 +214,19 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    *    ]
    *  </code>
    * @param {string} i18nSuffix
+   * @param {string} serviceName
    * @return {App.ModalPopup}
    * @method needToAddServicePopup
    */
-  needToAddServicePopup: function (services, i18nSuffix) {
+
+  needToAddServicePopup: function(services, i18nSuffix, serviceName) {
     if (!(services instanceof Array)) {
       services = [services];
     }
     var self = this;
     return App.ModalPopup.show({
-      header: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.header'),
-      body: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.body'),
+      header: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.header').format(serviceName),
+      body: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.body').format(serviceName),
       onPrimary: function () {
         services.forEach(function (service) {
           self.findProperty('serviceName', service.serviceName).set('isSelected', service.selected);
@@ -320,10 +242,10 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @return {App.ModalPopup}
    * @method monitoringCheckPopup
    */
-  monitoringCheckPopup: function () {
+  monitoringCheckPopup: function (notSelectedServiceNames,monitoringServicesNames) {
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step4.monitoringCheck.popup.header'),
-      body: Em.I18n.t('installer.step4.monitoringCheck.popup.body'),
+      body: Em.I18n.t('installer.step4.monitoringCheck.popup.body').format(notSelectedServiceNames,monitoringServicesNames),
       onPrimary: function () {
         this.hide();
         App.router.send('next');


[5/6] AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Posted by yu...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard/step5_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step5_controller.js b/ambari-web/app/controllers/wizard/step5_controller.js
index f004cb0..5ed0192 100644
--- a/ambari-web/app/controllers/wizard/step5_controller.js
+++ b/ambari-web/app/controllers/wizard/step5_controller.js
@@ -44,26 +44,28 @@ App.WizardStep5Controller = Em.Controller.extend({
   }.property('content.controllerName'),
 
   /**
-   * Is AddServiceWizard used
+   * Is isHighAvailabilityWizard used
    * @type {bool}
    */
-  isAddServiceWizard: function () {
-    return this.get('content.controllerName') == 'addServiceController';
+  isHighAvailabilityWizard: function () {
+    return this.get('content.controllerName') == 'highAvailabilityWizardController';
   }.property('content.controllerName'),
 
   /**
-   * Is Hive reassigning
+   * Is AddServiceWizard used
    * @type {bool}
    */
-  isReassignHive: function () {
-    return this.get('servicesMasters').objectAt(0) && this.get('servicesMasters').objectAt(0).component_name == 'HIVE_SERVER' && this.get('isReassignWizard');
-  }.property('isReassignWizard', 'servicesMasters'),
+  isAddServiceWizard: function () {
+    return this.get('content.controllerName') == 'addServiceController';
+  }.property('content.controllerName'),
 
   /**
    * Master components which could be assigned to multiple hosts
    * @type {string[]}
    */
-  multipleComponents: ['ZOOKEEPER_SERVER', 'HBASE_MASTER'],
+  multipleComponents: function () {
+    return App.get('components.addableMasterInstallerWizard');
+  }.property('App.components.addableMasterInstallerWizard'),
 
   /**
    * Define state for submit button
@@ -112,6 +114,7 @@ App.WizardStep5Controller = Em.Controller.extend({
    */
   selectedServicesMasters: [],
 
+
   /**
    * Is data for current step loaded
    * @type {bool}
@@ -119,14 +122,6 @@ App.WizardStep5Controller = Em.Controller.extend({
   isLoaded: false,
 
   /**
-   * Check if HIVE_SERVER component exist (also checks if this is not reassign)
-   * @type {bool}
-   */
-  hasHiveServer: function () {
-    return this.get('selectedServicesMasters').someProperty('component_name', 'HIVE_SERVER') && !this.get('isReassignWizard');
-  }.property('selectedServicesMasters'),
-
-  /**
    * List of host with assigned masters
    * Format:
    * <code>
@@ -198,6 +193,10 @@ App.WizardStep5Controller = Em.Controller.extend({
     this.set('hosts', []);
     this.set('selectedServicesMasters', []);
     this.set('servicesMasters', []);
+    App.StackServiceComponent.find().forEach(function (stackComponent) {
+      stackComponent.set('serviceComponentId', 1);
+    }, this);
+
   },
 
   /**
@@ -209,12 +208,9 @@ App.WizardStep5Controller = Em.Controller.extend({
     this.clearStep();
     this.renderHostInfo();
     this.renderComponents(this.loadComponents());
-
-    this.updateComponent('ZOOKEEPER_SERVER');
-    if (App.supports.multipleHBaseMasters) {
-      this.updateComponent('HBASE_MASTER');
-    }
-
+    this.get('multipleComponents').forEach(function (componentName) {
+      this.updateComponent(componentName);
+    }, this);
     if (!this.get("selectedServicesMasters").filterProperty('isInstalled', false).length) {
       console.log('no master components to add');
       App.router.send('next');
@@ -222,7 +218,7 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
 
   /**
-   * Used to set showAddControl flag for ZOOKEEPER_SERVER and HBASE_SERVER
+   * Used to set showAddControl flag for installer wizard
    * @method updateComponent
    */
   updateComponent: function (componentName) {
@@ -230,12 +226,12 @@ App.WizardStep5Controller = Em.Controller.extend({
     if (!component) {
       return;
     }
-    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName');
+    var services = App.StackService.find().filterProperty('isInstalled', true).mapProperty('serviceName');
     var currentService = componentName.split('_')[0];
     var showControl = !services.contains(currentService);
 
     if (showControl) {
-      if (this.get("selectedServicesMasters").filterProperty("component_name", componentName).length < this.get("hosts.length") && !this.get('isReassignWizard')) {
+      if (this.get("selectedServicesMasters").filterProperty("component_name", componentName).length < this.get("hosts.length") && !this.get('isReassignWizard') && !this.get('isHighAvailabilityWizard')) {
         component.set('showAddControl', true);
       } else {
         component.set('showRemoveControl', false);
@@ -289,11 +285,18 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @return {Object[]}
    */
   loadComponents: function () {
-
-    var services = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName'); //list of shown services
-    var selectedServices = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName');
-
-    var masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnInstallerAssignMasterPage', true); //get full list from mock data
+    var selectedServices = App.StackService.find().filterProperty('isSelected').mapProperty('serviceName');
+    var installedServices = App.StackService.find().filterProperty('isInstalled').mapProperty('serviceName');
+    var services = installedServices.concat(selectedServices).uniq();
+    var selectedNotInstalledServices = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName');
+
+    var masterComponents = [];
+    //get full list from mock data
+    if (this.get('isAddServiceWizard')) {
+      masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnAddServiceAssignMasterPage');
+    } else {
+      masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnInstallerAssignMasterPage');
+    }
     var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info
 
     var resultComponents = [];
@@ -303,7 +306,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       // If service is already installed and not being added as a new service then render on UI only those master components
       // that have already installed hostComponents.
       // NOTE: On upgrade there might be a prior installed service with non-installed newly introduced serviceComponent
-      var isNotSelectedService = !selectedServices.contains(services[index]);
+      var isNotSelectedService = !selectedNotInstalledServices.contains(services[index]);
       if (isNotSelectedService) {
         componentInfo = componentInfo.filter(function (_component) {
           return App.HostComponent.find().someProperty('componentName',_component.get('componentName'));
@@ -311,29 +314,29 @@ App.WizardStep5Controller = Em.Controller.extend({
       }
 
       componentInfo.forEach(function (_componentInfo) {
-        if (_componentInfo.get('componentName') == 'ZOOKEEPER_SERVER' || _componentInfo.get('componentName') == 'HBASE_MASTER') {
+        if (this.get('multipleComponents').contains(_componentInfo.get('componentName'))) {
           var savedComponents = masterHosts.filterProperty('component', _componentInfo.get('componentName'));
           if (savedComponents.length) {
             savedComponents.forEach(function (item) {
               var multipleMasterHost = {};
-              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.selectedHost = item.hostName;
               multipleMasterHost.serviceId = services[index];
               multipleMasterHost.isInstalled = item.isInstalled;
-              multipleMasterHost.isHiveCoHost = false;
+              multipleMasterHost.isServiceCoHost = false;
               resultComponents.push(multipleMasterHost);
             })
           } else {
-            var zooHosts = this.selectHost(_componentInfo.get('componentName'));
-            zooHosts.forEach(function (_host) {
+            var multipleMasterHosts = this.selectHost(_componentInfo.get('componentName'));
+            multipleMasterHosts.forEach(function (_host) {
               var multipleMasterHost = {};
-              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.selectedHost = _host;
               multipleMasterHost.serviceId = services[index];
               multipleMasterHost.isInstalled = false;
-              multipleMasterHost.isHiveCoHost = false;
+              multipleMasterHost.isServiceCoHost = false;
               resultComponents.push(multipleMasterHost);
             });
 
@@ -346,7 +349,7 @@ App.WizardStep5Controller = Em.Controller.extend({
           componentObj.selectedHost = savedComponent ? savedComponent.hostName : this.selectHost(_componentInfo.get('componentName'));   // call the method that plays selectNode algorithm or fetches from server
           componentObj.isInstalled = savedComponent ? savedComponent.isInstalled : false;
           componentObj.serviceId = services[index];
-          componentObj.isHiveCoHost = this._isHiveCoHost(_componentInfo.get('componentName'));
+          componentObj.isServiceCoHost = App.StackServiceComponent.find().findProperty('componentName', _componentInfo.get('componentName')).get('isCoHostedComponent') && !this.get('isReassignWizard');
           resultComponents.push(componentObj);
         }
       }, this);
@@ -356,6 +359,8 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
 
   /**
+<<<<<<< HEAD
+=======
    * @param {string} componentName
    * @returns {bool}
    * @private
@@ -366,73 +371,58 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
 
   /**
+>>>>>>> apache-ref/trunk
    * Put master components to <code>selectedServicesMasters</code>, which will be automatically rendered in template
    * @param {Ember.Enumerable} masterComponents
    * @method renderComponents
    */
   renderComponents: function (masterComponents) {
-    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
-    var showRemoveControlZk = !services.contains('ZOOKEEPER') && masterComponents.filterProperty('component_name', 'ZOOKEEPER_SERVER').length > 1;
-    var showRemoveControlHb = !services.contains('HBASE') && masterComponents.filterProperty('component_name', 'HBASE_MASTER').length > 1;
-    var zid = 1, hid = 1, nid = 1, result = [], self = this;
+    var installedServices = App.StackService.find().filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName'); //list of shown services
+    var result = [];
+    var serviceComponentId, previousComponentName;
 
     masterComponents.forEach(function (item) {
-
-      if (item.component_name == 'SECONDARY_NAMENODE') {
-        if (self.get('isAddServiceWizard')) {
-          if (App.get('isHaEnabled')) {
-            return;
-          }
-        }
-      }
-
+      var serviceComponent = App.StackServiceComponent.find().findProperty('componentName', item.component_name);
+      var showRemoveControl = installedServices.contains(serviceComponent.get('stackService.serviceName')) &&
+        (masterComponents.filterProperty('component_name', item.component_name).length > 1);
       var componentObj = Em.Object.create(item);
       console.log("TRACE: render master component name is: " + item.component_name);
-
-      if (item.component_name === "ZOOKEEPER_SERVER") {
-        componentObj.set('zId', zid++);
-        componentObj.set("showRemoveControl", showRemoveControlZk);
-      }
-      else {
-        if (App.get('supports.multipleHBaseMasters') && item.component_name === "HBASE_MASTER") {
-          componentObj.set('zId', hid++);
-          componentObj.set("showRemoveControl", showRemoveControlHb);
-        }
-        else {
-          if (item.component_name === "NAMENODE") {
-            componentObj.set('zId', nid++);
-          }
-        }
+      var masterComponent = App.StackServiceComponent.find().findProperty('componentName', item.component_name);
+      if (masterComponent.get('isMasterWithMultipleInstances')) {
+        if (item.component_name !== previousComponentName) serviceComponentId = 1;
+        previousComponentName = item.component_name;
+        componentObj.set('serviceComponentId', serviceComponentId++);
+        componentObj.set("showRemoveControl", showRemoveControl);
       }
       componentObj.set('isHostNameValid', true);
       result.push(componentObj);
     }, this);
-
     this.set("selectedServicesMasters", result);
     if (this.get('isReassignWizard')) {
       var components = result.filterProperty('component_name', this.get('content.reassign.component_name'));
       components.setEach('isInstalled', false);
       this.set('servicesMasters', components);
-    }
-    else {
+    } else {
       this.set('servicesMasters', result);
     }
   },
 
   /**
-   * Update host for components HIVE_METASTORE and WEBHCAT_SERVER according to host with HIVE_SERVER
-   * @method updateHiveCoHosts
+   * Update dependent co-hosted components according to the change in the component host
+   * @method updateCoHosts
    */
-  updateHiveCoHosts: function () {
-    var hiveServer = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER'),
-      hiveMetastore = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE'),
-      webHCatServer = this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER');
-    if (hiveServer && hiveMetastore && webHCatServer) {
-      if (!this.get('isReassignHive') && this.get('servicesMasters').objectAt(0) && !(this.get('servicesMasters').objectAt(0).component_name == 'HIVE_METASTORE')) {
-        hiveMetastore.set('selectedHost', hiveServer.get('selectedHost'))
-      }
-      webHCatServer.set('selectedHost', hiveServer.get('selectedHost'));
-    }
+  updateCoHosts: function () {
+    var components = App.StackServiceComponent.find().filterProperty('isOtherComponentCoHosted');
+    var selectedServicesMasters = this.get('selectedServicesMasters');
+    components.forEach(function (component) {
+      var componentName = component.get('componentName');
+      var hostComponent = selectedServicesMasters.findProperty('component_name', componentName);
+      var dependentCoHosts = component.get('coHostedComponents');
+      dependentCoHosts.forEach(function (coHostedComponent) {
+        var dependentHostComponent = selectedServicesMasters.findProperty('component_name', coHostedComponent);
+        if (hostComponent && dependentHostComponent) dependentHostComponent.set('selectedHost', hostComponent.get('selectedHost'));
+      }, this);
+    }, this);
   }.observes('selectedServicesMasters.@each.selectedHost'),
 
   /**
@@ -441,19 +431,25 @@ App.WizardStep5Controller = Em.Controller.extend({
    * if key more that number of hosts, then return value of that key.
    * Value is index of host in hosts array.
    *
-   * @param {number} noOfHosts
-   * @param {object} selectionScheme
+   * @param {object} componentName
+   * @param {object} hosts
    * @return {string}
    * @method getHostForComponent
    */
-  getHostForComponent: function (noOfHosts, selectionScheme) {
-    var hosts = this.get('hosts');
+  getHostForComponent: function (componentName, hosts) {
+    var component = App.StackServiceComponent.find().findProperty('componentName', componentName);
+    if (component) {
+      var selectionScheme = App.StackServiceComponent.find().findProperty('componentName', componentName).get('selectionSchemeForMasterComponent');
+    } else {
+      return hosts[0];
+    }
+
     if (hosts.length === 1 || $.isEmptyObject(selectionScheme)) {
       return hosts[0];
     } else {
       for (var i in selectionScheme) {
         if (window.isFinite(i)) {
-          if (noOfHosts < window.parseInt(i)) {
+          if (hosts.length < window.parseInt(i)) {
             return hosts[selectionScheme[i]];
           }
         }
@@ -463,34 +459,22 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
 
   /**
-   * Get list of hostnames for ZK Server
-   * @param {number} noOfHosts
+   * Get list of host names for master component with multiple instances
+   * @param {Object} component
+   * @param {Object} hosts
    * @returns {string[]}
-   * @method getZooKeeperServer
+   * @method getHostsForComponent
    */
-  getZooKeeperServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts < 3) {
-      return [hosts[0].host_name];
-    } else {
-      return [hosts[0].host_name, hosts[1].host_name, hosts[2].host_name];
+  getHostsForComponent: function (component, hosts) {
+    var defaultNoOfMasterHosts = component.get('defaultNoOfMasterHosts');
+    var masterHosts = [];
+    if (hosts.length < defaultNoOfMasterHosts) {
+      defaultNoOfMasterHosts = hosts.length;
     }
-  },
-
-  /**
-   * Get hostname based on number of available hosts
-   * @param {number} noOfHosts
-   * @returns {string}
-   * @method getServerHost
-   */
-  getServerHost: function (noOfHosts) {
-    var hostNames = this.get('hosts').mapProperty('host_name');
-    var hostExcAmbari = hostNames.without(location.hostname);
-    if (noOfHosts > 1) {
-      return hostExcAmbari[0];
-    } else {
-      return hostNames[0];
+    for (var index = 0; index < defaultNoOfMasterHosts; index++) {
+      masterHosts.push(hosts[index]);
     }
+    return masterHosts;
   },
 
   /**
@@ -500,50 +484,36 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @method selectHost
    */
   selectHost: function (componentName) {
-    var noOfHosts = this.get('hosts').length;
-
-    if (componentName === 'KERBEROS_SERVER')
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 3, "else": 5}).host_name;
-
-    if (componentName === 'NAMENODE')
-      return this.getHostForComponent(noOfHosts, {"else": 0}).host_name;
-
-    if (componentName === 'SECONDARY_NAMENODE')
-      return this.getHostForComponent(noOfHosts, {"else": 1}).host_name;
-
-    if (componentName === 'HBASE_MASTER')
-      return [this.getHostForComponent(noOfHosts, {"3": 0, "6": 0, "31": 2, "else": 3}).host_name];
-
-    if (componentName === 'ZOOKEEPER_SERVER')
-      return this.getZooKeeperServer(noOfHosts);
-
-    if (['JOBTRACKER', 'HISTORYSERVER', 'RESOURCEMANAGER', 'APP_TIMELINE_SERVER'].contains(componentName))
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 1, "else": 2}).host_name;
-
-    if (['OOZIE_SERVER', 'FALCON_SERVER'].contains(componentName))
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 2, "else": 3}).host_name;
-
-    if (['HIVE_SERVER', 'HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(componentName))
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 2, "else": 4}).host_name;
-
-    if (['STORM_UI_SERVER', 'DRPC_SERVER', 'STORM_REST_API', 'NIMBUS', 'GANGLIA_SERVER', 'NAGIOS_SERVER', 'HUE_SERVER'].contains(componentName))
-      return this.getServerHost(noOfHosts);
-
-    return '';
+    var component = App.StackServiceComponent.find().findProperty('componentName', componentName);
+    var hostNames = this.get('hosts').mapProperty('host_name');
+    if (hostNames.length > 1 && App.StackServiceComponent.find().filterProperty('isNotPreferableOnAmbariServerHost').mapProperty('componentName').contains(componentName)) {
+      hostNames = this.get('hosts').mapProperty('host_name').filter(function (item) {
+        return item !== location.hostname;
+      }, this);
+    }
+    if (this.get('multipleComponents').contains(componentName)) {
+      if (component.get('defaultNoOfMasterHosts') > 1) {
+        return this.getHostsForComponent(component, hostNames);
+      } else {
+        return [this.getHostForComponent(componentName, hostNames)];
+      }
+    } else {
+      return this.getHostForComponent(componentName, hostNames);
+    }
   },
 
   /**
    * On change callback for inputs
    * @param {string} componentName
    * @param {string} selectedHost
-   * @param {number} zId
+   * @param {number} serviceComponentId
    * @method assignHostToMaster
    */
-  assignHostToMaster: function (componentName, selectedHost, zId) {
+  assignHostToMaster: function (componentName, selectedHost, serviceComponentId) {
     var flag = this.isHostNameValid(componentName, selectedHost);
-    this.updateIsHostNameValidFlag(componentName, zId, flag);
+    this.updateIsHostNameValidFlag(componentName, serviceComponentId, flag);
     if (zId) {
-      this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("selectedHost", selectedHost);
+      this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("serviceComponentId", serviceComponentId).set("selectedHost", selectedHost);
     }
     else {
       this.get('selectedServicesMasters').findProperty("component_name", componentName).set("selectedHost", selectedHost);
@@ -582,10 +552,10 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @param {bool} flag
    * @method updateIsHostNameValidFlag
    */
-  updateIsHostNameValidFlag: function (componentName, zId, flag) {
+  updateIsHostNameValidFlag: function (componentName, serviceComponentId, flag) {
     if (componentName) {
-      if (zId) {
-        this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("isHostNameValid", flag);
+      if (serviceComponentId) {
+        this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("serviceComponentId", serviceComponentId).set("isHostNameValid", flag);
       } else {
         this.get('selectedServicesMasters').findProperty("component_name", componentName).set("isHostNameValid", flag);
       }
@@ -633,7 +603,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       currentMasters.set("lastObject.showAddControl", false);
       currentMasters.set("lastObject.showRemoveControl", true);
 
-      //create a new zookeeper based on an existing one
+      //create a new master component host based on an existing one
       newMaster = Em.Object.create({});
       lastMaster = currentMasters.get("lastObject");
       newMaster.set("display_name", lastMaster.get("display_name"));
@@ -659,7 +629,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       }
 
       newMaster.set("selectedHost", suggestedHost);
-      newMaster.set("zId", (currentMasters.get("lastObject.zId") + 1));
+      newMaster.set("serviceComponentId", (currentMasters.get("lastObject.serviceComponentId") + 1));
 
       this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastMaster) + 1, newMaster);
 
@@ -674,19 +644,19 @@ App.WizardStep5Controller = Em.Controller.extend({
   /**
    * Remove component from ZooKeeper server or Hbase Master
    * @param {string} componentName
-   * @param {number} zId
+   * @param {number} serviceComponentId
    * @return {bool} true - removed, false - no
    * @method removeComponent
    */
-  removeComponent: function (componentName, zId) {
+  removeComponent: function (componentName, serviceComponentId) {
     var currentMasters = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
 
-    //work only if the Zookeeper service is selected in previous step
+    //work only if the multiple master service is selected in previous step
     if (currentMasters.length <= 1) {
       return false;
     }
 
-    this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(currentMasters.findProperty("zId", zId)));
+    this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(currentMasters.findProperty("serviceComponentId", serviceComponentId)));
 
     currentMasters = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
     if (currentMasters.get("length") < this.get("hosts.length")) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard/step6_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step6_controller.js b/ambari-web/app/controllers/wizard/step6_controller.js
index 85800fb..b8309a9 100644
--- a/ambari-web/app/controllers/wizard/step6_controller.js
+++ b/ambari-web/app/controllers/wizard/step6_controller.js
@@ -52,13 +52,6 @@ App.WizardStep6Controller = Em.Controller.extend({
   headers: [],
 
   /**
-   * true - assign ZK, HB
-   * false - slaves and clients
-   * @type {bool}
-   */
-  isMasters: false,
-
-  /**
    * @type {bool}
    */
   isLoaded: false,
@@ -80,7 +73,7 @@ App.WizardStep6Controller = Em.Controller.extend({
   }.property('content.controllerName'),
 
   /**
-   * Check if <code>addHerviceWizard</code> used
+   * Check if <code>addServiceWizard</code> used
    * @type {bool}
    */
   isAddServiceWizard: function () {
@@ -118,21 +111,16 @@ App.WizardStep6Controller = Em.Controller.extend({
     }
 
     if (this.get('isAddHostWizard')) {
-      if (this.get('isMasters')) {
-        this.set('errorMessage', '');
-      }
-      else {
-        hosts.forEach(function (host) {
-          isError = false;
-          headers.forEach(function (header) {
-            isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
-          });
-          isError = !isError;
-          if (!isError) {
-            self.set('errorMessage', '');
-          }
+      hosts.forEach(function (host) {
+        isError = false;
+        headers.forEach(function (header) {
+          isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
         });
-      }
+        isError = !isError;
+        if (!isError) {
+          self.set('errorMessage', '');
+        }
+      });
     }
   },
 
@@ -195,8 +183,11 @@ App.WizardStep6Controller = Em.Controller.extend({
    * @method isServiceSelected
    */
   isServiceSelected: function (name) {
-    return !!(this.get('content.services').findProperty('serviceName', name) &&
-      this.get('content.services').findProperty('serviceName', name).get('isSelected'));
+    var serviceName = this.get('content.services').findProperty('serviceName', name);
+    if (!serviceName) {
+      return !!serviceName;
+    }
+    return serviceName.get('isSelected') || serviceName.get('isInstalled');
   },
 
   /**
@@ -226,16 +217,6 @@ App.WizardStep6Controller = Em.Controller.extend({
   },
 
   /**
-   * Get <code>displayName</code> for component by <code>componentName</code>
-   * @param componentName
-   * @returns {string}
-   * @method getComponentDisplayName
-   */
-  getComponentDisplayName: function (componentName) {
-    return App.StackServiceComponent.find().findProperty('componentName', componentName).get('displayName');
-  },
-
-  /**
    * Init step6 data
    * @method loadStep
    */
@@ -245,82 +226,39 @@ App.WizardStep6Controller = Em.Controller.extend({
 
     console.log("WizardStep6Controller: Loading step6: Assign Slaves");
     this.clearStep();
+    var selectedServices = App.StackService.find().filterProperty('isSelected');
+    var installedServices = App.StackService.find().filterProperty('isInstalled');
+    var services;
+    if (this.get('isInstallerWizard')) services = selectedServices;
+    else if (this.get('isAddHostWizard')) services = installedServices;
+    else if (this.get('isAddServiceWizard')) services = installedServices.concat(selectedServices);
 
     var headers = Em.A([]);
+    services.forEach(function (stackService) {
+      stackService.get('serviceComponents').forEach(function (serviceComponent) {
+        if (serviceComponent.get('isShownOnInstallerSlaveClientPage')) {
+          headers.pushObject(Em.Object.create({
+            name: serviceComponent.get('componentName'),
+            label: serviceComponent.get('displayName'),
+            allChecked: false,
+            noChecked: true
+          }));
+        }
+      }, this);
+    }, this);
 
-    if (this.get('isMasters')) {
-      if (this.isServiceSelected('HBASE') && App.supports.multipleHBaseMasters) {
-        headers.pushObject(Em.Object.create({
-          name: 'HBASE_MASTER',
-          label: self.getComponentDisplayName('HBASE_MASTER')
-        }));
-      }
-      if (this.isServiceSelected('ZOOKEEPER')) {
-        headers.pushObject(Em.Object.create({
-          name: 'ZOOKEEPER_SERVER',
-          label: self.getComponentDisplayName('ZOOKEEPER_SERVER')
-        }));
-      }
-    }
-    else {
-      if (this.isServiceSelected('HDFS')) {
-        headers.pushObject(Em.Object.create({
-          name: 'DATANODE',
-          label: self.getComponentDisplayName('DATANODE')
-        }));
-      }
-      if (this.isServiceSelected('MAPREDUCE')) {
-        headers.pushObject(Em.Object.create({
-          name: 'TASKTRACKER',
-          label: self.getComponentDisplayName('TASKTRACKER')
-        }));
-      }
-      if (this.isServiceSelected('YARN')) {
-        headers.pushObject(Em.Object.create({
-          name: 'NODEMANAGER',
-          label: self.getComponentDisplayName('NODEMANAGER')
-        }));
-      }
-      if (this.isServiceSelected('HBASE')) {
-        headers.pushObject(Em.Object.create({
-          name: 'HBASE_REGIONSERVER',
-          label: self.getComponentDisplayName('HBASE_REGIONSERVER')
-        }));
-      }
-      if (this.isServiceSelected('STORM')) {
-        headers.pushObject(Em.Object.create({
-          name: 'SUPERVISOR',
-          label: self.getComponentDisplayName('SUPERVISOR')
-        }));
-      }
-      if (this.isServiceSelected('FLUME')) {
-        headers.pushObject(Em.Object.create({
-          name: 'FLUME_HANDLER',
-          label: self.getComponentDisplayName('FLUME_HANDLER')
-        }));
-      }
-      headers.pushObject(Em.Object.create({
-        name: 'CLIENT',
-        label: App.format.role('CLIENT')
-      }));
-    }
-
-    headers.forEach(function (header) {
-      header.setProperties({ allChecked: false, noChecked: true });
-    });
+    headers.pushObject(Em.Object.create({
+      name: 'CLIENT',
+      label: App.format.role('CLIENT'),
+      allChecked: false,
+      noChecked: true
+    }));
 
     this.get('headers').pushObjects(headers);
 
     this.render();
-    if (this.get('isMasters')) {
-      if (this.get('content.skipMasterStep')) {
-        App.router.send('next');
-      }
-    }
-    else {
-      if (this.get('content.skipSlavesStep')) {
-        App.router.send('next');
-      }
+    if (this.get('content.skipSlavesStep')) {
+      App.router.send('next');
     }
   },
 
@@ -383,13 +321,7 @@ App.WizardStep6Controller = Em.Controller.extend({
     });
     //hosts with master components should be in the beginning of list
     hostsObj.unshift.apply(hostsObj, masterHosts);
-
-    if (this.get('isMasters')) {
-      hostsObj = this.selectMasterComponents(hostsObj);
-    } else {
-      hostsObj = this.renderSlaves(hostsObj);
-    }
-
+    hostsObj = this.renderSlaves(hostsObj);
     this.set('hosts', hostsObj);
     headers.forEach(function (header) {
       this.checkCallback(header.get('name'));
@@ -404,7 +336,6 @@ App.WizardStep6Controller = Em.Controller.extend({
    * @method renderSlaves
    */
   renderSlaves: function (hostsObj) {
-    var self = this;
     var headers = this.get('headers');
     var slaveComponents = this.get('content.slaveComponentHosts');
     if (!slaveComponents) { // we are at this page for the first time
@@ -416,9 +347,11 @@ App.WizardStep6Controller = Em.Controller.extend({
         checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', false);
         // First not Master should have Client (only first!)
         if (!client_is_set) {
-          if (self.isServiceSelected("HDFS")) {
-            var checkboxDatanode = checkboxes.findProperty('title', headers.findProperty('name', 'DATANODE').get('label'));
-            if (checkboxDatanode && checkboxDatanode.get('checked')) {
+          var dfs = App.StackService.find().findProperty('isPrimaryDFS');
+          if (dfs.get('isSelected') || dfs.get('isInstalled')) {
+            var checkboxServiceComponent = checkboxes.findProperty('title', headers.findProperty('name', dfs.get('serviceComponents').
+              findProperty('isShownOnInstallerSlaveClientPage').get('componentName')).get('label'));
+            if (checkboxServiceComponent && checkboxServiceComponent.get('checked')) {
               checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', true);
               client_is_set = true;
             }
@@ -430,8 +363,7 @@ App.WizardStep6Controller = Em.Controller.extend({
         var lastHost = hostsObj[hostsObj.length - 1];
         lastHost.get('checkboxes').setEach('checked', true);
       }
-    }
-    else {
+    } else {
       this.get('headers').forEach(function (header) {
         var nodes = slaveComponents.findProperty('componentName', header.get('name'));
         if (nodes) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/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 d59c1fd..6dcbdae 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -43,8 +43,6 @@ App.WizardStep7Controller = Em.Controller.extend({
 
   slaveHostToGroup: null,
 
-  secureConfigs: require('data/secure_mapping'),
-
   /**
    * If miscConfigChange Modal is shown
    * @type {bool}
@@ -131,7 +129,9 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @type {string[]}
    */
   allSelectedServiceNames: function () {
-    return this.get('content.services').filterProperty('isSelected').mapProperty('serviceName');
+    return this.get('content.services').filter(function (service) {
+      return service.get('isInstalled') || service.get('isSelected');
+    }).mapProperty('serviceName');
   }.property('content.services').cacheable(),
 
   /**
@@ -142,7 +142,9 @@ App.WizardStep7Controller = Em.Controller.extend({
   installedServiceNames: function () {
     var serviceNames = this.get('content.services').filterProperty('isInstalled').mapProperty('serviceName');
     if (this.get('content.controllerName') !== 'installerController') {
-      return serviceNames.without('SQOOP').without('HCATALOG');
+      serviceNames = serviceNames.filter(function(_serviceName){
+        return !App.get('services.noConfigTypes').concat('HCATALOG').contains(_serviceName);
+      });
     }
     return serviceNames;
   }.property('content.services').cacheable(),
@@ -260,7 +262,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     var serviceName = params.serviceName,
       service = this.get('stepConfigs').findProperty('serviceName', serviceName),
       defaultConfigGroupHosts = this.get('wizardController.allHosts').mapProperty('hostName'),
-      siteToTagMap = this._createSiteToTagMap(data.Clusters.desired_configs, params.serviceConfigsDef.sites),
+      siteToTagMap = this._createSiteToTagMap(data.Clusters.desired_configs, params.serviceConfigsDef.get('configTypes')),
       selectedConfigGroup;
 
     this.set('loadedClusterSiteToTagMap', siteToTagMap);
@@ -362,11 +364,11 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @method _getRecommendedDefaultsForComponent
    */
   _getRecommendedDefaultsForComponent: function (serviceName) {
-    var s = this.get('serviceConfigsData').findProperty('serviceName', serviceName),
+    var s = App.StackService.find(serviceName),
       recommendedDefaults = {},
       localDB = this.getInfoForDefaults();
-    if (s.defaultsProviders) {
-      s.defaultsProviders.forEach(function (defaultsProvider) {
+    if (s.get('defaultsProvider')) {
+      s.get('defaultsProvider').forEach(function (defaultsProvider) {
         var d = defaultsProvider.getDefaults(localDB);
         for (var name in d) {
           if (d.hasOwnProperty(name)) {
@@ -384,7 +386,7 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @slaveComponentHosts - contains slaves and clients as well
    * @returns {{masterComponentHosts: Array, slaveComponentHosts: Array, hosts: {}}}
    */
-  getInfoForDefaults: function() {
+  getInfoForDefaults: function () {
     var slaveComponentHosts = [];
     var hosts = this.get('content.hosts');
     var slaveHostMap = {};
@@ -407,7 +409,7 @@ App.WizardStep7Controller = Em.Controller.extend({
 
     //push slaves and clients into @slaveComponentHosts
     for (var componentName in slaveHostMap) {
-      if(slaveHostMap[componentName].length > 0) {
+      if (slaveHostMap[componentName].length > 0) {
         slaveComponentHosts.push({
           componentName: componentName,
           hosts: slaveHostMap[componentName]
@@ -415,7 +417,7 @@ App.WizardStep7Controller = Em.Controller.extend({
       }
     }
 
-    var masterComponentHosts = App.HostComponent.find().filterProperty('isMaster', true).map(function(item) {
+    var masterComponentHosts = App.HostComponent.find().filterProperty('isMaster', true).map(function (item) {
       return {
         component: item.get('componentName'),
         serviceId: item.get('service.serviceName'),
@@ -531,12 +533,12 @@ App.WizardStep7Controller = Em.Controller.extend({
    */
   _updateValidatorsForConfig: function (serviceConfigProperty, component, serviceConfigsData) {
     if (serviceConfigProperty.get('serviceName') === component.get('serviceName')) {
-      if (serviceConfigsData.configsValidator) {
-        var validators = serviceConfigsData.configsValidator.get('configValidators');
+      if (serviceConfigsData.get('configsValidator')) {
+        var validators = serviceConfigsData.get('configsValidator').get('configValidators');
         for (var validatorName in validators) {
           if (validators.hasOwnProperty(validatorName)) {
             if (serviceConfigProperty.get('name') == validatorName) {
-              serviceConfigProperty.set('serviceValidator', serviceConfigsData.configsValidator);
+              serviceConfigProperty.set('serviceValidator', serviceConfigsData.get('configsValidator'));
             }
           }
         }
@@ -556,12 +558,12 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @method loadComponentConfigs
    */
   loadComponentConfigs: function (configs, componentConfig, component) {
-    var s = this.get('serviceConfigsData').findProperty('serviceName', component.get('serviceName')),
+    var s = App.StackService.find(component.get('serviceName')),
       defaultGroupSelected = component.get('selectedConfigGroup.isDefault');
 
-    if (s.configsValidator) {
+    if (s && s.get('configsValidator')) {
       var recommendedDefaults = this._getRecommendedDefaultsForComponent(component.get('serviceName'));
-      s.configsValidator.set('recommendedDefaults', recommendedDefaults);
+      s.get('configsValidator').set('recommendedDefaults', recommendedDefaults);
     }
 
     configs.forEach(function (serviceConfigProperty) {
@@ -640,6 +642,9 @@ App.WizardStep7Controller = Em.Controller.extend({
       return;
     }
     this.clearStep();
+    App.config.setPreDefinedGlobalProperties();
+    App.config.setPreDefinedServiceConfigs();
+
     //STEP 1: Load advanced configs
     var advancedConfigs = this.get('content.advancedServiceConfig');
     //STEP 2: Load on-site configs by service from local DB
@@ -718,7 +723,7 @@ App.WizardStep7Controller = Em.Controller.extend({
       // Remove SNameNode if HA is enabled
       if (App.get('isHaEnabled')) {
         var c = serviceConfigs.findProperty('serviceName', 'HDFS').configs;
-        var removedConfigs = c.filterProperty('category', 'SNameNode');
+        var removedConfigs = c.filterProperty('category', 'SECONDARY_NAMENODE');
         removedConfigs.map(function (config) {
           c = c.without(config);
         });
@@ -765,10 +770,8 @@ App.WizardStep7Controller = Em.Controller.extend({
    */
   getConfigTagsSuccess: function (data) {
     var installedServiceSites = [];
-    this.get('serviceConfigsData').filter(function (service) {
-      if (this.get('installedServiceNames').contains(service.serviceName)) {
-        installedServiceSites = installedServiceSites.concat(service.sites);
-      }
+    App.StackService.find().filterProperty('isSelected').filter(function (service) {
+      installedServiceSites = installedServiceSites.concat(service.get('configTypes'));
     }, this);
     installedServiceSites = installedServiceSites.uniq();
     var serviceConfigTags = [];
@@ -1044,10 +1047,10 @@ App.WizardStep7Controller = Em.Controller.extend({
   },
 
   /**
-    * Check whether hive New MySQL database is on the same host as Ambari server MySQL server
-    * @return {$.ajax|null}
-    * @method checkMySQLHost
-    */
+   * Check whether hive New MySQL database is on the same host as Ambari server MySQL server
+   * @return {$.ajax|null}
+   * @method checkMySQLHost
+   */
   checkMySQLHost: function () {
     // get ambari database type and hostname
     return App.ajax.send({
@@ -1081,7 +1084,7 @@ App.WizardStep7Controller = Em.Controller.extend({
    *
    * @method resolveHiveMysqlDatabase
    **/
-  resolveHiveMysqlDatabase: function() {
+  resolveHiveMysqlDatabase: function () {
     var hiveService = this.get('content.services').findProperty('serviceName', 'HIVE');
     if (!hiveService || !hiveService.get('isSelected') || hiveService.get('isInstalled')) {
       this.moveNext();
@@ -1089,7 +1092,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     }
     var hiveDBType = this.get('stepConfigs').findProperty('serviceName', 'HIVE').configs.findProperty('name', 'hive_database').value;
     if (hiveDBType == 'New MySQL Database') {
-      var self= this;
+      var self = this;
       this.checkMySQLHost().done(function () {
         if (self.get('mySQLServerConflict')) {
           // error popup before you can proceed
@@ -1100,14 +1103,14 @@ App.WizardStep7Controller = Em.Controller.extend({
             }),
             secondary: Em.I18n.t('installer.step7.popup.mySQLWarning.button.gotostep5'),
             primary: Em.I18n.t('installer.step7.popup.mySQLWarning.button.dismiss'),
-            onSecondary: function (){
+            onSecondary: function () {
               var parent = this;
               return App.ModalPopup.show({
                 header: Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.header'),
                 bodyClass: Ember.View.extend({
-                  template: Ember.Handlebars.compile( Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.body'))
+                  template: Ember.Handlebars.compile(Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.body'))
                 }),
-                onPrimary: function (){
+                onPrimary: function () {
                   this.hide();
                   parent.hide();
                   // go back to step 5: assign masters and disable default navigation warning
@@ -1125,7 +1128,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     }
   },
 
-  checkDatabaseConnectionTest: function() {
+  checkDatabaseConnectionTest: function () {
     var deferred = $.Deferred();
     if (!App.supports.databaseConnection) {
       deferred.resolve();
@@ -1141,7 +1144,7 @@ App.WizardStep7Controller = Em.Controller.extend({
         ignored: Em.I18n.t('installer.step7.hive.database.new')
       }
     ];
-    configMap.forEach(function(config) {
+    configMap.forEach(function (config) {
       var isConnectionNotTested = false;
       var service = this.get('content.services').findProperty('serviceName', config.serviceName);
       if (service && service.get('isSelected') && !service.get('isInstalled')) {
@@ -1163,8 +1166,8 @@ App.WizardStep7Controller = Em.Controller.extend({
     }, this);
     var ignoredServices = configMap.filterProperty('isCheckIgnored', true);
     if (ignoredServices.length) {
-      var displayedServiceNames = ignoredServices.mapProperty('serviceName').map(function(serviceName) {
-        return App.Service.DisplayNames[serviceName];
+      var displayedServiceNames = ignoredServices.mapProperty('serviceName').map(function (serviceName) {
+        return this.get('content.services').findProperty('serviceName', serviceName).get('displayName');
       }, this);
       this.showDatabaseConnectionWarningPopup(displayedServiceNames, deferred);
     }
@@ -1174,17 +1177,17 @@ App.WizardStep7Controller = Em.Controller.extend({
     return deferred;
   },
 
-  showDatabaseConnectionWarningPopup: function(serviceNames, deferred) {
+  showDatabaseConnectionWarningPopup: function (serviceNames, deferred) {
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step7.popup.database.connection.header'),
       body: Em.I18n.t('installer.step7.popup.database.connection.body').format(serviceNames.join(', ')),
       secondary: Em.I18n.t('common.cancel'),
       primary: Em.I18n.t('common.proceedAnyway'),
-      onPrimary: function() {
+      onPrimary: function () {
         deferred.resolve();
         this._super();
       },
-      onSecondary: function() {
+      onSecondary: function () {
         deferred.reject();
         this._super();
       }
@@ -1193,7 +1196,7 @@ App.WizardStep7Controller = Em.Controller.extend({
   /**
    * Proceed to the next step
    **/
-  moveNext: function() {
+  moveNext: function () {
     App.router.send('next');
   },
 
@@ -1204,7 +1207,7 @@ App.WizardStep7Controller = Em.Controller.extend({
   submit: function () {
     var _this = this;
     if (!this.get('isSubmitDisabled')) {
-      this.checkDatabaseConnectionTest().done(function() {
+      this.checkDatabaseConnectionTest().done(function () {
         _this.resolveHiveMysqlDatabase();
       });
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index fb0be3b..3163531 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -27,7 +27,28 @@ App.WizardStep8Controller = Em.Controller.extend({
    * List of raw data about cluster that should be displayed
    * @type {Array}
    */
-  rawContent: require('data/review_configs'),
+  rawContent: [
+    {
+      config_name: 'Admin',
+      display_name: 'Admin Name',
+      config_value: ''
+    },
+    {
+      config_name: 'cluster',
+      display_name: 'Cluster Name',
+      config_value: ''
+    },
+    {
+      config_name: 'hosts',
+      display_name: 'Total Hosts',
+      config_value: ''
+    },
+    {
+      config_name: 'Repo',
+      display_name: 'Local Repository',
+      config_value: ''
+    }
+  ],
 
   /**
    * List of data about cluster (based on formatted <code>rawContent</code>)
@@ -644,19 +665,43 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @method loadServices
    */
   loadServices: function () {
-    var reviewService = this.get('rawContent').findProperty('config_name', 'services');
-    if (Em.isNone(reviewService)) return;
-
-    var config_value = Em.get(reviewService, 'config_value');
-    if (Em.isNone(config_value)) return;
-
-    this.get('selectedServices').forEach(function (_service) {
-      var serviceObj = config_value.findProperty('service_name', _service.serviceName);
-      if (Em.isNone(serviceObj)) return;
-      serviceObj.get('service_components').forEach(function (_component) {
-        this.assignComponentHosts(_component);
-        console.log(' ---INFO: step8: service component: ' + _service.serviceName);
+    this.get('selectedServices').filterProperty('isHiddenOnSelectServicePage', false).forEach(function (service) {
+      console.log('INFO: step8: Name of the service from getService function: ' + service.get('serviceName'));
+      var serviceObj = Em.Object.create({
+        service_name: service.get('serviceName'),
+        display_name: service.get('displayNameOnSelectServicePage'),
+        service_components: Em.A([])
+      });
+      service.get('serviceComponents').forEach(function(component) {
+        // show clients for services that have only clients components
+        if ((component.get('isClient') || component.get('isClientBehavior')) && !service.get('isClientOnlyService')) return;
+        // skip components that was hide on assign master page
+        if (component.get('isMaster') && !component.get('isShownOnInstallerAssignMasterPage')) return;
+        // no HA component
+        if (App.get('isHaEnabled') && component.get('isHAComponentOnly')) return;
+        var displayName;
+        if (component.get('isClient')) {
+          displayName = Em.I18n.t('common.clients')
+        } else {
+          // remove service name from component display name
+          displayName = component.get('displayName').replace(new RegExp('^' + service.get('serviceName') + '\\s','i'), '');
+        }
+        serviceObj.get('service_components').pushObject(Em.Object.create({
+          component_name: component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'),
+          display_name: displayName,
+          component_value: this.assignComponentHosts(component)
+        }));
       }, this);
+      if (service.get('customReviewHandler')) {
+        for (var displayName in service.get('customReviewHandler')) {
+          serviceObj.get('service_components').pushObject(Em.Object.create({
+            display_name: displayName,
+            component_value: this.assignComponentHosts(Em.Object.create({
+              customHandler: service.get('customReviewHandler.' + displayName)
+            }))
+          }));
+        }
+      }
       this.get('services').pushObject(serviceObj);
     }, this);
   },
@@ -664,31 +709,35 @@ App.WizardStep8Controller = Em.Controller.extend({
   /**
    * Set <code>component_value</code> property to <code>component</code>
    * @param {Em.Object} component
+   * @return {String}
    * @method assignComponentHosts
    */
   assignComponentHosts: function (component) {
     var componentValue;
     if (component.get('customHandler')) {
-      this[component.get('customHandler')].call(this, component);
-      console.log(' --- ---INFO: step8: in customHandler');
+      componentValue = this[component.get('customHandler')].call(this, component);
     }
     else {
-      console.log(' --- ---INFO: step8: NOT in customHandler');
-      if (component.get('isMaster')) {
-        console.log(' --- ---INFO: step8: component isMaster');
-        componentValue = this.get('content.masterComponentHosts')
-          .findProperty('component', component.component_name).hostName;
+      if (component.get('isMaster') || component.get('isMasterBehavior')) {
+        componentValue = this.getMasterComponentValue(component.get('componentName'));
       }
       else {
         console.log(' --- ---INFO: step8: NOT component isMaster');
         var hostsLength = this.get('content.slaveComponentHosts')
-          .findProperty('componentName', component.component_name)
+          .findProperty('componentName', component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'))
           .hosts.length;
         componentValue = hostsLength + Em.I18n.t('installer.step8.host' + ((hostsLength > 1) ? 's' : ''));
       }
-      console.log(' --- --- --- INFO: step8: componentValue: ' + componentValue);
-      component.set('component_value', componentValue);
     }
+    return componentValue;
+  },
+
+  getMasterComponentValue: function(componentName) {
+    var masterComponents = this.get('content.masterComponentHosts');
+    var hostsCount = masterComponents.filterProperty('component', componentName).length;
+    return stringUtils.pluralize(hostsCount,
+      masterComponents.findProperty('component', componentName).hostName,
+      hostsCount + ' ' + Em.I18n.t('installer.step8.hosts'));
   },
 
   /**
@@ -696,26 +745,26 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @param {Ember.Object} dbComponent
    * @method loadHiveDbValue
    */
-  loadHiveDbValue: function (dbComponent) {
+  loadHiveDbValue: function () {
     var db,
       serviceConfigPreoprties = this.get('wizardController').getDBProperty('serviceConfigProperties'),
       hiveDb = serviceConfigPreoprties.findProperty('name', 'hive_database');
     if (hiveDb.value === 'New MySQL Database') {
-      dbComponent.set('component_value', 'MySQL (New Database)');
+      return 'MySQL (New Database)';
     }
     else {
       if (hiveDb.value === 'Existing MySQL Database') {
-        db = serviceConfigPreoprties.findProperty('name', 'hive_existing_mysql_database');
-        dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
+        db = serviceConfigPreoprties .findProperty('name', 'hive_existing_mysql_database');
+        return db.value + ' (' + hiveDb.value + ')';
       }
       else {
         if (hiveDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
-          db = serviceConfigPreoprties.findProperty('name', 'hive_existing_postgresql_database');
-          dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
+          db = serviceConfigPreoprties .findProperty('name', 'hive_existing_postgresql_database');
+          return db.value + ' (' + hiveDb.value + ')';
         }
         else { // existing oracle database
-          db = serviceConfigPreoprties.findProperty('name', 'hive_existing_oracle_database');
-          dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
+          db = serviceConfigPreoprties .findProperty('name', 'hive_existing_oracle_database');
+          return db.value + ' (' + hiveDb.value + ')';
         }
       }
     }
@@ -756,25 +805,25 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @param {Object} dbComponent
    * @method loadOozieDbValue
    */
-  loadOozieDbValue: function (dbComponent) {
+  loadOozieDbValue: function () {
     var db, oozieDb = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_database');
     if (oozieDb.value === 'New Derby Database') {
       db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_derby_database');
-      dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+      return db.value + ' (' + oozieDb.value + ')';
     }
     else {
       if (oozieDb.value === 'Existing MySQL Database') {
         db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_mysql_database');
-        dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+        return db.value + ' (' + oozieDb.value + ')';
       }
       else {
         if (oozieDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
           db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_postgresql_database');
-          dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+          return db.value + ' (' + oozieDb.value + ')';
         }
         else { // existing oracle database
           db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_oracle_database');
-          dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+          return db.value + ' (' + oozieDb.value + ')';
         }
       }
     }
@@ -785,11 +834,11 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @param {Object} nagiosAdmin
    * @method loadNagiosAdminValue
    */
-  loadNagiosAdminValue: function (nagiosAdmin) {
+  loadNagiosAdminValue: function () {
     var config = this.get('content.serviceConfigProperties');
     var adminLoginName = config.findProperty('name', 'nagios_web_login');
     var adminEmail = config.findProperty('name', 'nagios_contact');
-    nagiosAdmin.set('component_value', adminLoginName.value + ' / (' + adminEmail.value + ')');
+    return adminLoginName.value + ' / (' + adminEmail.value + ')';
   },
 
   /**
@@ -1161,6 +1210,19 @@ App.WizardStep8Controller = Em.Controller.extend({
     }, this);
   },
 
+  getClientsToMasterMap: function () {
+    var clientNames = App.StackServiceComponent.find().filterProperty('isClient').mapProperty('componentName'),
+        clientsMap = {},
+        dependedComponents = App.StackServiceComponent.find().filterProperty('isMaster');
+    clientNames.forEach(function(clientName) {
+      clientsMap[clientName] = Em.A([]);
+      dependedComponents.forEach(function(component) {
+        if (component.get('dependencies').contains(clientName)) clientsMap[clientName].push(component.get('componentName'));
+      });
+      if (!clientsMap[clientName].length) delete clientsMap[clientName];
+    });
+    return clientsMap;
+  },
   /**
    * Register slave components and clients
    * @uses registerHostsToComponent
@@ -1183,16 +1245,7 @@ App.WizardStep8Controller = Em.Controller.extend({
      *  }
      * </code>
      */
-    var clientsToMasterMap = {
-      HDFS_CLIENT: Em.A(['HBASE_MASTER', 'HBASE_REGIONSERVER', 'WEBHCAT_SERVER', 'HISTORYSERVER', 'OOZIE_SERVER']),
-      MAPREDUCE_CLIENT: Em.A(['HIVE_SERVER', 'OOZIE_SERVER', 'NAGIOS_SERVER', 'WEBHCAT_SERVER']),
-      OOZIE_CLIENT: Em.A(['NAGIOS_SERVER']),
-      ZOOKEEPER_CLIENT: Em.A(['WEBHCAT_SERVER']),
-      HIVE_CLIENT: Em.A(['WEBHCAT_SERVER', 'HIVE_SERVER']),
-      HCAT: Em.A(['NAGIOS_SERVER']),
-      YARN_CLIENT: Em.A(['NAGIOS_SERVER', 'HIVE_SERVER', 'OOZIE_SERVER', 'WEBHCAT_SERVER']),
-      TEZ_CLIENT: Em.A(['NAGIOS_SERVER', 'HIVE_SERVER'])
-    };
+    var clientsToMasterMap = this.getClientsToMasterMap();
 
     slaveHosts.forEach(function (_slave) {
       if (_slave.componentName !== 'CLIENT') {
@@ -1267,9 +1320,9 @@ App.WizardStep8Controller = Em.Controller.extend({
    */
   createAdditionalHostComponents: function () {
     var masterHosts = this.get('content.masterComponentHosts');
-
+    // add MySQL Server if Hive is selected
     // add Ganglia Monitor (Slave) to all hosts if Ganglia service is selected
-    var gangliaService = this.get('content.services').filterProperty('isSelected', true).findProperty('serviceName', 'GANGLIA');
+    var gangliaService = this.get('content.services').filterProperty('isSelected').findProperty('serviceName', 'GANGLIA');
     if (gangliaService) {
       var hosts = this.getRegisteredHosts();
       if (gangliaService.get('isInstalled')) {
@@ -1279,7 +1332,6 @@ App.WizardStep8Controller = Em.Controller.extend({
         this.registerHostsToComponent(hosts.mapProperty('hostName'), 'GANGLIA_MONITOR');
       }
     }
-    // add MySQL Server if Hive is selected
     var hiveService = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).findProperty('serviceName', 'HIVE');
     if (hiveService) {
       var hiveDb = this.get('content.serviceConfigProperties').findProperty('name', 'hive_database');

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard/step9_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step9_controller.js b/ambari-web/app/controllers/wizard/step9_controller.js
index d9300c4..a447ef0 100644
--- a/ambari-web/app/controllers/wizard/step9_controller.js
+++ b/ambari-web/app/controllers/wizard/step9_controller.js
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 App.WizardStep9Controller = Em.Controller.extend({
 
@@ -474,11 +475,11 @@ App.WizardStep9Controller = Em.Controller.extend({
         data = {
           "context": Em.I18n.t("requestInfo.startHostComponents"),
           "query": "HostRoles/component_name.in(" + App.get('components.slaves').join(',') + ")&HostRoles/state=INSTALLED&HostRoles/host_name.in(" + hostnames.join(',') + ")",
-          "HostRoles": { "state": "STARTED" }
+          "HostRoles": { "state": "STARTED"}
         };
         break;
       case 'addServiceController':
-        var servicesList = this.get('content.services').filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName').join(",");
+        var servicesList = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName').join(",");
         name = 'common.services.update';
         data = {
           "context": Em.I18n.t("requestInfo.startAddedServices"),
@@ -1104,7 +1105,7 @@ App.WizardStep9Controller = Em.Controller.extend({
         var componentName = App.format.role(_hostComponent.HostRoles.component_name);
         componentArr.pushObject(componentName);
       }, this);
-      hostComponentObj.componentNames = this.getComponentMessage(componentArr);
+      hostComponentObj.componentNames = stringUtils.getFormattedStringFromArray(componentArr);
       hostsWithHeartbeatLost.pushObject(hostComponentObj);
     }, this);
     this.set('hostsWithHeartbeatLost', hostsWithHeartbeatLost);
@@ -1146,33 +1147,6 @@ App.WizardStep9Controller = Em.Controller.extend({
   },
 
   /**
-   * Get formatted string of components to display on the UI
-   * @param componentArr {Array}  Array of components
-   * @returns {String}
-   * @method getComponentMessage
-   */
-  getComponentMessage: function (componentArr) {
-    var label = '';
-    componentArr.forEach(function (_component) {
-      if (componentArr.length === 1) {
-        label = _component;
-      }
-      else {
-        if (_component !== componentArr[componentArr.length - 1]) {           // [clients.length - 1]
-          label = label + ' ' + _component;
-          if (_component !== componentArr[componentArr.length - 2]) {
-            label = label + ',';
-          }
-        }
-        else {
-          label = label + ' ' + Em.I18n.t('and') + ' ' + _component;
-        }
-      }
-    }, this);
-    return label.trim();
-  },
-
-  /**
    * save cluster status in the parentController and localdb
    * @param {object} clusterStatus
    * @method saveClusterStatus
@@ -1197,4 +1171,4 @@ App.WizardStep9Controller = Em.Controller.extend({
     }
   }
 
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/data/HDP2/global_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2/global_properties.js b/ambari-web/app/data/HDP2/global_properties.js
index 27fb6b0..3d9d5d6 100644
--- a/ambari-web/app/data/HDP2/global_properties.js
+++ b/ambari-web/app/data/HDP2/global_properties.js
@@ -92,7 +92,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": false,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 0
     },
     {
@@ -106,7 +106,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 2
     },
     {
@@ -120,7 +120,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 3
     },
     {
@@ -134,7 +134,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 4
     },
     {
@@ -149,7 +149,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 0
     },
     {
@@ -166,7 +166,7 @@ module.exports =
       "isRequiredByAgent": false,
       "domain": "datanode-global",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 0
     },
     {
@@ -180,7 +180,7 @@ module.exports =
       "isVisible": true,
       "domain": "datanode-global",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 2
     },
     {
@@ -247,7 +247,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "MAPREDUCE2",
-      "category": "HistoryServer",
+      "category": "HISTORYSERVER",
       "index": 0
     },
     {
@@ -261,7 +261,7 @@ module.exports =
       "displayType": "int",
       "isVisible": true,
       "serviceName": "MAPREDUCE2",
-      "category": "HistoryServer",
+      "category": "HISTORYSERVER",
       "index": 1
     },
     {
@@ -316,7 +316,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "YARN",
-      "category": "ResourceManager",
+      "category": "RESOURCEMANAGER",
       "index": 0
     },
     {
@@ -330,7 +330,7 @@ module.exports =
       "unit": "MB",
       "isVisible": true,
       "serviceName": "YARN",
-      "category": "ResourceManager",
+      "category": "RESOURCEMANAGER",
       "index": 1
     },
     {
@@ -344,7 +344,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "YARN",
-      "category": "NodeManager",
+      "category": "NODEMANAGER",
       "index": 0
     },
     {
@@ -358,7 +358,7 @@ module.exports =
       "unit": "MB",
       "isVisible": true,
       "serviceName": "YARN",
-      "category": "NodeManager",
+      "category": "NODEMANAGER",
       "index": 0
     },
     {
@@ -398,7 +398,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "YARN",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "index": 0
     },
     {
@@ -412,7 +412,7 @@ module.exports =
       "unit": "MB",
       "isVisible": true,
       "serviceName": "YARN",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "index": 1
     },
   /**********************************************HBASE***************************************/
@@ -428,7 +428,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 0
     },
     {
@@ -442,7 +442,7 @@ module.exports =
       "isOverridable": true,
       "isVisible": true,
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 1
     },
     {
@@ -457,9 +457,8 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "isRequired": false,
-      "domain": "regionserver-global",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 0
     },
     {
@@ -471,9 +470,8 @@ module.exports =
       "displayType": "int",
       "unit": "MB",
       "isVisible": true,
-      "domain": "regionserver-global",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 1
     },
     {
@@ -631,7 +629,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isVisible": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 0
     },
     // for existing MySQL
@@ -647,7 +645,7 @@ module.exports =
       "isVisible": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     // for existing PostgreSQL
@@ -663,7 +661,7 @@ module.exports =
       "isVisible": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     // for existing Oracle
@@ -679,7 +677,7 @@ module.exports =
       "isOverridable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     // for new MySQL
@@ -694,7 +692,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
     },
     {
@@ -729,7 +727,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 2
     },
     {
@@ -744,7 +742,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -760,7 +758,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -776,7 +774,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -792,7 +790,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -808,7 +806,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": false,
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
     },
     {
@@ -889,7 +887,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": false,
       "serviceName": "WEBHCAT",
-      "category": "WebHCat Server"
+      "category": "WEBHCAT_SERVER"
     },
     {
       "id": "puppet var",
@@ -930,7 +928,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 0
     },
     // for existing Oracle
@@ -947,7 +945,7 @@ module.exports =
       "isReconfigurable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for existing PostgreSQL
@@ -963,7 +961,7 @@ module.exports =
       "isVisible": false,
       "isReconfigurable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for new MySQL
@@ -978,7 +976,7 @@ module.exports =
       "isVisible": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for current derby
@@ -994,7 +992,7 @@ module.exports =
       "isReconfigurable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     // for existing MySQL oozie
@@ -1010,7 +1008,7 @@ module.exports =
       "isReconfigurable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
     },
     {
@@ -1052,7 +1050,7 @@ module.exports =
       "radioName": "oozie-database",
       "isVisible": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 2
     },
     {
@@ -1068,7 +1066,7 @@ module.exports =
       "isVisible": true,
       "isRequired": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 9
     },
     {
@@ -1082,7 +1080,7 @@ module.exports =
       "displayType": "host",
       "isVisible": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1097,7 +1095,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1112,7 +1110,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1127,7 +1125,7 @@ module.exports =
       "isVisible": false,
       "isObserved": true,
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
     },
     {
@@ -1143,7 +1141,7 @@ module.exports =
       "isVisible": false,
       "isRequiredByAgent": false,
       "serviceName": "OOZIE",
-      "category": "Oozie Server"
+      "category": "OOZIE_SERVER"
     },
     {
       "id": "puppet var",
@@ -1235,7 +1233,7 @@ module.exports =
       "isOverridable": false,
       "isRequired": false,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 0
     },
     {
@@ -1249,7 +1247,7 @@ module.exports =
       "displayType": "directory",
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 1
     },
     {
@@ -1263,7 +1261,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 2
     },
     {
@@ -1276,7 +1274,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 3
     },
     {
@@ -1289,7 +1287,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 4
     },
     {
@@ -1302,7 +1300,7 @@ module.exports =
       "isOverridable": false,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 5
     },
     {
@@ -1401,7 +1399,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": false,
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     {
       "id": "puppet var",
@@ -1414,7 +1412,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": true,
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     {
       "id": "puppet var",
@@ -1427,7 +1425,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": true,
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     {
       "id": "puppet var",
@@ -1440,7 +1438,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": true,
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     {
       "id": "puppet var",
@@ -1550,7 +1548,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": false,
       "serviceName": "STORM",
-      "category": "StormUIServer",
+      "category": "STORM_UI_SERVER",
       "filename": "global.xml"
     },
     {
@@ -1564,7 +1562,7 @@ module.exports =
       "isVisible": true,
       "isRequiredByAgent": false,
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "filename": "global.xml"
     },
     {
@@ -1579,7 +1577,7 @@ module.exports =
       "isRequiredByAgent": false,
       "serviceName": "STORM",
       "isOverridable": false,
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "filename": "global.xml"
     },
     {
@@ -1594,7 +1592,7 @@ module.exports =
       "isRequiredByAgent": false,
       "serviceName": "STORM",
       "isOverridable": false,
-      "category": "StormRestApi",
+      "category": "STORM_REST_API",
       "filename": "global.xml"
     },
   /**********************************************MISC***************************************/