Bladeren bron

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

atkach 11 jaren geleden
bovenliggende
commit
298bb53d6a
29 gewijzigde bestanden met toevoegingen van 322 en 393 verwijderingen
  1. 1 1
      ambari-web/app/controllers/global/update_controller.js
  2. 1 0
      ambari-web/app/controllers/wizard/step7_controller.js
  3. 32 0
      ambari-web/app/mappers/components_state_mapper.js
  4. 3 1
      ambari-web/app/mappers/service_metrics_mapper.js
  5. 1 0
      ambari-web/app/messages.js
  6. 2 0
      ambari-web/app/models.js
  7. 43 0
      ambari-web/app/models/client_component.js
  8. 4 1
      ambari-web/app/models/service.js
  9. 28 0
      ambari-web/app/models/slave_component.js
  10. 1 11
      ambari-web/app/templates.js
  11. 2 57
      ambari-web/app/templates/main/service/info/summary.hbs
  12. 3 2
      ambari-web/app/templates/main/service/info/summary/base.hbs
  13. 13 6
      ambari-web/app/templates/main/service/info/summary/client_components.hbs
  14. 0 32
      ambari-web/app/templates/main/service/info/summary/ganglia.hbs
  15. 0 23
      ambari-web/app/templates/main/service/info/summary/glusterfs.hbs
  16. 0 26
      ambari-web/app/templates/main/service/info/summary/hive.hbs
  17. 0 25
      ambari-web/app/templates/main/service/info/summary/mapreduce2.hbs
  18. 7 7
      ambari-web/app/templates/main/service/info/summary/master_components.hbs
  19. 0 28
      ambari-web/app/templates/main/service/info/summary/oozie.hbs
  20. 0 23
      ambari-web/app/templates/main/service/info/summary/pig.hbs
  21. 13 6
      ambari-web/app/templates/main/service/info/summary/slave_components.hbs
  22. 0 23
      ambari-web/app/templates/main/service/info/summary/sqoop.hbs
  23. 0 27
      ambari-web/app/templates/main/service/info/summary/zookeeper.hbs
  24. 1 1
      ambari-web/app/templates/main/service/services/storm.hbs
  25. 54 4
      ambari-web/app/utils/helper.js
  26. 10 1
      ambari-web/app/utils/string_utils.js
  27. 1 0
      ambari-web/app/views.js
  28. 37 0
      ambari-web/app/views/main/service/info/components_list_view.js
  29. 65 88
      ambari-web/app/views/main/service/info/summary.js

+ 1 - 1
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, {

+ 1 - 0
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);

+ 32 - 0
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');
   }
 });

+ 3 - 1
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',

+ 1 - 0
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',

+ 2 - 0
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');

+ 43 - 0
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 = [];

+ 4 - 1
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',

+ 28 - 0
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 = [];

+ 1 - 11
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');

+ 2 - 57
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>

+ 3 - 2
ambari-web/app/templates/main/service/info/summary/hue.hbs → ambari-web/app/templates/main/service/info/summary/base.hbs

@@ -16,5 +16,6 @@
 * limitations under the License.
 }}
 
-
-{{view view.sumMasterComponentView}}
+{{view App.SummaryMasterComponentsView mastersCompBinding="view.content.mastersObj"}}
+{{view App.SummarySlaveComponentsView slavesObjBinding="view.content.slavesObj"}}
+{{view App.SummaryClientComponentsView clientsObjBinding="view.content.clientObj"}}

+ 13 - 6
ambari-web/app/templates/main/service/info/summary/tez.hbs → ambari-web/app/templates/main/service/info/summary/client_components.hbs

@@ -15,9 +15,16 @@
 * 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>
+<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}}

+ 0 - 32
ambari-web/app/templates/main/service/info/summary/ganglia.hbs

@@ -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>

+ 0 - 23
ambari-web/app/templates/main/service/info/summary/glusterfs.hbs

@@ -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>

+ 0 - 26
ambari-web/app/templates/main/service/info/summary/hive.hbs

@@ -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>

+ 0 - 25
ambari-web/app/templates/main/service/info/summary/mapreduce2.hbs

@@ -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>

+ 7 - 7
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}}

+ 0 - 28
ambari-web/app/templates/main/service/info/summary/oozie.hbs

@@ -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>
-

+ 0 - 23
ambari-web/app/templates/main/service/info/summary/pig.hbs

@@ -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>

+ 13 - 6
ambari-web/app/templates/main/service/info/summary/falcon.hbs → ambari-web/app/templates/main/service/info/summary/slave_components.hbs

@@ -15,12 +15,19 @@
 * 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 class="hidden"><td></td></tr>
 
-<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>
+{{#each slaveComponent in view.slavesObj}}
+  <tr>
+    <td><a href="#" {{action filterHosts slaveComponent}}>{{slaveComponent.displayNamePluralized}}</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}}
+      <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>
+  </tr>
+{{/each}}

+ 0 - 23
ambari-web/app/templates/main/service/info/summary/sqoop.hbs

@@ -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>

+ 0 - 27
ambari-web/app/templates/main/service/info/summary/zookeeper.hbs

@@ -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>

+ 1 - 1
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]}}>

+ 54 - 4
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;
+    }
   }
   })
 );

+ 10 - 1
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;
     }

+ 1 - 0
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');

+ 37 - 0
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: []
+});

+ 65 - 88
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'),
 
   /*