You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ja...@apache.org on 2014/04/09 04:45:14 UTC

[1/2] AMBARI-5389. Stack service component data should be dynamically fetched from server. (jaimin)

Repository: ambari
Updated Branches:
  refs/heads/trunk 77c8f1ff7 -> 29e61ae9c


http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/data/service_components.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/service_components.js b/ambari-web/app/data/service_components.js
deleted file mode 100644
index f066c46..0000000
--- a/ambari-web/app/data/service_components.js
+++ /dev/null
@@ -1,423 +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 = new Ember.Set([
-
-  {
-    service_name: 'HDFS',
-    component_name: 'NAMENODE',
-    display_name: 'NameNode',
-    isMaster: true,
-    isClient: false,
-    description: 'Master server that manages the file system namespace and regulates access to files by clients'
-  },
-  {
-    service_name: 'HDFS',
-    component_name: 'SECONDARY_NAMENODE',
-    display_name: 'SNameNode',
-    isMaster: true,
-    isClient: false,
-    description: 'Helper to the primary NameNode that is responsible for supporting periodic checkpoints of the HDFS metadata'
-  },
-  {
-    service_name: 'HDFS',
-    component_name: 'DATANODE',
-    display_name: 'DataNode',
-    isMaster: false,
-    isClient: false,
-    description: 'The slave for HDFS'
-  },
-  {
-    service_name: 'HDFS',
-    component_name: 'HDFS_CLIENT',
-    display_name: 'HDFS Client',
-    isMaster: false,
-    isClient: true,
-    description: 'Client component for HDFS'
-  },
-  {
-    service_name: 'MAPREDUCE',
-    component_name: 'JOBTRACKER',
-    display_name: 'JobTracker',
-    isMaster: true,
-    isClient: false,
-    description: 'Central Master service that pushes work (MR tasks) out to available TaskTracker nodes in the cluster'
-  },
-  {
-    service_name: 'MAPREDUCE',
-    component_name: 'HISTORYSERVER',
-    display_name: 'History Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'MAPREDUCE',
-    component_name: 'TASKTRACKER',
-    display_name: 'TaskTracker',
-    isMaster: false,
-    isClient: false,
-    description: 'The slave for MapReduce'
-  },
-  {
-    service_name: 'MAPREDUCE',
-    component_name: 'MAPREDUCE_CLIENT',
-    display_name: 'MapReduce Client',
-    isMaster: false,
-    isClient: true,
-    description: 'Client component for MapReduce'
-  },
-  {
-    service_name: 'MAPREDUCE2',
-    component_name: 'MAPREDUCE2_CLIENT',
-    display_name: 'MapReduce 2 Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'MAPREDUCE2',
-    component_name: 'HISTORYSERVER',
-    display_name: 'History Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'TEZ',
-    component_name: 'TEZ_CLIENT',
-    display_name: 'Tez Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'YARN',
-    component_name: 'RESOURCEMANAGER',
-    display_name: 'ResourceManager',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'YARN',
-    component_name: 'YARN_CLIENT',
-    display_name: 'YARN Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  // @todo uncomment after Application Timeline Server API implementation
-//  {
-//    service_name: 'YARN',
-//    component_name: 'APP_TIMELINE_SERVER',
-//    display_name: 'App Timeline Server',
-//    isMaster: true,
-//    isClient: false,
-//    stackVersions: ['2.1.1'],
-//    description: ''
-//  },
-  {
-    service_name: 'YARN',
-    component_name: 'NODEMANAGER',
-    display_name: 'NodeManager',
-    isMaster: false,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'ZOOKEEPER',
-    component_name: 'ZOOKEEPER_SERVER',
-    display_name: 'ZooKeeper',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'ZOOKEEPER',
-    component_name: 'ZOOKEEPER_CLIENT',
-    display_name: 'ZooKeeper Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'HBASE',
-    component_name: 'HBASE_MASTER',
-    display_name: 'HBase Master',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'HBASE',
-    component_name: 'HBASE_REGIONSERVER',
-    display_name: 'RegionServer',
-    isMaster: false,
-    isClient: false,
-    description: 'The slave for HBase'
-  },
-  {
-    service_name: 'HBASE',
-    component_name: 'HBASE_CLIENT',
-    display_name: 'HBase Client',
-    isMaster: false,
-    isClient: true,
-    description: 'The slave for HBase'
-  },
-  {
-    service_name: 'PIG',
-    component_name: 'PIG',
-    display_name: 'Pig',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'SQOOP',
-    component_name: 'SQOOP',
-    display_name: 'Sqoop',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'OOZIE',
-    component_name: 'OOZIE_SERVER',
-    display_name: 'Oozie Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'OOZIE',
-    component_name: 'OOZIE_CLIENT',
-    display_name: 'Oozie Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'HIVE',
-    component_name: 'HIVE_SERVER',
-    display_name: 'HiveServer2',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'HIVE',
-    component_name: 'HIVE_METASTORE',
-    display_name: 'Hive Metastore',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'HIVE',
-    component_name: 'HIVE_CLIENT',
-    display_name: 'Hive Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'HIVE',
-    component_name: 'MYSQL_SERVER',
-    display_name: 'MySQL Server for Hive',
-    isMaster: false,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'HCATALOG',
-    component_name: 'HCAT',
-    display_name: 'HCat Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'WEBHCAT',
-    component_name: 'WEBHCAT_SERVER',
-    display_name: 'WebHCat Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'DASHBOARD',
-    component_name: 'DASHBOARD',
-    display_name: 'Monitoring Dashboard',
-    isMaster: false,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'NAGIOS',
-    component_name: 'NAGIOS_SERVER',
-    display_name: 'Nagios Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'GANGLIA',
-    component_name: 'GANGLIA_SERVER',
-    display_name: 'Ganglia Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'GANGLIA',
-    component_name: 'GANGLIA_MONITOR',
-    display_name: 'Ganglia Slave',
-    isMaster: false,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'KERBEROS',
-    component_name: 'KERBEROS_SERVER',
-    display_name: 'Kerberos Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  {
-    service_name: 'KERBEROS',
-    component_name: 'KERBEROS_ADMIN_CLIENT',
-    display_name: 'Kerberos Admin Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'KERBEROS',
-    component_name: 'KERBEROS_CLIENT',
-    display_name: 'Kerberos Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'CLIENT',
-    component_name: 'CLIENT',
-    display_name: 'Client',
-    isMaster: false,
-    isClient: true,
-    description: ''
-  },
-  {
-    service_name: 'HUE',
-    component_name: 'HUE_SERVER',
-    display_name: 'Hue Server',
-    isMaster: true,
-    isClient: false,
-    description: ''
-  },
-  { 
-    service_name: 'GLUSTERFS',
-    component_name: 'GLUSTERFS_CLIENT',
-    display_name: 'GLUSTERFS Client', 
-    isMaster: false, 
-    isClient: true, 
-    description: 'Client component for GLUSTERFS'
-  },
-  {
-    service_name: 'FALCON',
-    component_name: 'FALCON_SERVER',
-    display_name: 'Falcon Server',
-    isMaster: true,
-    isClient: false,
-    description: 'Falcon Server for mirroring'
-  },
-  {
-    service_name: 'FALCON',
-    component_name: 'FALCON_CLIENT',
-    display_name: 'Falcon Client',
-    isMaster: false,
-    isClient: true,
-    description: 'Falcon Client for mirroring'
-  },
-  {
-    service_name: 'STORM',
-    component_name: 'NIMBUS',
-    display_name: 'Nimbus',
-    isMaster: true,
-    isClient: false,
-    description: 'Master component for STORM'
-  },
-  {
-    service_name: 'STORM',
-    component_name: 'SUPERVISOR',
-    display_name: 'Supervisor',
-    isMaster: false,
-    isClient: false,
-    description: 'Slave component for STORM'
-  },
-  {
-    service_name: 'STORM',
-    component_name: 'STORM_UI_SERVER',
-    display_name: 'Storm UI Server',
-    isMaster: true,
-    isClient: false,
-    description: 'Master component for STORM'
-  },
-  {
-    service_name: 'STORM',
-    component_name: 'DRPC_SERVER',
-    display_name: 'DRPC Server',
-    isMaster: true,
-    isClient: false,
-    description: 'Master component for STORM'
-  },
-  {
-    service_name: 'STORM',
-    component_name: 'STORM_REST_API',
-    display_name: 'Storm REST API Server',
-    isMaster: true,
-    isClient: false,
-    description: 'Master component for STORM'
-  },
-  {
-    service_name: 'FLUME',
-    component_name: 'FLUME_HANDLER',
-    display_name: 'Flume Agent',
-    isMaster: false,
-    isClient: false,
-    description: 'Slave component for Flume'
-  }
-]);
-
-// @todo remove after Application Timeline Server API implementation
-if (App.supports.appTimelineServer) {
-  var appTimelineServerObj = {
-    service_name: 'YARN',
-    component_name: 'APP_TIMELINE_SERVER',
-    display_name: 'App Timeline Server',
-    isMaster: true,
-    isClient: false,
-    stackVersions: ['2.1'],
-    description: ''
-  };
-  module.exports.push(appTimelineServerObj);
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/initialize.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/initialize.js b/ambari-web/app/initialize.js
index 777779a..9f048d5 100644
--- a/ambari-web/app/initialize.js
+++ b/ambari-web/app/initialize.js
@@ -36,20 +36,8 @@ require('router');
 require('utils/ajax');
 require('utils/updater');
 
-require('mappers/server_data_mapper');
-require('mappers/status_mapper');
-require('mappers/hosts_mapper');
-require('mappers/cluster_mapper');
-require('mappers/jobs_mapper');
-require('mappers/runs_mapper');
-require('mappers/racks_mapper');
-require('mappers/users_mapper');
-require('mappers/service_mapper');
-require('mappers/service_metrics_mapper');
-require('mappers/target_cluster_mapper');
-require('mappers/dataset_mapper');
-require('mappers/component_config_mapper');
-require('mappers/jobs/hive_jobs_mapper');
+require('mappers');
+
 require('mappers/jobs/hive_job_mapper');
 require('utils/http_client');
 require('utils/host_progress_popup');

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/mappers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js
new file mode 100644
index 0000000..08d40fe
--- /dev/null
+++ b/ambari-web/app/mappers.js
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+//load all mappers
+require('mappers/server_data_mapper');
+require('mappers/stack_service_component_mapper');
+require('mappers/status_mapper');
+require('mappers/hosts_mapper');
+require('mappers/cluster_mapper');
+require('mappers/jobs_mapper');
+require('mappers/runs_mapper');
+require('mappers/racks_mapper');
+require('mappers/users_mapper');
+require('mappers/service_mapper');
+require('mappers/service_metrics_mapper');
+require('mappers/target_cluster_mapper');
+require('mappers/dataset_mapper');
+require('mappers/component_config_mapper');
+require('mappers/jobs/hive_jobs_mapper');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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
new file mode 100644
index 0000000..6b13214
--- /dev/null
+++ b/ambari-web/app/mappers/stack_service_component_mapper.js
@@ -0,0 +1,44 @@
+/**
+ * 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.config));
+      }, this);
+      App.store.loadMany(model, result);
+    }
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index ce53c73..b9239fb 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_component');
 require('models/quick_links');
 require('models/service');
 require('models/service_config');

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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
new file mode 100644
index 0000000..50175af
--- /dev/null
+++ b/ambari-web/app/models/stack_service_component.js
@@ -0,0 +1,72 @@
+/**
+ * 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');
+/**
+ * This model loads all serviceComponents supported by the stack
+ * @type {*}
+ */
+App.StackServiceComponent = DS.Model.extend({
+  componentName: DS.attr('string'),
+  serviceName: DS.attr('string'),
+  componentCategory: DS.attr('string'),
+  isMaster: DS.attr('boolean'),
+  isClient: DS.attr('boolean'),
+  stackName: DS.attr('string'),
+  stackVersion: DS.attr('string'),
+
+  displayName: function() {
+    return App.format.components[this.get('componentName')];
+  }.property('componentName'),
+
+  isSlave: function() {
+   return this.get('componentCategory') === 'SLAVE';
+  }.property('componentCategory'),
+
+  isRestartable: function() {
+    return !this.get('isClient');
+  }.property('isClient'),
+
+  isReassignable: function() {
+    return ['NAMENODE', 'SECONDARY_NAMENODE', 'JOBTRACKER', 'RESOURCEMANAGER'].contains(this.get('componentName'));
+  }.property('componentName'),
+
+  isDeletable: function() {
+    return ['SUPERVISOR', 'HBASE_MASTER', 'DATANODE', 'TASKTRACKER', 'NODEMANAGER', 'HBASE_REGIONSERVER'].contains(this.get('componentName'));
+  }.property('componentName'),
+
+  isRollinRestartAllowed: function() {
+    return ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "SUPERVISOR"].contains(this.get('componentName'));
+  }.property('componentName'),
+
+  isDecommissionAllowed: function() {
+    return ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER"].contains(this.get('componentName'));
+  }.property('componentName'),
+
+  isAddableToHost: function() {
+    return ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "HBASE_MASTER", "ZOOKEEPER_SERVER", "SUPERVISOR"].contains(this.get('componentName'));
+  }.property('componentName'),
+
+  isShownOnInstallerAssignMasterPage: function() {
+    var component = this.get('componentName');
+    var mastersNotShown = ['MYSQL_SERVER','JOURNALNODE'];
+    return ((this.get('isMaster') && !mastersNotShown.contains(component)) || component === 'APP_TIMELINE_SERVER');
+  }.property('isMaster','componentName')
+});
+
+App.StackServiceComponent.FIXTURES = [];
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index 4f25d93..cad1c3e 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -1231,12 +1231,12 @@ var urls = {
     }
   },
   'wizard.service_components': {
-    'real': '{stackUrl}/stackServices?fields=StackServices',
-    'mock': '/data/wizard/stack/hdp/version/{stackVersion}.json',
-    'format': function() {
+    'real': '{stackUrl}/stackServices?fields=StackServices/comments,StackServices/service_version,serviceComponents/*',
+    'mock': '/data/wizard/stacks/HDP-2.1/service_components.json',
+    'format': function(data) {
       return {
         timeout: 10000,
-        async: false
+        async: !!data.async
       };
     }
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/utils/component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/component.js b/ambari-web/app/utils/component.js
index dec45a7..e085763 100644
--- a/ambari-web/app/utils/component.js
+++ b/ambari-web/app/utils/component.js
@@ -20,6 +20,8 @@
  * Here will be stored slave functions related to components
  * @type {Object}
  */
+
+var App = require('app');
 module.exports = {
 
   /**
@@ -52,5 +54,31 @@ module.exports = {
     });
 
     return result;
+  },
+
+  /**
+   *
+   * @param data
+   */
+  loadStackServiceComponentModel: function(data) {
+    var serviceComponents = {items: []};
+    data.items.forEach(function(item){
+      item.serviceComponents.forEach(function(_serviceComponent){
+        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
+        };
+        serviceComponents.items.pushObject(serviceComponent);
+      },this);
+    },this);
+    App.stackServiceComponentMapper.map(serviceComponents);
+    App.handleStackDependedComponents();
+    return serviceComponents;
   }
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/views/main/host/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js
index d367e89..8967cd1 100644
--- a/ambari-web/app/views/main/host/summary.js
+++ b/ambari-web/app/views/main/host/summary.js
@@ -238,7 +238,7 @@ App.MainHostSummaryView = Em.View.extend({
       return [];
     }
     var componentServiceMap = App.QuickDataMapper.componentServiceMap();
-    var allClients = App.get('components.clients');
+    var allClients = App.StackServiceComponent.find().filterProperty('isClient',true).mapProperty('componentName');
     var installedServices = this.get('installedServices');
     var installedClients = this.get('clients').mapProperty('componentName');
     return allClients.filter(function(componentName) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/test/app_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/app_test.js b/ambari-web/test/app_test.js
index 4830b58..b43aa0d 100644
--- a/ambari-web/test/app_test.js
+++ b/ambari-web/test/app_test.js
@@ -19,31 +19,12 @@
 var App = require('app');
 
 describe('#App', function() {
+  describe('Disable/enable components', function() {
 
-  describe('App.components', function() {
-
-    it('slaves and masters should not intersect', function() {
-      var intersected = App.get('components.slaves').filter(function(item){
-        return App.get('components.masters').contains(item);
-      });
-      expect(intersected).to.eql([]);
-    });
-
-    it('decommissionAllowed', function() {
-      expect(App.get('components.decommissionAllowed')).to.eql(["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER"]);
-    });
-
-    it('addableToHost', function() {
-      expect(App.get('components.addableToHost')).to.eql(["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "HBASE_MASTER", "ZOOKEEPER_SERVER", "SUPERVISOR"]);
+    var testableComponent =  Ember.Object.create({
+      componentName: 'APP_TIMELINE_SERVER',
+      serviceName: 'YARN'
     });
-
-  });
-
-  describe('Disable/enable components', function() {
-    var testableComponent =  {
-      service_name: 'YARN',
-      component_name: 'APP_TIMELINE_SERVER'
-    };
     var expectedInfo = {
       componentName: 'APP_TIMELINE_SERVER',
       properties: {
@@ -59,7 +40,6 @@ describe('#App', function() {
     };
     var globalProperties = require('data/HDP2/global_properties');
     var siteProperties = require('data/HDP2/site_properties');
-    var serviceComponents = require('data/service_components');
     var reviewConfigs = require('data/review_configs');
     var disableResult;
 
@@ -71,7 +51,6 @@ describe('#App', function() {
       // copy
       var _globalProperties = $.extend({}, globalProperties);
       var _siteProperties = $.extend({}, siteProperties);
-      var _serviceComponents = $.extend({}, serviceComponents);
       var _reviewConfigs = JSON.parse(JSON.stringify(reviewConfigs));
 
       describe('result validation', function() {
@@ -103,9 +82,6 @@ describe('#App', function() {
 
       describe('effect validation',function() {
 
-        it('should remove component from service_components object', function() {
-          expect(_serviceComponents.findProperty('component_name', testableComponent.component_name)).to.be.undefined;
-        });
 
         it('should remove global properties of component', function() {
           expect(_globalProperties.configProperties.mapProperty('name')).to.not.include.members(expectedInfo.properties.global_properties);
@@ -117,7 +93,7 @@ describe('#App', function() {
 
         it('should remove review config for component', function() {
           var reviewConfig = _reviewConfigs.findProperty('config_name', 'services')
-            .config_value.findProperty('service_name', testableComponent.service_name)
+            .config_value.findProperty('service_name', testableComponent.get('serviceName'))
             .service_components.mapProperty('component_name');
           expect(reviewConfig).to.not.include(expectedInfo.reviewConfigs.component_name);
         });
@@ -127,10 +103,6 @@ describe('#App', function() {
     describe('#enableComponent', function() {
       App.enableComponent(disableResult);
 
-      it('should add component to service_components object', function() {
-        expect(serviceComponents.findProperty('component_name', testableComponent.component_name)).to.exist;
-      });
-
       it('should add global properties of component', function() {
         expect(globalProperties.configProperties.mapProperty('name')).to.include.members(expectedInfo.properties.global_properties);
       });
@@ -141,11 +113,10 @@ describe('#App', function() {
 
       it('should add review config for component', function() {
         var reviewConfig = reviewConfigs.findProperty('config_name', 'services')
-          .config_value.findProperty('service_name', testableComponent.service_name)
+          .config_value.findProperty('service_name', testableComponent.get('serviceName'))
           .get('service_components').mapProperty('component_name');
         expect(reviewConfig).to.include(expectedInfo.reviewConfigs.component_name);
       });
     });
   });
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/test/installer/step5_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/installer/step5_test.js b/ambari-web/test/installer/step5_test.js
index 57cef17..a672900 100644
--- a/ambari-web/test/installer/step5_test.js
+++ b/ambari-web/test/installer/step5_test.js
@@ -19,7 +19,6 @@
 var Ember = require('ember');
 var App = require('app');
 require('controllers/wizard/step5_controller');
-var components = require('data/service_components');
 
 describe('App.WizardStep5Controller', function () {
   var controller = App.WizardStep5Controller.create();

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/test/installer/step6_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/installer/step6_test.js b/ambari-web/test/installer/step6_test.js
index e323f2d..da64fc1 100644
--- a/ambari-web/test/installer/step6_test.js
+++ b/ambari-web/test/installer/step6_test.js
@@ -23,7 +23,6 @@ require('controllers/wizard/step6_controller');
 describe('App.WizardStep6Controller', function () {
 
   var controller = App.WizardStep6Controller.create();
-
   controller.set('content', {
     hosts: {},
     masterComponentHosts: {},
@@ -46,6 +45,9 @@ describe('App.WizardStep6Controller', function () {
       })
     ]
   });
+  controller.set('getComponentDisplayName',function () {
+    return true;
+  });
 
   var HOSTS = Em.A([ 'host0', 'host1', 'host2', 'host3' ]);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/test/installer/step9_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/installer/step9_test.js b/ambari-web/test/installer/step9_test.js
index 4ecd864..32bb806 100644
--- a/ambari-web/test/installer/step9_test.js
+++ b/ambari-web/test/installer/step9_test.js
@@ -19,11 +19,71 @@
 
 var Ember = require('ember');
 var App = require('app');
+require('models/stack_service_component');
 require('models/hosts');
 require('controllers/wizard/step9_controller');
 require('utils/helper');
 
 describe('App.InstallerStep9Controller', function () {
+  var data = [
+    {
+      id: 'DATANODE',
+      component_name: 'DATANODE',
+      service_name: 'HDFS',
+      is_client: false,
+      is_master: false,
+      component_category: 'SLAVE'
+    },
+    {
+      id: 'TASKTRACKER',
+      component_name: 'TASKTRACKER',
+      service_name: 'MAPREDUCE',
+      is_client: false,
+      is_master: false,
+      component_category: 'SLAVE'
+    },
+    {
+      id: 'HBASE_REGIONSERVER',
+      component_name: 'HBASE_REGIONSERVER',
+      service_name: 'HBASE',
+      is_client: false,
+      is_master: false,
+      component_category: 'SLAVE'
+    },
+    {
+      id: 'GANGLIA_MONITOR',
+      component_name: 'GANGLIA_MONITOR',
+      service_name: 'GANGLIA',
+      is_client: false,
+      is_master: false,
+      component_category: 'SLAVE'
+    },
+    {
+      id: 'SUPERVISOR',
+      component_name: 'SUPERVISOR',
+      service_name: 'STORM',
+      is_client: false,
+      is_master: false,
+      component_category: 'SLAVE'
+    },
+    {
+      id: 'NAMENODE',
+      component_name: 'NAMENODE',
+      service_name: 'HDFS',
+      is_client: false,
+      is_master: true,
+      component_category: 'MASTER'
+    },
+    {
+      id: 'HDFS_CLIENT',
+      component_name: 'HDFS_CLIENT',
+      service_name: 'HDFS',
+      is_client: true,
+      is_master: false,
+      component_category: 'SLAVE'
+    }
+  ];
+  App.store.loadMany(App.StackServiceComponent,data);
 
   describe('#isSubmitDisabled', function () {
     var tests = Em.A([


[2/2] git commit: AMBARI-5389. Stack service component data should be dynamically fetched from server. (jaimin)

Posted by ja...@apache.org.
AMBARI-5389. Stack service component data should be dynamically fetched from server. (jaimin)


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

Branch: refs/heads/trunk
Commit: 29e61ae9cf0b1c7a75fda592f81e6244274a0d84
Parents: 77c8f1f
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Tue Apr 8 19:44:40 2014 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Tue Apr 8 19:44:40 2014 -0700

----------------------------------------------------------------------
 ambari-web/app/app.js                           |  98 +--
 .../data/stacks/HDP-2.1/service_components.json | 665 +++++++++++++++++++
 .../controllers/global/cluster_controller.js    | 145 ++--
 ambari-web/app/controllers/installer.js         |  21 +-
 .../app/controllers/main/host/add_controller.js |  20 +-
 .../controllers/main/service/add_controller.js  |  10 +-
 ambari-web/app/controllers/main/service/item.js |   1 -
 .../service/manage_config_groups_controller.js  |   3 +-
 ambari-web/app/controllers/wizard.js            |  38 +-
 .../app/controllers/wizard/step5_controller.js  |  62 +-
 .../app/controllers/wizard/step6_controller.js  |   5 +-
 .../app/controllers/wizard/step7_controller.js  |   6 +-
 .../app/controllers/wizard/step8_controller.js  |   7 +-
 .../app/controllers/wizard/step9_controller.js  |   5 +-
 ambari-web/app/data/HDP2/global_properties.js   | 206 +++---
 ambari-web/app/data/service_components.js       | 423 ------------
 ambari-web/app/initialize.js                    |  16 +-
 ambari-web/app/mappers.js                       |  34 +
 .../mappers/stack_service_component_mapper.js   |  44 ++
 ambari-web/app/models.js                        |   1 +
 .../app/models/stack_service_component.js       |  72 ++
 ambari-web/app/utils/ajax.js                    |   8 +-
 ambari-web/app/utils/component.js               |  28 +
 ambari-web/app/views/main/host/summary.js       |   2 +-
 ambari-web/test/app_test.js                     |  41 +-
 ambari-web/test/installer/step5_test.js         |   1 -
 ambari-web/test/installer/step6_test.js         |   4 +-
 ambari-web/test/installer/step9_test.js         |  60 ++
 28 files changed, 1240 insertions(+), 786 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index e83319e..628f19e 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -91,7 +91,6 @@ module.exports = Em.Application.create({
    *    for example:
    *      properties: { global_properties: [], site_properties: [], etc. }
    *   @property reviewConfigs {Ember.Object} - reference review_configs.js
-   *   @property serviceComponent {Object} - reference service_components.js
    *
    * @type {Array}
    */
@@ -105,45 +104,42 @@ module.exports = Em.Application.create({
   enableComponent: function(component) {
     var propertyFileNames = ['global_properties', 'site_properties'];
     var requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
-    // add component to service_components list
-    require('data/service_components').push(component.get('serviceComponent'));
     // 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('serviceComponent.service_name'));
+      .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} - component info reference service_components.js
+   * @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.component_name,
+      componentName: component.get('componentName'),
+      serviceName: component.get('serviceName'),
       properties: {},
       reviewConfigs: {},
-      configCategory: {},
-      serviceComponent: {}
+      configCategory: {}
     });
-    componentCopy.set('serviceComponent', require('data/service_components').findProperty('component_name', component.component_name));
-    // remove component from service_components list
-    require('data/service_components').removeObject(componentCopy.get('serviceComponent'));
+
     var serviceConfigsCategoryName, requirePrefix, serviceConfig;
     // get service category name related to component
-    serviceConfig = require('data/service_configs').findProperty('serviceName', component.service_name);
+    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.component_name)) {
+        if (configCategory.get('hostComponentNames').contains(component.get('componentName'))) {
           componentCopy.set('configCategory', configCategory);
         }
       }
@@ -170,9 +166,9 @@ module.exports = Em.Application.create({
     // remove component from review configs
     var reviewConfigsService = require('data/review_configs')
       .findProperty('config_name', 'services').config_value
-      .findProperty('service_name', component.service_name);
+      .findProperty('service_name', component.get('serviceName'));
     reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) {
-      if (serviceComponent.get('component_name') != component.component_name) {
+      if (serviceComponent.get('component_name') != component.get('componentName')) {
         return true;
       } else {
         componentCopy.set('reviewConfigs', serviceComponent);
@@ -188,51 +184,59 @@ module.exports = Em.Application.create({
   handleStackDependedComponents: function() {
     // need for unit testing and test mode
     if (this.get('handleStackDependencyTest') || this.testMode) return;
-    var stackVersion, stackDependedComponents;
-    stackVersion = this.get('currentStackVersionNumber');
-    stackDependedComponents = [];
+    var stackDependedComponents = [];
+    var service_configs = require('data/service_configs');
+    var stackServiceComponents = this.StackServiceComponent.find();
+    if (!stackServiceComponents.mapProperty('componentName').length) {
+       return;
+    }
     // disable components
-    require('data/service_components').filterProperty('stackVersions').forEach(function(component) {
-      if (!component.stackVersions.contains(stackVersion))
-        stackDependedComponents.push(this.disableComponent(component));
-    }, this);
+    service_configs.forEach(function(service){
+      service.configCategories.forEach(function(serviceConfigCategory){
+        var categoryComponents = serviceConfigCategory.get('hostComponentNames');
+        if (categoryComponents && categoryComponents.length) {
+          categoryComponents.forEach(function(categoryComponent) {
+            var stackComponent = stackServiceComponents.findProperty('componentName',categoryComponent);
+            if(!stackComponent && !this.get('stackDependedComponents').mapProperty('componentName').contains['categoryComponent'] ) {
+              var _stackComponent = Ember.Object.create({
+                componentName: categoryComponent,
+                serviceName:service.serviceName
+              });
+              stackDependedComponents.push(this.disableComponent(_stackComponent));
+            }
+          },this);
+        }
+      },this);
+    },this);
     // enable components
     if (this.get('stackDependedComponents').length > 0) {
       this.get('stackDependedComponents').forEach(function(component) {
-        if (component.get('serviceComponent').stackVersions.contains(this.get('currentStackVersionNumber'))) {
+        if (stackServiceComponents.findProperty('componentName',component.get('componentName'))) {
           this.enableComponent(component);
           stackDependedComponents = this.get('stackDependedComponents').removeObject(component);
         }
       }, this);
     }
     this.set('stackDependedComponents', this.get('stackDependedComponents').concat(stackDependedComponents));
-  }.observes('currentStackVersionNumber'),
+  },
 
   /**
    * List of components with allowed action for them
    * @type {Em.Object}
    */
-  components: Ember.Object.create({
-    reassignable: ['NAMENODE', 'SECONDARY_NAMENODE', 'JOBTRACKER', 'RESOURCEMANAGER'],
-    restartable: function() {
-      return this.get('masters').concat(this.get('slaves'));
-    }.property('masters'),
-    deletable: ['SUPERVISOR', 'HBASE_MASTER', 'DATANODE', 'TASKTRACKER', 'NODEMANAGER', 'HBASE_REGIONSERVER'],
-    rollinRestartAllowed: ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "SUPERVISOR"],
-    decommissionAllowed: ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER"],
-    addableToHost: ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "HBASE_MASTER", "ZOOKEEPER_SERVER", "SUPERVISOR"],
-    slaves: function() {
-      return require('data/service_components').filter(function(component){
-        return !component.isClient && !component.isMaster;
-      }).mapProperty('component_name').uniq().without("DASHBOARD").without("MYSQL_SERVER");
-    }.property().cacheable(),
-
-    masters: function() {
-      return require('data/service_components').filterProperty('isMaster', true)
-        .mapProperty('component_name').concat(['MYSQL_SERVER']).uniq();
-    }.property().cacheable(),
-    clients: function() {
-      return require('data/service_components').filterProperty('isClient', true).mapProperty('component_name').uniq();
-    }.property().cacheable()
-  })
+  components: function() {
+    var self = this;
+    return Ember.Object.create({
+      allComponents:self.StackServiceComponent.find().mapProperty('componentName'),
+      reassignable: self.StackServiceComponent.find().filterProperty('isReassignable',true).mapProperty('componentName'),
+      restartable: self.StackServiceComponent.find().filterProperty('isRestartable',true).mapProperty('componentName'),
+      deletable: self.StackServiceComponent.find().filterProperty('isDeletable',true).mapProperty('componentName'),
+      rollinRestartAllowed: self.StackServiceComponent.find().filterProperty('isRollinRestartAllowed',true).mapProperty('componentName'),
+      decommissionAllowed: self.StackServiceComponent.find().filterProperty('isDecommissionAllowed',true).mapProperty('componentName'),
+      addableToHost: self.StackServiceComponent.find().filterProperty('isAddableToHost',true).mapProperty('componentName'),
+      slaves: self.StackServiceComponent.find().filterProperty('isSlave',true).mapProperty('componentName'),
+      masters: self.StackServiceComponent.find().filterProperty('isMaster',true).mapProperty('componentName'),
+      clients: self.StackServiceComponent.find().filterProperty('isClient',true).mapProperty('componentName')
+    })
+  }.property()
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/assets/data/stacks/HDP-2.1/service_components.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/stacks/HDP-2.1/service_components.json b/ambari-web/app/assets/data/stacks/HDP-2.1/service_components.json
new file mode 100644
index 0000000..ab7e45d
--- /dev/null
+++ b/ambari-web/app/assets/data/stacks/HDP-2.1/service_components.json
@@ -0,0 +1,665 @@
+{
+  "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices?fields=StackServices/comments,StackServices/service_version,serviceComponents/*",
+  "items" : [
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/FALCON",
+      "StackServices" : {
+        "comments" : "Data management and processing platform",
+        "service_name" : "FALCON",
+        "service_version" : "0.4.0.2.1.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/FALCON/serviceComponents/FALCON_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "FALCON_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "FALCON",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/FALCON/serviceComponents/FALCON_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "FALCON_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "FALCON",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/GANGLIA",
+      "StackServices" : {
+        "comments" : "Ganglia Metrics Collection system",
+        "service_name" : "GANGLIA",
+        "service_version" : "3.5.0",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/GANGLIA/serviceComponents/GANGLIA_MONITOR",
+          "StackServiceComponents" : {
+            "component_category" : "SLAVE",
+            "component_name" : "GANGLIA_MONITOR",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "GANGLIA",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/GANGLIA/serviceComponents/GANGLIA_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "GANGLIA_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "GANGLIA",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HBASE",
+      "StackServices" : {
+        "comments" : "Non-relational distributed database and centralized service for configuration management &\n        synchronization\n      ",
+        "service_name" : "HBASE",
+        "service_version" : "0.96.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "HBASE_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "HBASE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_MASTER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "HBASE_MASTER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HBASE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HBASE/serviceComponents/HBASE_REGIONSERVER",
+          "StackServiceComponents" : {
+            "component_category" : "SLAVE",
+            "component_name" : "HBASE_REGIONSERVER",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "HBASE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HCATALOG",
+      "StackServices" : {
+        "comments" : "This is comment for HCATALOG service",
+        "service_name" : "HCATALOG",
+        "service_version" : "0.12.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HCATALOG/serviceComponents/HCAT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "HCAT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "HCATALOG",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS",
+      "StackServices" : {
+        "comments" : "Apache Hadoop Distributed File System",
+        "service_name" : "HDFS",
+        "service_version" : "2.1.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS/serviceComponents/DATANODE",
+          "StackServiceComponents" : {
+            "component_category" : "SLAVE",
+            "component_name" : "DATANODE",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "HDFS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS/serviceComponents/HDFS_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "HDFS_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "HDFS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS/serviceComponents/JOURNALNODE",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "JOURNALNODE",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HDFS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS/serviceComponents/NAMENODE",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "NAMENODE",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HDFS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS/serviceComponents/SECONDARY_NAMENODE",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "SECONDARY_NAMENODE",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HDFS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HDFS/serviceComponents/ZKFC",
+          "StackServiceComponents" : {
+            "component_category" : "SLAVE",
+            "component_name" : "ZKFC",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "HDFS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HIVE",
+      "StackServices" : {
+        "comments" : "Data warehouse system for ad-hoc queries & analysis of large datasets and table & storage management service",
+        "service_name" : "HIVE",
+        "service_version" : "0.12.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "HIVE_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "HIVE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_METASTORE",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "HIVE_METASTORE",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HIVE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HIVE/serviceComponents/HIVE_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "HIVE_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HIVE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/HIVE/serviceComponents/MYSQL_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "MYSQL_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "HIVE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/MAPREDUCE2",
+      "StackServices" : {
+        "comments" : "Apache Hadoop NextGen MapReduce (YARN)",
+        "service_name" : "MAPREDUCE2",
+        "service_version" : "2.1.0.2.0.6.0",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/MAPREDUCE2/serviceComponents/HISTORYSERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "HISTORYSERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "MAPREDUCE2",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/MAPREDUCE2/serviceComponents/MAPREDUCE2_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "MAPREDUCE2_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "MAPREDUCE2",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/NAGIOS",
+      "StackServices" : {
+        "comments" : "Nagios Monitoring and Alerting system",
+        "service_name" : "NAGIOS",
+        "service_version" : "3.5.0",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/NAGIOS/serviceComponents/NAGIOS_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "NAGIOS_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "NAGIOS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/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      ",
+        "service_name" : "OOZIE",
+        "service_version" : "4.0.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "OOZIE_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "OOZIE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/OOZIE/serviceComponents/OOZIE_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "OOZIE_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "OOZIE",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/PIG",
+      "StackServices" : {
+        "comments" : "Scripting platform for analyzing large datasets",
+        "service_name" : "PIG",
+        "service_version" : "0.12.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/PIG/serviceComponents/PIG",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "PIG",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "PIG",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/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      ",
+        "service_name" : "SQOOP",
+        "service_version" : "1.4.4.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/SQOOP/serviceComponents/SQOOP",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "SQOOP",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "SQOOP",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM",
+      "StackServices" : {
+        "comments" : "Apache Hadoop Stream processing framework",
+        "service_name" : "STORM",
+        "service_version" : "0.9.0.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM/serviceComponents/DRPC_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "DRPC_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "STORM",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM/serviceComponents/LOGVIEWER_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "LOGVIEWER_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "STORM",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM/serviceComponents/NIMBUS",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "NIMBUS",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "STORM",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM/serviceComponents/STORM_REST_API",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "STORM_REST_API",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "STORM",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM/serviceComponents/STORM_UI_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "STORM_UI_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "STORM",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/STORM/serviceComponents/SUPERVISOR",
+          "StackServiceComponents" : {
+            "component_category" : "SLAVE",
+            "component_name" : "SUPERVISOR",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "STORM",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/TEZ",
+      "StackServices" : {
+        "comments" : "Tez is the next generation Hadoop Query Processing framework written on top of YARN.",
+        "service_name" : "TEZ",
+        "service_version" : "0.4.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/TEZ/serviceComponents/TEZ_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "TEZ_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "TEZ",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/WEBHCAT",
+      "StackServices" : {
+        "comments" : "This is comment for WEBHCAT service",
+        "service_name" : "WEBHCAT",
+        "service_version" : "0.12.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/WEBHCAT/serviceComponents/WEBHCAT_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "WEBHCAT_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "WEBHCAT",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/YARN",
+      "StackServices" : {
+        "comments" : "Apache Hadoop NextGen MapReduce (YARN)",
+        "service_name" : "YARN",
+        "service_version" : "2.1.0.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/YARN/serviceComponents/APP_TIMELINE_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "APP_TIMELINE_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "YARN",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/YARN/serviceComponents/NODEMANAGER",
+          "StackServiceComponents" : {
+            "component_category" : "SLAVE",
+            "component_name" : "NODEMANAGER",
+            "is_client" : false,
+            "is_master" : false,
+            "service_name" : "YARN",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/YARN/serviceComponents/RESOURCEMANAGER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "RESOURCEMANAGER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "YARN",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/YARN/serviceComponents/YARN_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "YARN_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "YARN",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/ZOOKEEPER",
+      "StackServices" : {
+        "comments" : "Centralized service which provides highly reliable distributed\n        coordination.",
+        "service_name" : "ZOOKEEPER",
+        "service_version" : "3.4.5.2.1",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1"
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/ZOOKEEPER/serviceComponents/ZOOKEEPER_CLIENT",
+          "StackServiceComponents" : {
+            "component_category" : "CLIENT",
+            "component_name" : "ZOOKEEPER_CLIENT",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "ZOOKEEPER",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        },
+        {
+          "href" : "http://localhost:8080/api/v1/stacks/HDP/versions/2.1/stackServices/ZOOKEEPER/serviceComponents/ZOOKEEPER_SERVER",
+          "StackServiceComponents" : {
+            "component_category" : "MASTER",
+            "component_name" : "ZOOKEEPER_SERVER",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "ZOOKEEPER",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 7a1304f..242ba56 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -19,9 +19,9 @@
 var App = require('app');
 
 App.ClusterController = Em.Controller.extend({
-  name:'clusterController',
-  cluster:null,
-  isLoaded:false,
+  name: 'clusterController',
+  cluster: null,
+  isLoaded: false,
   ambariProperties: null,
   ambariVersion: null,
   ambariViews: [],
@@ -30,7 +30,7 @@ App.ClusterController = Em.Controller.extend({
    * Whether we need to update statuses automatically or not
    */
   isWorking: false,
-  updateLoadStatus:function (item) {
+  updateLoadStatus: function (item) {
     var loadList = this.get('dataLoadList');
     var loaded = true;
     var numLoaded = 0;
@@ -39,12 +39,12 @@ App.ClusterController = Em.Controller.extend({
     for (var i in loadList) {
       if (loadList.hasOwnProperty(i)) {
         loadListLength++;
-        if(!loadList[i] && loaded){
+        if (!loadList[i] && loaded) {
           loaded = false;
         }
       }
       // calculate the number of true
-      if (loadList.hasOwnProperty(i) && loadList[i]){
+      if (loadList.hasOwnProperty(i) && loadList[i]) {
         numLoaded++;
       }
     }
@@ -55,6 +55,7 @@ App.ClusterController = Em.Controller.extend({
   dataLoadList:Em.Object.create({
     'hosts':false,
     'serviceMetrics':false,
+    'stackComponents':false,
     'services': false,
     'cluster':false,
     'clusterStatus':false,
@@ -66,7 +67,7 @@ App.ClusterController = Em.Controller.extend({
   /**
    * load cluster name
    */
-  loadClusterName:function (reload) {
+  loadClusterName: function (reload) {
     if (this.get('clusterName') && !reload) {
       return;
     }
@@ -78,7 +79,7 @@ App.ClusterController = Em.Controller.extend({
       error: 'loadClusterNameErrorCallback'
     });
 
-    if(!App.get('currentStackVersion')){
+    if (!App.get('currentStackVersion')) {
       App.set('currentStackVersion', App.defaultStackVersion);
     }
   },
@@ -105,7 +106,7 @@ App.ClusterController = Em.Controller.extend({
     return dfd.promise();
   },
 
-  getServerClock: function(){
+  getServerClock: function () {
     return App.ajax.send({
       name: 'ambari.service.load_server_clock',
       sender: this,
@@ -116,7 +117,7 @@ App.ClusterController = Em.Controller.extend({
   getServerClockSuccessCallback: function (data) {
     var clientClock = new Date().getTime();
     var serverClock = (data.RootServiceComponents.server_clock).toString();
-    serverClock = serverClock.length < 13? serverClock+ '000': serverClock;
+    serverClock = serverClock.length < 13 ? serverClock + '000' : serverClock;
     App.set('clockDistance', serverClock - clientClock);
     App.set('currentServerTime', parseInt(serverClock));
     console.log('loading ambari server clock distance');
@@ -125,7 +126,7 @@ App.ClusterController = Em.Controller.extend({
     console.log('Cannot load ambari server clock');
   },
 
-  getUrl:function (testUrl, url) {
+  getUrl: function (testUrl, url) {
     return (App.testMode) ? testUrl : App.apiPrefix + '/clusters/' + this.get('clusterName') + url;
   },
 
@@ -160,7 +161,7 @@ App.ClusterController = Em.Controller.extend({
       }
       return null;
     }
-  }.property('App.router.updateController.isUpdated', 'dataLoadList.hosts','gangliaWebProtocol'),
+  }.property('App.router.updateController.isUpdated', 'dataLoadList.hosts', 'gangliaWebProtocol'),
 
   /**
    * Provides the URL to use for NAGIOS server. This URL
@@ -169,7 +170,7 @@ App.ClusterController = Em.Controller.extend({
    *
    * If null is returned, it means NAGIOS service is not installed.
    */
-  nagiosUrl:function () {
+  nagiosUrl: function () {
     if (App.testMode) {
       return 'http://nagiosserver/nagios';
     } else {
@@ -194,7 +195,7 @@ App.ClusterController = Em.Controller.extend({
       }
       return null;
     }
-  }.property('App.router.updateController.isUpdated', 'dataLoadList.serviceMetrics', 'dataLoadList.hosts','nagiosWebProtocol'),
+  }.property('App.router.updateController.isUpdated', 'dataLoadList.serviceMetrics', 'dataLoadList.hosts', 'nagiosWebProtocol'),
 
   nagiosWebProtocol: function () {
     var properties = this.get('ambariProperties');
@@ -214,11 +215,11 @@ App.ClusterController = Em.Controller.extend({
     }
   }.property('ambariProperties'),
 
-  isNagiosInstalled:function () {
+  isNagiosInstalled: function () {
     return !!App.Service.find().findProperty('serviceName', 'NAGIOS');
   }.property('App.router.updateController.isUpdated', 'dataLoadList.serviceMetrics'),
 
-  isGangliaInstalled:function () {
+  isGangliaInstalled: function () {
     return !!App.Service.find().findProperty('serviceName', 'GANGLIA');
   }.property('App.router.updateController.isUpdated', 'dataLoadList.serviceMetrics'),
 
@@ -257,8 +258,8 @@ App.ClusterController = Em.Controller.extend({
    * Run <code>loadUpdatedStatus</code> with delay
    * @param delay
    */
-  loadUpdatedStatusDelayed: function(delay){
-    setTimeout(function(){
+  loadUpdatedStatusDelayed: function (delay) {
+    setTimeout(function () {
       App.updater.immediateRun('loadUpdatedStatus');
     }, delay);
   },
@@ -266,8 +267,8 @@ App.ClusterController = Em.Controller.extend({
   /**
    * Start polling, when <code>isWorking</code> become true
    */
-  startPolling: function(){
-    if(!this.get('isWorking')){
+  startPolling: function () {
+    if (!this.get('isWorking')) {
       return false;
     }
     App.updater.run(this, 'loadUpdatedStatus', 'isWorking', App.componentsUpdateInterval); //update will not run it immediately
@@ -277,7 +278,7 @@ App.ClusterController = Em.Controller.extend({
    *
    *  load all data and update load status
    */
-  loadClusterData:function () {
+  loadClusterData: function () {
     var self = this;
     this.loadAmbariProperties();
     this.loadAmbariViews();
@@ -285,7 +286,7 @@ App.ClusterController = Em.Controller.extend({
       return;
     }
 
-    if(this.get('isLoaded')) { // do not load data repeatedly
+    if (this.get('isLoaded')) { // do not load data repeatedly
       App.router.get('mainController').startPolling();
       return;
     }
@@ -294,7 +295,7 @@ App.ClusterController = Em.Controller.extend({
     var racksUrl = "/data/racks/racks.json";
 
     App.HttpClient.get(racksUrl, App.racksMapper, {
-      complete:function (jqXHR, textStatus) {
+      complete: function (jqXHR, textStatus) {
         self.updateLoadStatus('racks');
       }
     }, function (jqXHR, textStatus) {
@@ -302,53 +303,60 @@ App.ClusterController = Em.Controller.extend({
     });
 
     App.HttpClient.get(clusterUrl, App.clusterMapper, {
-      complete:function (jqXHR, textStatus) {
+      complete: function (jqXHR, textStatus) {
         self.updateLoadStatus('cluster');
       }
     }, function (jqXHR, textStatus) {
-        self.updateLoadStatus('cluster');
+      self.updateLoadStatus('cluster');
     });
 
     if (App.testMode) {
       self.updateLoadStatus('clusterStatus');
     } else {
-      App.clusterStatus.updateFromServer(true).complete(function() {
+      App.clusterStatus.updateFromServer(true).complete(function () {
         self.updateLoadStatus('clusterStatus');
       });
     }
-    
+
     App.HttpClient.get(usersUrl, App.usersMapper, {
-      complete:function (jqXHR, textStatus) {
+      complete: function (jqXHR, textStatus) {
         self.updateLoadStatus('users');
       }
     }, function (jqXHR, textStatus) {
-        self.updateLoadStatus('users');
+      self.updateLoadStatus('users');
     });
 
     /**
      * Order of loading:
-     * 1. request for services
-     * 2. put services in cache
-     * 3. request for hosts and host-components (single call)
-     * 4. request for service metrics
-     * 5. load host-components to model
-     * 6. load hosts to model
-     * 7. load services from cache with metrics to model
-     * 8. update stale_configs of host-components (depends on App.supports.hostOverrides)
+     * 1. request for service components supported by stack
+     * 2. load stack components to model
+     * 3. request for services
+     * 4. put services in cache
+     * 5. request for hosts and host-components (single call)
+     * 6. request for service metrics
+     * 7. load host-components to model
+     * 8. load hosts to model
+     * 9. load services from cache with metrics to model
+     * 10. update stale_configs of host-components (depends on App.supports.hostOverrides)
      */
-    App.router.get('updateController').updateServices(function () {
-      self.updateLoadStatus('services');
-      self.loadUpdatedStatus(function () {
-        self.updateLoadStatus('hosts');
-        if (App.supports.hostOverrides) {
-          App.router.get('updateController').updateComponentConfig(function () {
+    this.loadStackServiceComponents(function (data) {
+      require('utils/component').loadStackServiceComponentModel(data);
+      self.updateLoadStatus('stackComponents');
+      App.router.get('updateController').updateServices(function () {
+        self.updateLoadStatus('services');
+        self.loadUpdatedStatus(function () {
+          self.updateLoadStatus('hosts');
+          if (App.supports.hostOverrides) {
+            App.router.get('updateController').updateComponentConfig(function () {
+              self.updateLoadStatus('componentConfigs');
+            });
+          } else {
             self.updateLoadStatus('componentConfigs');
-          });
-        } else {
-          self.updateLoadStatus('componentConfigs');
-        }
-      }, true);
-      App.router.get('updateController').updateServiceMetric(function () {}, true);
+          }
+        }, true);
+        App.router.get('updateController').updateServiceMetric(function () {
+        }, true);
+      });
     });
   },
   /**
@@ -376,8 +384,8 @@ App.ClusterController = Em.Controller.extend({
     }
   },
 
-  requestHosts: function(realUrl, callback){
-    var testHostUrl =  App.get('isHadoop2Stack') ? '/data/hosts/HDP2/hosts.json':'/data/hosts/hosts.json';
+  requestHosts: function (realUrl, callback) {
+    var testHostUrl = App.get('isHadoop2Stack') ? '/data/hosts/HDP2/hosts.json' : '/data/hosts/hosts.json';
     var url = this.getUrl(testHostUrl, realUrl);
     App.HttpClient.get(url, App.hostsMapper, {
       complete: callback
@@ -418,7 +426,27 @@ App.ClusterController = Em.Controller.extend({
     }, this);
   },
 
-  loadAmbariProperties: function() {
+  /**
+   *
+   * @param callback
+   */
+  loadStackServiceComponents: function(callback) {
+    var callbackObj = {
+      loadStackServiceComponentsSuccess: callback
+    };
+    App.ajax.send({
+      name: 'wizard.service_components',
+      data: {
+        stackUrl: App.get('stack2VersionURL'),
+        stackVersion: App.get('currentStackVersionNumber'),
+        async: true
+      },
+      sender: callbackObj,
+      success: 'loadStackServiceComponentsSuccess'
+    });
+  },
+
+  loadAmbariProperties: function () {
     App.ajax.send({
       name: 'ambari.service',
       sender: this,
@@ -428,25 +456,26 @@ App.ClusterController = Em.Controller.extend({
     return this.get('ambariProperties');
   },
 
-  loadAmbariPropertiesSuccess: function(data) {
+  loadAmbariPropertiesSuccess: function (data) {
     console.log('loading ambari properties');
     this.set('ambariProperties', data.RootServiceComponents.properties);
     this.set('ambariVersion', data.RootServiceComponents.component_version);
   },
 
-  loadAmbariPropertiesError: function() {
+  loadAmbariPropertiesError: function () {
     console.warn('can\'t get ambari properties');
   },
 
-  clusterName:function () {
+  clusterName: function () {
     return (this.get('cluster')) ? this.get('cluster').Clusters.cluster_name : null;
   }.property('cluster'),
-  
+
   updateClusterData: function () {
-    var testUrl = App.get('isHadoop2Stack') ? '/data/clusters/HDP2/cluster.json':'/data/clusters/cluster.json';
+    var testUrl = App.get('isHadoop2Stack') ? '/data/clusters/HDP2/cluster.json' : '/data/clusters/cluster.json';
     var clusterUrl = this.getUrl(testUrl, '?fields=Clusters');
     App.HttpClient.get(clusterUrl, App.clusterMapper, {
-      complete:function(){}
+      complete: function () {
+      }
     });
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index bfcd1ca..4cc7b8f 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -181,6 +181,18 @@ 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: [],
 
   /**
@@ -429,14 +441,14 @@ App.InstallerController = App.WizardController.extend({
    */
   saveClients: function (stepController) {
     var clients = [];
-    var serviceComponents = require('data/service_components');
+    var serviceComponents = App.StackServiceComponent.find();
 
     stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) {
-      var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
+      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient', true);
       if (client) {
         clients.pushObject({
-          component_name: client.component_name,
-          display_name: client.display_name,
+          component_name: client.get('componentName'),
+          display_name: client.get('displayName'),
           isInstalled: false
         });
       }
@@ -561,6 +573,7 @@ App.InstallerController = App.WizardController.extend({
         this.loadConfirmedHosts();
       case '4':
         this.loadServices();
+        this.loadServiceComponentsDb();
       case '3':
         this.loadConfirmedHosts();
       case '2':

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 179c92a..ab282c1 100644
--- a/ambari-web/app/controllers/main/host/add_controller.js
+++ b/ambari-web/app/controllers/main/host/add_controller.js
@@ -57,8 +57,6 @@ App.AddHostController = App.WizardController.extend({
     configGroups: null
   }),
 
-  components:require('data/service_components'),
-
   setCurrentStep: function (currentStep, completed) {
     this._super(currentStep, completed);
     App.clusterStatus.setClusterStatus({
@@ -175,14 +173,14 @@ App.AddHostController = App.WizardController.extend({
     });
 
     headers.forEach(function(header) {
-      var component = self.get('components').findProperty('component_name', header.get('name'));
+      var component = App.StackServiceComponent.find().findProperty('componentName', header.get('name'));
       hosts.forEach(function(host) {
         if (host.get('checkboxes').findProperty('title', component.display_name).checked) {
           masterComponentHosts .push({
-            display_name: component.display_name,
-            component: component.component_name,
+            display_name: component.get('displayName'),
+            component: component.get('componentName'),
             hostName: host.get('hostName'),
-            serviceId: component.service_name,
+            serviceId: component.get('serviceName'),
             isInstalled: false
           });
         }
@@ -230,16 +228,16 @@ App.AddHostController = App.WizardController.extend({
    */
   saveClients: function () {
     var clients = [];
-    var serviceComponents = require('data/service_components');
+    var serviceComponents = App.StackServiceComponent.find();
     var hostComponents = App.HostComponent.find();
 
     this.get('content.services').filterProperty('isSelected', true).forEach(function (_service) {
-      var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
+      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient', true);
       if (client) {
         clients.pushObject({
-          component_name: client.component_name,
-          display_name: client.display_name,
-          isInstalled: hostComponents.filterProperty('componentName', client.component_name).length > 0
+          component_name: client.get('componentName'),
+          display_name: client.get('displayName'),
+          isInstalled: hostComponents.filterProperty('componentName', client.get('componentName')).length > 0
         });
       }
     }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 8b1ce05..8ce5411 100644
--- a/ambari-web/app/controllers/main/service/add_controller.js
+++ b/ambari-web/app/controllers/main/service/add_controller.js
@@ -275,16 +275,16 @@ App.AddServiceController = App.WizardController.extend({
    */
   saveClients: function(stepController){
     var clients = [];
-    var serviceComponents = require('data/service_components');
+    var serviceComponents = App.StackServiceComponent.find();
     var hostComponents = App.HostComponent.find();
 
     stepController.get('content').filterProperty('isSelected',true).forEach(function (_service) {
-      var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true);
+      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient', true);
       if (client) {
         clients.pushObject({
-          component_name: client.component_name,
-          display_name: client.display_name,
-          isInstalled: hostComponents.filterProperty('componentName', client.component_name).length > 0
+          component_name: client.get('componentName'),
+          display_name: client.get('displayName'),
+          isInstalled: hostComponents.filterProperty('componentName', client.get('componentName')).length > 0
         });
       }
     }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 f78a57b..dff7fd7 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -17,7 +17,6 @@
  */
 
 var App = require('app');
-var service_components = require('data/service_components');
 var batchUtils = require('utils/batch_scheduled_requests');
 
 App.MainServiceItemController = Em.Controller.extend({

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
index bcd7e15..da26ac3 100644
--- a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
+++ b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
@@ -20,7 +20,6 @@
 var App = require('app');
 var hostsManagement = require('utils/hosts');
 var componentHelper = require('utils/component');
-var serviceComponents = require('data/service_components');
 
 App.ManageConfigGroupsController = Em.Controller.extend({
   name: 'manageConfigGroupsController',
@@ -252,7 +251,7 @@ App.ManageConfigGroupsController = Em.Controller.extend({
    * @return {Array}
    */
   componentsForFilter: function () {
-    return serviceComponents.filterProperty('service_name', this.get('serviceName')).map(function (component) {
+    return App.StackServiceComponent.find().filterProperty('serviceName', this.get('serviceName')).map(function (component) {
       return Em.Object.create({
         displayName: component.display_name,
         componentName: component.isClient ? 'CLIENT' : component.component_name,

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 4affb3b..f39f024 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -40,10 +40,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
 
   slaveComponents: function () {
-    return require('data/service_components').filter(function (component) {
-      return !(component.isClient || component.isMaster ||
-        ["GANGLIA_MONITOR", "DASHBOARD", "MYSQL_SERVER"].contains(component.component_name));
-    });
+    return App.StackServiceComponent.find().filterProperty('isSlave',true);
   }.property(),
 
   allHosts: App.Host.find(),
@@ -414,6 +411,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     this.setDBProperty('allHostNames', undefined);
     this.setDBProperty('installOptions', undefined);
     this.setDBProperty('allHostNamesPattern', undefined);
+    this.setDBProperty('serviceComponents', undefined);
   },
 
   installOptionsTemplate: {
@@ -439,7 +437,8 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       sender: this,
       data: {
         stackUrl: App.get('stack2VersionURL'),
-        stackVersion: App.get('currentStackVersionNumber')
+        stackVersion: App.get('currentStackVersionNumber'),
+        async: false
       },
       success: 'loadServiceComponentsSuccessCallback',
       error: 'loadServiceComponentsErrorCallback'
@@ -448,10 +447,24 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
 
   loadServiceComponentsSuccessCallback: function (jsonData) {
-    var displayOrderConfig = require('data/services');
+    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);
+  },
+
+  loadServiceComponentsErrorCallback: function (request, ajaxOptions, error) {
+    console.log("TRACE: STep5 -> In error function for the getServiceComponents call");
+    console.log("TRACE: STep5 -> error code status is: " + request.status);
+    console.log('Step8: Error message is: ' + request.responseText);
+  },
 
+  /**
+   *
+   * @param jsonData
+   */
+  setServices: function(jsonData) {
+    var displayOrderConfig = require('data/services');
     // Creating Model
     var Service = Ember.Object.extend({
       serviceName: null,
@@ -488,14 +501,15 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     }
 
     this.set('loadedServiceComponents', data);
-    console.log('TRACE: service components: ' + JSON.stringify(data));
-
   },
 
-  loadServiceComponentsErrorCallback: function (request, ajaxOptions, error) {
-    console.log("TRACE: STep5 -> In error function for the getServiceComponents call");
-    console.log("TRACE: STep5 -> error code status is: " + request.status);
-    console.log('Step8: Error message is: ' + request.responseText);
+  /**
+   *
+   * @param jsonData
+   */
+  setServiceComponents: function(jsonData) {
+    var serviceComponents = require('utils/component').loadStackServiceComponentModel(jsonData);
+    this.setDBProperty('serviceComponents', serviceComponents);
   },
 
   loadServicesFromServer: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 40c1f99..cbe7aba 100644
--- a/ambari-web/app/controllers/wizard/step5_controller.js
+++ b/ambari-web/app/controllers/wizard/step5_controller.js
@@ -70,8 +70,6 @@ App.WizardStep5Controller = Em.Controller.extend({
   servicesMasters:[],
   selectedServicesMasters:[],
 
-  components:require('data/service_components'),
-
   clearStep:function () {
     this.set('hosts', []);
     this.set('selectedServicesMasters', []);
@@ -162,55 +160,52 @@ App.WizardStep5Controller = Em.Controller.extend({
     var services = this.get('content.services')
       .filterProperty('isSelected', true).mapProperty('serviceName'); //list of shown services
 
-    var masterComponents = this.get('components').filterProperty('isMaster', true); //get full list from mock data
+    var masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnInstallerAssignMasterPage', true); //get full list from mock data
     var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info
 
     var resultComponents = [];
 
     var servicesLength = services.length;
     for (var index = 0; index < servicesLength; index++) {
-      var componentInfo = masterComponents.filterProperty('service_name', services[index]);
+      var componentInfo = masterComponents.filterProperty('serviceName', services[index]);
 
       componentInfo.forEach(function (_componentInfo) {
-        if (_componentInfo.component_name == 'ZOOKEEPER_SERVER' || _componentInfo.component_name == 'HBASE_MASTER') {
-          var savedComponents = masterHosts.filterProperty('component', _componentInfo.component_name);
+        if (_componentInfo.get('componentName') == 'ZOOKEEPER_SERVER' || _componentInfo.get('componentName') == 'HBASE_MASTER') {
+          var savedComponents = masterHosts.filterProperty('component', _componentInfo.get('componentName'));
           if (savedComponents.length) {
-
             savedComponents.forEach(function (item) {
-              var zooKeeperHost = {};
-              zooKeeperHost.display_name = _componentInfo.display_name;
-              zooKeeperHost.component_name = _componentInfo.component_name;
-              zooKeeperHost.selectedHost = item.hostName;
-              zooKeeperHost.serviceId = services[index];
-              zooKeeperHost.isInstalled = item.isInstalled;
-              zooKeeperHost.isHiveCoHost = false;
-              resultComponents.push(zooKeeperHost);
+              var multipleMasterHost = {};
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
+              multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.selectedHost = item.hostName;
+              multipleMasterHost.serviceId = services[index];
+              multipleMasterHost.isInstalled = item.isInstalled;
+              multipleMasterHost.isHiveCoHost = false;
+              resultComponents.push(multipleMasterHost);
             })
-
           } else {
-
-            var zooHosts = this.selectHost(_componentInfo.component_name);
+            var zooHosts = this.selectHost(_componentInfo.get('componentName'));
             zooHosts.forEach(function (_host) {
-              var zooKeeperHost = {};
-              zooKeeperHost.display_name = _componentInfo.display_name;
-              zooKeeperHost.component_name = _componentInfo.component_name;
-              zooKeeperHost.selectedHost = _host;
-              zooKeeperHost.serviceId = services[index];
-              zooKeeperHost.isInstalled = false;
-              zooKeeperHost.isHiveCoHost = false;
-              resultComponents.push(zooKeeperHost);
+              var multipleMasterHost = {};
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
+              multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.selectedHost = _host;
+              multipleMasterHost.serviceId = services[index];
+              multipleMasterHost.isInstalled = false;
+              multipleMasterHost.isHiveCoHost = false;
+              resultComponents.push(multipleMasterHost);
             });
 
           }
         } else {
-          var savedComponent = masterHosts.findProperty('component', _componentInfo.component_name);
+          var savedComponent = masterHosts.findProperty('component', _componentInfo.get('componentName'));
           var componentObj = {};
-          componentObj.component_name = _componentInfo.component_name;
-          componentObj.display_name = _componentInfo.display_name;
-          componentObj.selectedHost = savedComponent ? savedComponent.hostName : this.selectHost(_componentInfo.component_name);   // call the method that plays selectNode algorithm or fetches from server
+          componentObj.component_name = _componentInfo.get('componentName');
+          componentObj.display_name = _componentInfo.get('displayName');
+          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 = ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(_componentInfo.component_name) && !this.get('isReassignWizard');
+          componentObj.isHiveCoHost = ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(_componentInfo.get('componentName')) && !this.get('isReassignWizard');
           resultComponents.push(componentObj);
         }
       }, this);
@@ -227,7 +222,7 @@ App.WizardStep5Controller = Em.Controller.extend({
     var self = this;
     var services = this.get('content.services')
       .filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
-    var showRemoveControlZk = !services.contains('ZOOKEEPER') && masterComponents.filterProperty('display_name', 'ZooKeeper').length > 1;
+    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;
     var hid = 1;
@@ -247,7 +242,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       var componentObj = Ember.Object.create(item);
       console.log("TRACE: render master component name is: " + item.component_name);
 
-      if (item.display_name === "ZooKeeper") {
+      if (item.component_name === "ZOOKEEPER_SERVER") {
         componentObj.set('zId', zid++);
         componentObj.set("showRemoveControl", showRemoveControlZk);
       } else if (App.supports.multipleHBaseMasters && item.component_name === "HBASE_MASTER") {
@@ -454,7 +449,6 @@ App.WizardStep5Controller = Em.Controller.extend({
     var mapping = [], mappingObject, mappedHosts, hostObj;
     //get the unique assigned hosts and find the master services assigned to them
     mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq();
-
     mappedHosts.forEach(function (item) {
       hostObj = this.get("hosts").findProperty("host_name", item);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 b7f4639..f8af7a6 100644
--- a/ambari-web/app/controllers/wizard/step6_controller.js
+++ b/ambari-web/app/controllers/wizard/step6_controller.js
@@ -53,7 +53,6 @@ App.WizardStep6Controller = Em.Controller.extend({
   isMasters: false,
   isLoaded: false,
 
-  components: require('data/service_components'),
 
   isAddHostWizard: function () {
     return this.get('content.controllerName') === 'addHostController';
@@ -187,7 +186,7 @@ App.WizardStep6Controller = Em.Controller.extend({
   },
 
   getComponentDisplayName: function (componentName) {
-    return this.get('components').findProperty('component_name', componentName).display_name
+    return App.StackServiceComponent.find().findProperty('componentName', componentName).get('displayName')
   },
 
   loadStep: function () {
@@ -252,7 +251,7 @@ App.WizardStep6Controller = Em.Controller.extend({
       }
       headers.pushObject(Ember.Object.create({
         name: 'CLIENT',
-        label: self.getComponentDisplayName('CLIENT')
+        label: App.format.role('CLIENT')
       }));
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 b7a9cfd..51b7f41 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -632,7 +632,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     var selectedServiceName = this.get('selectedService.serviceName');
     var masterComponents = this.get('content.masterComponentHosts');
     var slaveComponents = this.get('content.slaveComponentHosts');
-    var scMaps = require('data/service_components');
+    var scMaps = App.StackServiceComponent.find();
     
     var validComponents = Ember.A([]);
     var seenComponents = {};
@@ -651,8 +651,8 @@ App.WizardStep7Controller = Em.Controller.extend({
     slaveComponents.forEach(function(component){
       var cn = component.componentName;
       var cdn = component.displayName;
-      var componentDef = scMaps.findProperty('component_name', cn);
-      if(componentDef!=null && selectedServiceName===componentDef.service_name && !seenComponents[cn]){
+      var componentDef = scMaps.findProperty('componentName', cn);
+      if(!!componentDef && selectedServiceName===componentDef.get('serviceName') && !seenComponents[cn]){
         validComponents.pushObject(Ember.Object.create({
           componentName: cn,
           displayName: cdn,

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 9958dda..5571a36 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -954,11 +954,11 @@ App.WizardStep8Controller = Em.Controller.extend({
    * One request for each service!
    */
   createComponents: function () {
-    var serviceComponents = require('data/service_components');
+    var serviceComponents = App.StackServiceComponent.find();
     this.get('selectedServices').forEach(function (_service) {
       var serviceName = _service.get('serviceName');
-      var componentsData = serviceComponents.filterProperty('service_name', serviceName).map(function (_component) {
-        return { "ServiceComponentInfo": { "component_name": _component.component_name } };
+      var componentsData = serviceComponents.filterProperty('serviceName', serviceName).map(function (_component) {
+        return { "ServiceComponentInfo": { "component_name": _component.get('componentName') } };
       });
 
       // Service must be specified in terms of a query for creating multiple components at the same time.
@@ -969,7 +969,6 @@ App.WizardStep8Controller = Em.Controller.extend({
         data: JSON.stringify({"components": componentsData})
       });
     }, this);
-
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 5a133ed..876096b 100644
--- a/ambari-web/app/controllers/wizard/step9_controller.js
+++ b/ambari-web/app/controllers/wizard/step9_controller.js
@@ -16,7 +16,6 @@
  * limitations under the License.
  */
 var App = require('app');
-var serviceComponents = require('data/service_components');
 
 App.WizardStep9Controller = Em.Controller.extend({
   name: 'wizardStep9Controller',
@@ -476,8 +475,8 @@ App.WizardStep9Controller = Em.Controller.extend({
       var OnlyClients = true;
       var tasks = host.get('logTasks');
       tasks.forEach(function (task) {
-        var component = serviceComponents.findProperty('component_name', task.Tasks.role);
-        if (!(component && component.isClient)) {
+        var component = App.StackServiceComponent.find().findProperty('componentName', task.Tasks.role);
+        if (!(component && component.get('isClient'))) {
           OnlyClients = false;
         }
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/29e61ae9/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 a3eedaa..0b61e77 100644
--- a/ambari-web/app/data/HDP2/global_properties.js
+++ b/ambari-web/app/data/HDP2/global_properties.js
@@ -79,7 +79,7 @@ require('config');
 module.exports =
 {
   "configProperties": [
-    /**********************************************HDFS***************************************/
+  /**********************************************HDFS***************************************/
     {
       "id": "puppet var",
       "name": "namenode_host",
@@ -397,35 +397,34 @@ module.exports =
       "serviceName": "YARN",
       "category": "Advanced"
     },
-// @todo uncomment after App Timeline service integration
-//    {
-//      "id": "puppet var",
-//      "name": "ats_host",
-//      "displayName": "App Timeline Server",
-//      "description": "Application Timeline Server Host",
-//      "defaultValue": "",
-//      "isOverridable": false,
-//      "displayType": "masterHost",
-//      "isRequiredByAgent": false,
-//      "isVisible": true,
-//      "serviceName": "YARN",
-//      "category": "AppTimelineServer",
-//      "index": 0
-//    },
-//    {
-//      "id": "puppet var",
-//      "name": "apptimelineserver_heapsize",
-//      "displayName": "AppTimelineServer Java heap size",
-//      "description": "AppTimelineServer Java heap size",
-//      "defaultValue": "1024",
-//      "isOverridable": false,
-//      "displayType": "int",
-//      "unit": "MB",
-//      "isVisible": true,
-//      "serviceName": "YARN",
-//      "category": "AppTimelineServer",
-//      "index": 1
-//    }
+    {
+      "id": "puppet var",
+      "name": "ats_host",
+      "displayName": "App Timeline Server",
+      "description": "Application Timeline Server Host",
+      "defaultValue": "",
+      "isOverridable": false,
+      "displayType": "masterHost",
+      "isRequiredByAgent": false,
+      "isVisible": true,
+      "serviceName": "YARN",
+      "category": "AppTimelineServer",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "apptimelineserver_heapsize",
+      "displayName": "AppTimelineServer Java heap size",
+      "description": "AppTimelineServer Java heap size",
+      "defaultValue": "1024",
+      "isOverridable": false,
+      "displayType": "int",
+      "unit": "MB",
+      "isVisible": true,
+      "serviceName": "YARN",
+      "category": "AppTimelineServer",
+      "index": 1
+    },
   /**********************************************HBASE***************************************/
     {
       "id": "puppet var",
@@ -513,7 +512,7 @@ module.exports =
       "serviceName": "HBASE",
       "category": "Advanced"
     },
-    /**********************************************GLUSTERFS***************************************/
+  /**********************************************GLUSTERFS***************************************/
     {
       "id": "puppet var",
       "name": "glusterfs_defaultFS_name",
@@ -527,30 +526,30 @@ module.exports =
       "category": "General"
     },
     {
-        "id": "puppet var",
-        "name": "fs_glusterfs_default_name",
-        "displayName": "GlusterFS default fs name",
-        "description": "GlusterFS default filesystem name (glusterfs:///)",
-        "defaultValue": "glusterfs:///",
-        "displayType": "string",
-        "isVisible": true,
-        "domain": "global",
-        "serviceName": "GLUSTERFS",
-        "category": "General"
-      },
-          {
-            "id": "puppet var",
-            "name": "hadoop_heapsize",
-            "displayName": "Hadoop maximum Java heap size",
-            "description": "Maximum Java heap size for daemons such as Balancer (Java option -Xmx)",
-            "defaultValue": "1024",
-            "displayType": "int",
-            "unit": "MB",
-            "isVisible": true,
-            "domain": "global",
-            "serviceName": "GLUSTERFS",
-            "category": "General"
-          },
+      "id": "puppet var",
+      "name": "fs_glusterfs_default_name",
+      "displayName": "GlusterFS default fs name",
+      "description": "GlusterFS default filesystem name (glusterfs:///)",
+      "defaultValue": "glusterfs:///",
+      "displayType": "string",
+      "isVisible": true,
+      "domain": "global",
+      "serviceName": "GLUSTERFS",
+      "category": "General"
+    },
+    {
+      "id": "puppet var",
+      "name": "hadoop_heapsize",
+      "displayName": "Hadoop maximum Java heap size",
+      "description": "Maximum Java heap size for daemons such as Balancer (Java option -Xmx)",
+      "defaultValue": "1024",
+      "displayType": "int",
+      "unit": "MB",
+      "isVisible": true,
+      "domain": "global",
+      "serviceName": "GLUSTERFS",
+      "category": "General"
+    },
 
   /**********************************************HIVE***************************************/
     {
@@ -971,10 +970,10 @@ module.exports =
           foreignKeys: ['oozie_derby_database']
         },
         /*{
-          displayName: 'New MySQL Database',
-          foreignKeys: ['oozie_ambari_database', 'oozie_ambari_host'],
-          hidden: !App.supports.hiveOozieExtraDatabases
-        },*/
+         displayName: 'New MySQL Database',
+         foreignKeys: ['oozie_ambari_database', 'oozie_ambari_host'],
+         hidden: !App.supports.hiveOozieExtraDatabases
+         },*/
         {
           displayName: 'Existing MySQL Database',
           foreignKeys: ['oozie_existing_mysql_database', 'oozie_existing_mysql_host'],
@@ -1542,7 +1541,7 @@ module.exports =
       "isRequiredByAgent": false,
       "serviceName": "MISC",
       "category": "General",
-      "belongsToService":[]
+      "belongsToService": []
     },
     {
       "id": "puppet var",
@@ -1557,7 +1556,7 @@ module.exports =
       "filename": "core-site.xml",
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HIVE","WEBHCAT","OOZIE","FALCON"],
+      "belongsToService": ["HIVE", "WEBHCAT", "OOZIE", "FALCON"],
       "index": 18
     },
     {
@@ -1571,7 +1570,7 @@ module.exports =
       "isVisible": false,
       "serviceName": "MISC",
       "category": "General",
-      "belongsToService":[]
+      "belongsToService": []
     },
     {
       "id": "puppet var",
@@ -1585,7 +1584,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HDFS"],
+      "belongsToService": ["HDFS"],
       "index": 1
     },
     {
@@ -1600,7 +1599,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["MAPREDUCE2"],
+      "belongsToService": ["MAPREDUCE2"],
       "index": 2
     },
     {
@@ -1615,7 +1614,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["YARN"],
+      "belongsToService": ["YARN"],
       "index": 3
     },
     {
@@ -1630,7 +1629,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HBASE"],
+      "belongsToService": ["HBASE"],
       "index": 4
     },
     {
@@ -1645,7 +1644,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HIVE"],
+      "belongsToService": ["HIVE"],
       "index": 5
     },
     {
@@ -1660,7 +1659,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HCATALOG"],
+      "belongsToService": ["HCATALOG"],
       "index": 6
     },
     {
@@ -1675,7 +1674,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["WEBHCAT"],
+      "belongsToService": ["WEBHCAT"],
       "index": 7
     },
     {
@@ -1690,7 +1689,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["OOZIE"],
+      "belongsToService": ["OOZIE"],
       "index": 8
     },
     {
@@ -1703,9 +1702,9 @@ module.exports =
       "displayType": "user",
       "isOverridable": false,
       "isVisible": true,
-      "serviceName":"MISC",
+      "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["FALCON"],
+      "belongsToService": ["FALCON"],
       "index": 10
     },
     {
@@ -1718,9 +1717,9 @@ module.exports =
       "displayType": "user",
       "isOverridable": false,
       "isVisible": true,
-      "serviceName":"MISC",
+      "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["STORM"],
+      "belongsToService": ["STORM"],
       "index": 9
     },
     {
@@ -1735,7 +1734,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["ZOOKEEPER"],
+      "belongsToService": ["ZOOKEEPER"],
       "index": 11
     },
     {
@@ -1750,7 +1749,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["GANGLIA"],
+      "belongsToService": ["GANGLIA"],
       "index": 12
     },
     {
@@ -1763,9 +1762,9 @@ module.exports =
       "displayType": "advanced",
       "isOverridable": false,
       "isVisible": false,
-      "serviceName":"MISC",
+      "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":[]
+      "belongsToService": []
     },
     {
       "id": "puppet var",
@@ -1777,9 +1776,9 @@ module.exports =
       "displayType": "user",
       "isOverridable": false,
       "isVisible": true,
-      "serviceName":"MISC",
+      "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["NAGIOS"],
+      "belongsToService": ["NAGIOS"],
       "index": 14
     },
     {
@@ -1792,9 +1791,9 @@ module.exports =
       "displayType": "user",
       "isOverridable": false,
       "isVisible": true,
-      "serviceName":"MISC",
+      "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["NAGIOS"],
+      "belongsToService": ["NAGIOS"],
       "index": 13
     },
     {
@@ -1809,7 +1808,7 @@ module.exports =
       "isVisible": App.supports.customizeSmokeTestUser,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HDFS"],
+      "belongsToService": ["HDFS"],
       "index": 16
     },
     {
@@ -1822,9 +1821,9 @@ module.exports =
       "displayType": "user",
       "isOverridable": false,
       "isVisible": true,
-      "serviceName":"MISC",
+      "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["TEZ"],
+      "belongsToService": ["TEZ"],
       "index": 15
     },
     {
@@ -1839,7 +1838,7 @@ module.exports =
       "isVisible": true,
       "serviceName": "MISC",
       "category": "Users and Groups",
-      "belongsToService":["HDFS"],
+      "belongsToService": ["HDFS"],
       "index": 16
     },
     {
@@ -1854,41 +1853,8 @@ module.exports =
       "isVisible": true,
       "serviceName": "GANGLIA",
       "category": "General",
-      "belongsToService":["GANGLIA"]
+      "belongsToService": ["GANGLIA"]
     }
 
   ]
 };
-// @todo remove after App Timeline service integration
-if (App.supports.appTimelineServer) {
-  module.exports.configProperties.push(
-    {
-      "id": "puppet var",
-      "name": "ats_host",
-      "displayName": "App Timeline Server",
-      "description": "Application Timeline Server Host",
-      "defaultValue": "",
-      "isOverridable": false,
-      "displayType": "masterHost",
-      "isRequiredByAgent": false,
-      "isVisible": true,
-      "serviceName": "YARN",
-      "category": "AppTimelineServer",
-      "index": 0
-    },
-    {
-      "id": "puppet var",
-      "name": "apptimelineserver_heapsize",
-      "displayName": "AppTimelineServer Java heap size",
-      "description": "AppTimelineServer Java heap size",
-      "defaultValue": "1024",
-      "isOverridable": false,
-      "displayType": "int",
-      "unit": "MB",
-      "isVisible": true,
-      "serviceName": "YARN",
-      "category": "AppTimelineServer",
-      "index": 1
-    }
-  );
-}