You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2014/07/16 19:11:00 UTC

git commit: AMBARI-6509 New service added to stack should have a default summary page. (Buzhor Denys via atkach)

Repository: ambari
Updated Branches:
  refs/heads/trunk 87db0903c -> 298bb53d6


AMBARI-6509 New service added to stack should have a default summary page. (Buzhor Denys via atkach)


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

Branch: refs/heads/trunk
Commit: 298bb53d6a68d309f7c0539b02aa52222531b864
Parents: 87db090
Author: atkach <at...@hortonworks.com>
Authored: Wed Jul 16 20:09:14 2014 +0300
Committer: atkach <at...@hortonworks.com>
Committed: Wed Jul 16 20:09:14 2014 +0300

----------------------------------------------------------------------
 .../app/controllers/global/update_controller.js |   2 +-
 .../app/controllers/wizard/step7_controller.js  |   1 +
 .../app/mappers/components_state_mapper.js      |  32 ++++
 .../app/mappers/service_metrics_mapper.js       |   4 +-
 ambari-web/app/messages.js                      |   1 +
 ambari-web/app/models.js                        |   2 +
 ambari-web/app/models/client_component.js       |  43 ++++++
 ambari-web/app/models/service.js                |   5 +-
 ambari-web/app/models/slave_component.js        |  28 ++++
 ambari-web/app/templates.js                     |  12 +-
 .../app/templates/main/service/info/summary.hbs |  59 +------
 .../main/service/info/summary/base.hbs          |  21 +++
 .../service/info/summary/client_components.hbs  |  30 ++++
 .../main/service/info/summary/falcon.hbs        |  26 ----
 .../main/service/info/summary/ganglia.hbs       |  32 ----
 .../main/service/info/summary/glusterfs.hbs     |  23 ---
 .../main/service/info/summary/hive.hbs          |  26 ----
 .../templates/main/service/info/summary/hue.hbs |  20 ---
 .../main/service/info/summary/mapreduce2.hbs    |  25 ---
 .../service/info/summary/master_components.hbs  |  14 +-
 .../main/service/info/summary/oozie.hbs         |  28 ----
 .../templates/main/service/info/summary/pig.hbs |  23 ---
 .../service/info/summary/slave_components.hbs   |  33 ++++
 .../main/service/info/summary/sqoop.hbs         |  23 ---
 .../templates/main/service/info/summary/tez.hbs |  23 ---
 .../main/service/info/summary/zookeeper.hbs     |  27 ----
 .../templates/main/service/services/storm.hbs   |   2 +-
 ambari-web/app/utils/helper.js                  |  58 ++++++-
 ambari-web/app/utils/string_utils.js            |  11 +-
 ambari-web/app/views.js                         |   1 +
 .../main/service/info/components_list_view.js   |  37 +++++
 .../app/views/main/service/info/summary.js      | 153 ++++++++-----------
 32 files changed, 377 insertions(+), 448 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index 7d21f1b..4b35224 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -429,7 +429,7 @@ App.UpdateController = Em.Controller.extend({
   updateComponentsState: function (callback) {
     var testUrl = '/data/services/HDP2/components_state.json';
     var realUrl = '/components/?ServiceComponentInfo/category.in(SLAVE,CLIENT)&fields=ServiceComponentInfo/service_name,' +
-      'ServiceComponentInfo/installed_count,ServiceComponentInfo/started_count,ServiceComponentInfo/total_count&minimal_response=true';
+      'ServiceComponentInfo/category,ServiceComponentInfo/installed_count,ServiceComponentInfo/started_count,ServiceComponentInfo/total_count&minimal_response=true';
     var url = this.getUrl(testUrl, realUrl);
 
     App.HttpClient.get(url, App.componentsStateMapper, {

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/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 357b54a..a57ee77 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -775,6 +775,7 @@ App.WizardStep7Controller = Em.Controller.extend({
   getConfigTagsSuccess: function (data) {
     var installedServiceSites = [];
     App.StackService.find().filterProperty('isInstalled').forEach(function (service) {
+      if (!service.get('configTypes')) return;
       var configTypes = Object.keys(service.get('configTypes'));
       installedServiceSites = installedServiceSites.concat(configTypes);
     }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/mappers/components_state_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/components_state_mapper.js b/ambari-web/app/mappers/components_state_mapper.js
index 0a63a28..803bba9 100644
--- a/ambari-web/app/mappers/components_state_mapper.js
+++ b/ambari-web/app/mappers/components_state_mapper.js
@@ -21,6 +21,21 @@ var stringUtils = require('utils/string_utils');
 App.componentsStateMapper = App.QuickDataMapper.create({
 
   model: App.Service,
+
+  clientModel: App.ClientComponent,
+  clientMap: {
+    id: 'ServiceComponentInfo.component_name',
+    service_id: 'ServiceComponentInfo.service_name',
+    stack_info_id: 'ServiceComponentInfo.component_name',
+    component_name: 'ServiceComponentInfo.component_name',
+    service_name: 'ServiceComponentInfo.service_name',
+    installed_count: 'ServiceComponentInfo.installed_count',
+    started_count: 'ServiceComponentInfo.started_count',
+    total_count: 'ServiceComponentInfo.total_count'
+  },
+
+  slaveModel: App.SlaveComponent,
+
   paths: {
     INSTALLED_PATH: 'ServiceComponentInfo.installed_count',
     STARTED_PATH: 'ServiceComponentInfo.started_count',
@@ -123,6 +138,9 @@ App.componentsStateMapper = App.QuickDataMapper.create({
   map: function (json) {
     console.time('App.componentsStateMapper execution time');
 
+    var clients = [];
+    var slaves = [];
+
     if (json.items) {
       json.items.forEach(function (item) {
         var componentConfig = this.getComponentConfig(item.ServiceComponentInfo.component_name);
@@ -131,6 +149,17 @@ App.componentsStateMapper = App.QuickDataMapper.create({
         var extendedModel = this.getExtendedModel(item.ServiceComponentInfo.service_name);
         var cacheService = App.cache['services'].findProperty('ServiceInfo.service_name', item.ServiceComponentInfo.service_name);
 
+        if (item.ServiceComponentInfo.category === 'CLIENT') {
+          clients.push(this.parseIt(item, this.clientMap));
+        }
+        if (item.ServiceComponentInfo.category === 'SLAVE') {
+          // for now map for slaves and clients are equal but it may vary in future.
+          slaves.push(this.parseIt(item, this.clientMap));
+        }
+
+        cacheService.client_components = clients.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
+        cacheService.slave_components = slaves.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
+
         for (var i in parsedItem) {
           if (service.get('isLoaded')) {
             cacheService[i] = parsedItem[i];
@@ -142,6 +171,9 @@ App.componentsStateMapper = App.QuickDataMapper.create({
         }
       }, this)
     }
+    App.store.loadMany(this.clientModel, clients);
+    App.store.loadMany(this.slaveModel, slaves);
+
     console.timeEnd('App.componentsStateMapper execution time');
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/mappers/service_metrics_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_metrics_mapper.js b/ambari-web/app/mappers/service_metrics_mapper.js
index ee2a66a..33f56b8 100644
--- a/ambari-web/app/mappers/service_metrics_mapper.js
+++ b/ambari-web/app/mappers/service_metrics_mapper.js
@@ -33,7 +33,9 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
     $alerts: [ 1, 2, 3 ],
     host_components: 'host_components',
     tool_tip_content: 'tool_tip_content',
-    installed_clients: 'installed_clients'
+    installed_clients: 'installed_clients',
+    client_components: 'client_components',
+    slave_components: 'slave_components'
   },
   hdfsConfig: {
     version: 'nameNodeComponent.host_components[0].metrics.dfs.namenode.Version',

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index c9b23fb..78ab353 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1791,6 +1791,7 @@ Em.I18n.translations = {
   'dashboard.services':'Services',
   'dashboard.services.hosts':'Hosts',
   'dashboard.services.uptime':'{0}',
+  'dashboard.services.summary.slaves.live': 'Live',
   'dashboard.services.hdfs.summary':'{0} of {1} nodes live, {2}% capacity used',
   'dashboard.services.hdfs.nanmenode':'NameNode',
   'dashboard.services.hdfs.snanmenode':'Secondary NameNode',

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index 2c3bce0..efae7f0 100644
--- a/ambari-web/app/models.js
+++ b/ambari-web/app/models.js
@@ -45,10 +45,12 @@ require('models/job');
 require('models/run');
 require('models/app');
 require('models/background_operation');
+require('models/client_component');
 require('models/host_component');
 require('models/target_cluster');
 require('models/dataset');
 require('models/dataset_job');
+require('models/slave_component');
 require('classes/run_class');
 require('classes/job_class');
 require('models/config_group');

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/models/client_component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/client_component.js b/ambari-web/app/models/client_component.js
new file mode 100644
index 0000000..84fde28
--- /dev/null
+++ b/ambari-web/app/models/client_component.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var stringUtils = require('utils/string_utils');
+
+App.ClientComponent = DS.Model.extend({
+  service: DS.belongsTo('App.Service'),
+  componentName: DS.attr('string'),
+  installedCount: DS.attr('number'),
+  startedCount: DS.attr('number'),
+  totalCount: DS.attr('number'),
+  stackInfo: DS.belongsTo('App.StackServiceComponent'),
+
+  displayName: function() {
+    var displayName = App.format.role(this.get('componentName'));
+    if (this.get('service.serviceName') === this.get('componentName')) {
+      displayName += ' ' + Em.I18n.t('common.client');
+    }
+    return displayName;
+  }.property('componentName'),
+
+  displayNamePluralized: function() {
+    return stringUtils.pluralize(this.get('installedCount'), this.get('displayName'));
+  }.property('installedCount')
+});
+
+App.ClientComponent.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/models/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js
index 3dca304..b275a9b 100644
--- a/ambari-web/app/models/service.js
+++ b/ambari-web/app/models/service.js
@@ -36,6 +36,9 @@ App.Service = DS.Model.extend(App.ServiceModelMixin, {
    */
   installedClients: DS.attr('number'),
 
+  clientComponents: DS.hasMany('App.ClientComponent'),
+  slaveComponents: DS.hasMany('App.SlaveComponent'),
+
   /**
    * @type {bool}
    */
@@ -178,7 +181,7 @@ App.Service.Health = {
  * association between service and extended model name
  * @type {Object}
  */
-App.Service.extendedModel = {
+  App.Service.extendedModel = {
   'HDFS': 'HDFSService',
   'MAPREDUCE': 'MapReduceService',
   'HBASE': 'HBaseService',

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/models/slave_component.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/slave_component.js b/ambari-web/app/models/slave_component.js
new file mode 100644
index 0000000..eb20c75
--- /dev/null
+++ b/ambari-web/app/models/slave_component.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var stringUtils = require('utils/string_utils');
+
+App.SlaveComponent = App.ClientComponent.extend({
+  displayNamePluralized: function() {
+    return stringUtils.pluralize(this.get('startedCount'), this.get('displayName'));
+  }.property('startedCount')
+});
+
+App.SlaveComponent.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates.js b/ambari-web/app/templates.js
index e1528fa..6340385 100644
--- a/ambari-web/app/templates.js
+++ b/ambari-web/app/templates.js
@@ -20,15 +20,5 @@
 
 // load templates here
 
-require('templates/main/service/info/summary/ganglia');
-require('templates/main/service/info/summary/oozie');
-require('templates/main/service/info/summary/zookeeper');
-require('templates/main/service/info/summary/mapreduce2');
-require('templates/main/service/info/summary/hive');
-require('templates/main/service/info/summary/hue');
-require('templates/main/service/info/summary/falcon');
-require('templates/main/service/info/summary/tez');
-require('templates/main/service/info/summary/pig');
-require('templates/main/service/info/summary/glusterfs');
-require('templates/main/service/info/summary/sqoop');
+require('templates/main/service/info/summary/base');
 require('templates/main/admin/highAvailability/progress');

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary.hbs b/ambari-web/app/templates/main/service/info/summary.hbs
index a5a7e26..0f04649 100644
--- a/ambari-web/app/templates/main/service/info/summary.hbs
+++ b/ambari-web/app/templates/main/service/info/summary.hbs
@@ -26,63 +26,8 @@
       <div class="service-content">
         <table id="summary-info" class="table no-borders table-condensed">
           <tbody>
-            {{#if view.noTemplateService}}
-              {{view view.sumMasterComponentView}}
-            {{/if}}
-            {{#if view.serviceStatus.hdfs}}
-              {{view App.MainDashboardServiceHdfsView serviceBinding="view.service"}}
-            {{/if}}
-            {{#if view.serviceStatus.mapreduce}}
-              {{view App.MainDashboardServiceMapreduceView serviceBinding="view.service"}}
-            {{/if}}
-            {{#if view.serviceStatus.yarn}}
-              {{view App.MainDashboardServiceYARNView serviceBinding="view.service"}}
-            {{/if}}
-            {{#if view.serviceStatus.mapreduce2}}
-              {{template "templates/main/service/info/summary/mapreduce2"}}
-            {{/if}}
-            {{#if view.serviceStatus.hbase}}
-              {{view App.MainDashboardServiceHbaseView serviceBinding="view.service"}}
-            {{/if}}
-            {{#if view.serviceStatus.zookeeper}}
-              {{template "templates/main/service/info/summary/zookeeper"}}
-            {{/if}}
-            {{#if view.serviceStatus.oozie}}
-              {{template "templates/main/service/info/summary/oozie"}}
-            {{/if}}
-            {{#if view.serviceStatus.ganglia}}
-              {{template "templates/main/service/info/summary/ganglia"}}
-            {{/if}}
-            {{#if view.serviceStatus.hive}}
-              {{template "templates/main/service/info/summary/hive"}}
-            {{/if}}
-            {{#if view.serviceStatus.hue}}
-              {{template "templates/main/service/info/summary/hue"}}
-            {{/if}}
-            {{#if view.serviceStatus.flume}}
-              <tr>
-                <td>
-                  {{view App.MainDashboardServiceFlumeView serviceBinding="view.service"}}
-                </td>
-              </tr>
-            {{/if}}
-            {{#if view.serviceStatus.falcon}}
-              {{template "templates/main/service/info/summary/falcon"}}
-            {{/if}}
-            {{#if view.serviceStatus.storm}}
-              {{view App.MainDashboardServiceStormView serviceBinding="view.service"}}
-            {{/if}}
-            {{#if view.serviceStatus.tez}}
-              {{template "templates/main/service/info/summary/tez"}}
-            {{/if}}
-            {{#if view.serviceStatus.pig}}
-              {{template "templates/main/service/info/summary/pig"}}
-            {{/if}}
-            {{#if view.serviceStatus.glusterfs}}
-              {{template "templates/main/service/info/summary/glusterfs"}}
-            {{/if}}            
-            {{#if view.serviceStatus.sqoop}}
-              {{template "templates/main/service/info/summary/sqoop"}}
+            {{#if view.serviceSummaryView}}
+              {{view view.serviceSummaryView}}
             {{/if}}
           </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/base.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/base.hbs b/ambari-web/app/templates/main/service/info/summary/base.hbs
new file mode 100644
index 0000000..de18721
--- /dev/null
+++ b/ambari-web/app/templates/main/service/info/summary/base.hbs
@@ -0,0 +1,21 @@
+{{!
+* 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.
+}}
+
+{{view App.SummaryMasterComponentsView mastersCompBinding="view.content.mastersObj"}}
+{{view App.SummarySlaveComponentsView slavesObjBinding="view.content.slavesObj"}}
+{{view App.SummaryClientComponentsView clientsObjBinding="view.content.clientObj"}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/client_components.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/client_components.hbs b/ambari-web/app/templates/main/service/info/summary/client_components.hbs
new file mode 100644
index 0000000..7729ad2
--- /dev/null
+++ b/ambari-web/app/templates/main/service/info/summary/client_components.hbs
@@ -0,0 +1,30 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+<tr class="hidden"><td></td></tr>
+{{#each clientComponent in view.clientsObj}}
+  <tr>
+    <td class="summary-label">
+      <a {{action filterHosts clientComponent}} href="javascript:void(null)" >
+        {{clientComponent.displayNamePluralized}}
+      </a>
+    </td>
+    <td>
+      <span class="green-live">{{clientComponent.installedCount}}</span> {{clientComponent.displayNamePluralized}} {{t common.installed}}
+    </td>
+  </tr>
+{{/each}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/falcon.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/falcon.hbs b/ambari-web/app/templates/main/service/info/summary/falcon.hbs
deleted file mode 100644
index 59bb096..0000000
--- a/ambari-web/app/templates/main/service/info/summary/falcon.hbs
+++ /dev/null
@@ -1,26 +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.
-}}
-{{!<!-- @todo create correct view after api implementing-->}}
-{{view view.sumMasterComponentView}}
-
-<tr>
-    <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.falcon.client" plural="t:services.falcon.clients"}}</a></td>
-    <td>
-        <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.falcon.client" plural="t:services.falcon.clients"}} {{t common.installed}}
-    </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/ganglia.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/ganglia.hbs b/ambari-web/app/templates/main/service/info/summary/ganglia.hbs
deleted file mode 100644
index c510f2c..0000000
--- a/ambari-web/app/templates/main/service/info/summary/ganglia.hbs
+++ /dev/null
@@ -1,32 +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.
-}}
-
-
-
-{{view view.sumMasterComponentView}}
-
-<tr>
-  <td class="summary-label"><a {{action filterHosts view.monitorsObj}} href="javascript:void(null)" >{{t services.ganglia.monitors}}</a></td>
-  <td>
-    <span>
-      {{#view App.ComponentLiveTextView liveComponentsBinding="content.gangliaMonitorsStarted"}}
-        {{view.parentView.monitors}}
-      {{/view}}
-    </span> {{t services.service.summary.GangliaMonitorsLIVE}}
-  </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/glusterfs.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/glusterfs.hbs b/ambari-web/app/templates/main/service/info/summary/glusterfs.hbs
deleted file mode 100644
index 596cc6e..0000000
--- a/ambari-web/app/templates/main/service/info/summary/glusterfs.hbs
+++ /dev/null
@@ -1,23 +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.
-}}
-<tr>
-  <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.clients.length singular="t:services.glusterfs.client" plural="t:services.glusterfs.clients"}}</a></td>
-  <td>
-    <span class="green-live">{{view.clients.length}} </span>{{pluralize view.clients.length singular="t:services.glusterfs.client" plural="t:services.glusterfs.clients"}} {{t common.installed}}
-  </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/hive.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/hive.hbs b/ambari-web/app/templates/main/service/info/summary/hive.hbs
deleted file mode 100644
index 054e431..0000000
--- a/ambari-web/app/templates/main/service/info/summary/hive.hbs
+++ /dev/null
@@ -1,26 +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.
-}}
-
-{{view view.sumMasterComponentView}}
-
-<tr>
-    <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.hive.client" plural="t:services.hive.clients"}}</a></td>
-    <td>
-        <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.hive.client" plural="t:services.hive.clients"}} {{t common.installed}}
-    </td>
-</tr>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/hue.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/hue.hbs b/ambari-web/app/templates/main/service/info/summary/hue.hbs
deleted file mode 100644
index de832ae..0000000
--- a/ambari-web/app/templates/main/service/info/summary/hue.hbs
+++ /dev/null
@@ -1,20 +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.
-}}
-
-
-{{view view.sumMasterComponentView}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/mapreduce2.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/mapreduce2.hbs b/ambari-web/app/templates/main/service/info/summary/mapreduce2.hbs
deleted file mode 100644
index 79ef7e0..0000000
--- a/ambari-web/app/templates/main/service/info/summary/mapreduce2.hbs
+++ /dev/null
@@ -1,25 +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.
-}}
-
-{{view view.sumMasterComponentView}}
-<tr>
-    <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.mapReduce2Clients singular="t:services.service.summary.mapreduce2.client" plural="t:services.service.summary.mapreduce2.clients"}}</a></td>
-    <td>
-        <span class="green-live">{{view.service.mapReduce2Clients}} </span>{{pluralize view.service.mapReduce2Clients singular="t:services.service.summary.mapreduce2.client" plural="t:services.service.summary.mapreduce2.clients"}} {{t common.installed}}
-    </td>
-</tr>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/master_components.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/master_components.hbs b/ambari-web/app/templates/main/service/info/summary/master_components.hbs
index dc9a4ee..c0fa98c 100644
--- a/ambari-web/app/templates/main/service/info/summary/master_components.hbs
+++ b/ambari-web/app/templates/main/service/info/summary/master_components.hbs
@@ -15,10 +15,10 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
-
+<tr class="hidden"><td></td></tr>
 {{#each masterComp in view.mastersComp}}
   <tr>
-     <td>
+    <td>
       <a href="#" {{action showDetails masterComp.host}} title="{{unbound masterComp.host.publicHostName}}" rel="UsageTooltip">
        {{#if masterComp.displayNameAdvanced}}
          {{masterComp.displayNameAdvanced}}
@@ -26,10 +26,10 @@
          {{masterComp.displayName}}
        {{/if}}
       </a>
-     </td>
-   <td>
-     <span rel='healthTooltip' {{bindAttr class="masterComp.statusClass masterComp.statusIconClass" data-original-title="masterComp.passiveTooltip"}}></span>
-     {{masterComp.componentTextStatus}}
-   </td>
+    </td>
+    <td>
+      <span rel='healthTooltip' {{bindAttr class="masterComp.statusClass masterComp.statusIconClass" data-original-title="masterComp.passiveTooltip"}}></span>
+      {{masterComp.componentTextStatus}}
+    </td>
   </tr>
 {{/each}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/oozie.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/oozie.hbs b/ambari-web/app/templates/main/service/info/summary/oozie.hbs
deleted file mode 100644
index 9625b73..0000000
--- a/ambari-web/app/templates/main/service/info/summary/oozie.hbs
+++ /dev/null
@@ -1,28 +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.
-}}
-
-
-{{view view.sumMasterComponentView}}
-
-<tr>
-    <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.oozie.client" plural="t:services.oozie.clients"}}</a></td>
-    <td>
-        <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.oozie.client" plural="t:services.oozie.clients"}} {{t common.installed}}
-    </td>
-</tr>
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/pig.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/pig.hbs b/ambari-web/app/templates/main/service/info/summary/pig.hbs
deleted file mode 100644
index d4d48fd..0000000
--- a/ambari-web/app/templates/main/service/info/summary/pig.hbs
+++ /dev/null
@@ -1,23 +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.
-}}
-<tr>
-  <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.pig.client" plural="t:services.pig.clients"}}</a></td>
-  <td>
-    <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.pig.client" plural="t:services.pig.clients"}} {{t common.installed}}
-  </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/slave_components.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/slave_components.hbs b/ambari-web/app/templates/main/service/info/summary/slave_components.hbs
new file mode 100644
index 0000000..218874d
--- /dev/null
+++ b/ambari-web/app/templates/main/service/info/summary/slave_components.hbs
@@ -0,0 +1,33 @@
+{{!
+* 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.
+}}
+<tr class="hidden"><td></td></tr>
+
+{{#each slaveComponent in view.slavesObj}}
+  <tr>
+    <td><a href="#" {{action filterHosts slaveComponent}}>{{slaveComponent.displayNamePluralized}}</a>
+    </td>
+    <td>
+      <span>
+        {{#view App.ComponentLiveTextView liveComponentsBinding="slaveComponent.startedCount" totalComponentsBinding="slaveComponent.totalCount"}}
+          {{view.liveComponents}}/{{view.totalComponents}}
+        {{/view}}
+      </span>
+      {{slaveComponent.displayNamePluralized}} {{t dashboard.services.summary.slaves.live}}
+    </td>
+  </tr>
+{{/each}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/sqoop.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/sqoop.hbs b/ambari-web/app/templates/main/service/info/summary/sqoop.hbs
deleted file mode 100644
index db80425..0000000
--- a/ambari-web/app/templates/main/service/info/summary/sqoop.hbs
+++ /dev/null
@@ -1,23 +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.
-}}
-<tr>
-  <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.sqoop.client" plural="t:services.sqoop.clients"}}</a></td>
-  <td>
-    <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.sqoop.client" plural="t:services.sqoop.clients"}} {{t common.installed}}
-  </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/tez.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/tez.hbs b/ambari-web/app/templates/main/service/info/summary/tez.hbs
deleted file mode 100644
index 162c7b4..0000000
--- a/ambari-web/app/templates/main/service/info/summary/tez.hbs
+++ /dev/null
@@ -1,23 +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.
-}}
-<tr>
-  <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.tez.client" plural="t:services.tez.clients"}}</a></td>
-  <td>
-    <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.tez.client" plural="t:services.tez.clients"}} {{t common.installed}}
-  </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/info/summary/zookeeper.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/summary/zookeeper.hbs b/ambari-web/app/templates/main/service/info/summary/zookeeper.hbs
deleted file mode 100644
index 551e243..0000000
--- a/ambari-web/app/templates/main/service/info/summary/zookeeper.hbs
+++ /dev/null
@@ -1,27 +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.
-}}
-
-
-
-{{view view.sumMasterComponentView}}
-<tr>
-    <td class="summary-label"><a {{action filterHosts view.clientObj}} href="javascript:void(null)" >{{pluralize view.service.installedClients singular="t:services.zookeeper.client" plural="t:services.zookeeper.clients"}}</a></td>
-    <td>
-        <span class="green-live">{{view.service.installedClients}} </span>{{pluralize view.service.installedClients singular="t:services.zookeeper.client" plural="t:services.zookeeper.clients"}} {{t common.installed}}
-    </td>
-</tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/templates/main/service/services/storm.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/services/storm.hbs b/ambari-web/app/templates/main/service/services/storm.hbs
index d70842c..5382612 100644
--- a/ambari-web/app/templates/main/service/services/storm.hbs
+++ b/ambari-web/app/templates/main/service/services/storm.hbs
@@ -16,7 +16,7 @@
 * limitations under the License.
 }}
 
-{{view view.parentView.sumMasterComponentView}}
+{{view App.SummaryMasterComponentsView mastersCompBinding="view.parentView.mastersObj"}}
 <tr>
   <td>
     <a href="#" {{action filterHosts view.superVisorComponents.[0]}}>

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index 5bff313..6b4b307 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -514,9 +514,10 @@ App.registerBoundHelper = function(name, view) {
 };
 
 /*
- * Return singular or plural word based on Em.I18n property key.
+ * Return singular or plural word based on Em.I18n, view|controller context property key.
  *
  *  Example: {{pluralize hostsCount singular="t:host" plural="t:hosts"}}
+ *           {{pluralize hostsCount singular="@view.hostName"}}
  */
 App.registerBoundHelper('pluralize', Em.View.extend({
   tagName: 'span',
@@ -529,10 +530,20 @@ App.registerBoundHelper('pluralize', Em.View.extend({
     plural = this.get('plural');
     return this.getWord(count, singular, plural);
   }.property('content'),
-
+  /**
+   * Get computed word.
+   *
+   * @param {Number} count
+   * @param {String} singular
+   * @param {String} [plural]
+   * @return {String}
+   * @method getWord
+   */
   getWord: function(count, singular, plural) {
-    singular = this.tDetect(singular);
-    plural = this.tDetect(plural);
+    singular = this.parseValue(singular);
+    // if plural not passed
+    if (!plural) plural = singular + 's';
+    else plural = this.parseValue(plural);
     if (singular && plural) {
       if (count > 1) {
         return plural;
@@ -542,6 +553,26 @@ App.registerBoundHelper('pluralize', Em.View.extend({
     }
     return '';
   },
+  /**
+   * Detect and return value from its instance.
+   *
+   * @param {String} value
+   * @return {*}
+   * @method parseValue
+   **/
+  parseValue: function(value) {
+    switch (value[0]) {
+      case '@':
+        value = this.getViewPropertyValue(value);
+        break;
+      case 't':
+        value = this.tDetect(value);
+        break;
+      default:
+        break;
+    }
+    return value;
+  },
   /*
    * Detect for Em.I18n.t reference call
    * @params word {String}
@@ -554,6 +585,25 @@ App.registerBoundHelper('pluralize', Em.View.extend({
     } else {
       return splitted[0];
     }
+  },
+  /**
+   * Get property value from view|controller by its key path.
+   *
+   * @param {String} value - key path
+   * @return {*}
+   * @method getViewPropertyValue
+   **/
+  getViewPropertyValue: function(value) {
+    value = value.substr(1);
+    var keyword = value.split('.')[0]; // return 'controller' or 'view'
+    switch (keyword) {
+      case 'controller':
+        return Em.get(this, value);
+      case 'view':
+        return Em.get(this, value.replace(/^view/, 'parentView'))
+      default:
+        break;
+    }
   }
   })
 );

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/utils/string_utils.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/string_utils.js b/ambari-web/app/utils/string_utils.js
index b16852e..e912ba5 100644
--- a/ambari-web/app/utils/string_utils.js
+++ b/ambari-web/app/utils/string_utils.js
@@ -189,8 +189,17 @@ module.exports = {
     }, this);
     return label.trim();
   },
-
+  /**
+   * Get plural|singular value of string by related count.
+   *
+   * @param {Number} count
+   * @param {String} singular
+   * @param {String} [plural]
+   * @return {String}
+   * @method pluralize
+   */
   pluralize: function(count, singular, plural) {
+    plural = plural || singular + 's';
     if (count > 1) {
       return plural;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 7a8fb4f..2e4c81c 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -166,6 +166,7 @@ require('views/main/service/all_services_actions');
 require('views/main/service/menu');
 require('views/main/service/item');
 require('views/main/service/reconfigure');
+require('views/main/service/info/components_list_view');
 require('views/main/service/info/menu');
 require('views/main/service/info/summary');
 require('views/main/service/info/configs');

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/views/main/service/info/components_list_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/components_list_view.js b/ambari-web/app/views/main/service/info/components_list_view.js
new file mode 100644
index 0000000..5486f8b
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/components_list_view.js
@@ -0,0 +1,37 @@
+/**
+ * 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.SummaryMasterComponentsView = Em.View.extend({
+  templateName: require('templates/main/service/info/summary/master_components'),
+  masterComp: null,
+  didInsertElement: function() {
+    App.tooltip($('[rel=healthTooltip]'));
+  }
+});
+
+App.SummaryClientComponentsView = Em.View.extend({
+  templateName: require('templates/main/service/info/summary/client_components'),
+  clientsObj: []
+});
+
+App.SummarySlaveComponentsView = Em.View.extend({
+  templateName: require('templates/main/service/info/summary/slave_components'),
+  slavesObj: []
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/298bb53d/ambari-web/app/views/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js
index 8f66509..2bd6152 100644
--- a/ambari-web/app/views/main/service/info/summary.js
+++ b/ambari-web/app/views/main/service/info/summary.js
@@ -35,26 +35,37 @@ App.AlertItemView = Em.View.extend({
 App.MainServiceInfoSummaryView = Em.View.extend({
   templateName: require('templates/main/service/info/summary'),
   attributes:null,
-  serviceStatus:{
-    hdfs:false,
-    yarn:false,
-    mapreduce:false,
-    mapreduce2:false,
-    hbase:false,
-    zookeeper:false,
-    oozie:false,
-    hive:false,
-    ganglia:false,
-    nagios:false,
-    hue: false,
-    flume: false,
-    falcon: false,
-    storm: false,
-    tez: false,
-    pig :false,
-    glusterfs: false,    
-    sqoop: false
-  },
+  /**
+   *  @property {String} templatePathPrefix - base path for custom templates
+   *    if you want to add custom template, add <service_name>.hbs file to
+   *    templates/main/service/info/summary folder.
+   */
+  templatePathPrefix: 'templates/main/service/info/summary/',
+  /** @property {Ember.View} serviceSummaryView - view to embed, computed in
+   *  <code>loadServiceSummary()</code>
+   */
+  serviceSummaryView: null,
+  /**
+   * @property {Object} serviceCustomViewsMap - custom views to embed
+   *
+   */
+  serviceCustomViewsMap: function() {
+    return {
+      HBASE: App.MainDashboardServiceHbaseView,
+      HDFS: App.MainDashboardServiceHdfsView,
+      MAPREDUCE: App.MainDashboardServiceMapreduceView,
+      STORM: App.MainDashboardServiceStormView,
+      YARN: App.MainDashboardServiceYARNView,
+      FLUME: Em.View.extend({
+        template: Em.Handlebars.compile('' +
+          '<tr>' +
+            '<td>' +
+              '{{view App.MainDashboardServiceFlumeView serviceBinding="view.service"}}' +
+            '</td>' +
+          '</tr>')
+      })
+    }
+  }.property('serviceName'),
   /** @property collapsedMetrics {object[]} - metrics list for collapsed section
    *    structure of element from list:
    *      @property {string} header - title for section
@@ -68,16 +79,6 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     return App.get('services.hasClient');
   }.property('App.services.hasClient'),
 
-  sumMasterComponentView : Em.View.extend({
-    didInsertElement: function() {
-      App.tooltip($('[rel=healthTooltip]'));
-    },
-    templateName: require('templates/main/service/info/summary/master_components'),
-    mastersComp : function(){
-      return this.get('parentView.service.hostComponents').filterProperty('isMaster', true);
-    }.property("service")
-  }),
-
   alertsControllerBinding: 'App.router.mainAlertsController',
   alerts: function () {
     return this.get('alertsController.alerts');
@@ -105,7 +106,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({
 
   hasManyClients: function () {
     return this.get('controller.content.installedClients').length > 1;
-  }.property('controller.content.installedClients'),
+  }.property('service.installedClients'),
 
   servers: function () {
     var result = [];
@@ -143,36 +144,6 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     var service=this.get('controller.content');
     return (App.singleNodeInstall ? "http://" + App.singleNodeAlias + ":19888" : "http://" + service.get("hostComponents").findProperty('isMaster', true).get("host").get("publicHostName")+":19888");
   }.property('controller.content'),
-
-  monitors: function () {
-    var result = '';
-    var service = this.get('controller.content');
-    if (service.get("id") == "GANGLIA") {
-      var totalMonitors = service.get('gangliaMonitorsTotal');
-      var liveMonitors = service.get('gangliaMonitorsStarted');
-      if (totalMonitors) {
-        result = Em.I18n.t('services.service.info.summary.hostsRunningMonitor').format(liveMonitors, totalMonitors);
-      }
-    }
-    return result;
-  }.property('controller.content'),
-
-  /**
-   * Property related to GANGLIA service, is unused for other services
-   * @type {Object}
-   */
-  monitorsObj: function () {
-    if (this.get('controller.content.id') == "GANGLIA") {
-      var monitors = App.StackServiceComponent.find().filterProperty('serviceName', 'GANGLIA').filterProperty('isMaster', false);
-      if (monitors.length) {
-        return Em.Object.create({
-          componentName: monitors.objectAt(0).get('componentName')
-        });
-      }
-    }
-    return {};
-  }.property('controller.content.id'),
-
   /**
    * Property related to ZOOKEEPER service, is unused for other services
    * @return {Object}
@@ -188,22 +159,27 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     return {};
   }.property('controller.content'),
 
+  mastersObj: function() {
+    return this.get('service.hostComponents').filterProperty('isMaster', true);
+  }.property('service'),
+
   /**
-   * Contain Object with <code>componentName</code> property for <code>filterByComponent</code> method
-   * @type {Object}
+   * Contain array with list of client components models <code>App.ClientComponent</code>.
+   * @type {Array}
    */
   clientObj: function () {
-    var serviceName = this.get('controller.content.id');
-    if (this.get('servicesHaveClients').contains(serviceName)) {
-      var clients = App.StackServiceComponent.find().filterProperty('serviceName', serviceName).filterProperty('isClient');
-      if (clients.length) {
-        return Em.Object.create({
-          componentName: clients.objectAt(0).get('componentName')
-        });
-      }
-    }
-    return {};
-  }.property('controller.content.id'),
+    var clientComponents = this.get('controller.content.clientComponents').toArray();
+    return clientComponents.get('length') ? clientComponents : [];
+  }.property('service.clientComponents.@each.totalCount'),
+
+  /**
+   * Contain array with list of slave components models <code>App.SlaveComponent</code>.
+   * @type {Array}
+   */
+  slavesObj: function() {
+    var slaveComponents = this.get('controller.content.slaveComponents').toArray();
+    return slaveComponents.get('length') ? slaveComponents : [];
+  }.property('service.slaveComponents.@each.totalCount', 'service.slaveComponents.@each.startedCount'),
 
   data:{
     hive:{
@@ -353,9 +329,10 @@ App.MainServiceInfoSummaryView = Em.View.extend({
     return graphs;
   }.property(''),
 
-  loadServiceSummary:function (serviceName) {
-
+  loadServiceSummary: function (serviceName) {
     var serviceName = this.get('serviceName');
+    var serviceSummaryView = null;
+
     if (!serviceName) {
       return;
     }
@@ -365,19 +342,19 @@ App.MainServiceInfoSummaryView = Em.View.extend({
       return;
     }
 
-    var summaryView = this;
-    var serviceStatus = summaryView.get('serviceStatus');
-    $.each(serviceStatus, function (key, value) {
-      if (key.toUpperCase() == serviceName) {
-        summaryView.set('serviceStatus.' + key, true);
-      } else {
-        summaryView.set('serviceStatus.' + key, false);
-      }
-    });
-
-    console.log('load ', serviceName, ' info');
+    var customServiceView = this.get('serviceCustomViewsMap')[serviceName];
+    if (customServiceView) {
+      serviceSummaryView  = customServiceView.extend({
+        service: this.get('service')
+      });
+    } else  {
+      serviceSummaryView = Em.View.extend({
+        templateName: this.get('templatePathPrefix') + 'base',
+        content: this
+      });
+    }
+    this.set('serviceSummaryView', serviceSummaryView);
     this.set('oldServiceName', serviceName);
-    serviceName = serviceName.toLowerCase();
   }.observes('serviceName'),
 
   /*